Skip to content

Commit bf5da38

Browse files
committed
improved error handling fro font-face rules
1 parent 5a80186 commit bf5da38

3 files changed

Lines changed: 94 additions & 4 deletions

File tree

src/main/javacc/CSS3Parser.jj

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -490,9 +490,6 @@ void styleSheetRuleList() :
490490
if (t.kind != RBRACE) {
491491
error_skipblock(null, null);
492492
}
493-
if (t.kind == EOF) {
494-
return;
495-
}
496493
}
497494
}
498495
)
@@ -927,7 +924,9 @@ void fontFaceRule() :
927924
}
928925
catch(ParseException e)
929926
{
930-
throw toCSSParseException("invalidFontFaceRule", e);
927+
CSSParseException cpe = toCSSParseException("invalidFontFaceRule", e);
928+
getErrorHandler().error(cpe);
929+
error_skipblock("invalidFontFaceRule", cpe);
931930
}
932931
finally {
933932
if (start) {

src/test/java/org/htmlunit/cssparser/parser/CSS3ParserTest.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131

3232
import org.htmlunit.cssparser.ErrorHandler;
3333
import org.htmlunit.cssparser.dom.AbstractCSSRuleImpl;
34+
import org.htmlunit.cssparser.dom.CSSFontFaceRuleImpl;
3435
import org.htmlunit.cssparser.dom.CSSMediaRuleImpl;
36+
import org.htmlunit.cssparser.dom.CSSPageRuleImpl;
3537
import org.htmlunit.cssparser.dom.CSSRuleListImpl;
3638
import org.htmlunit.cssparser.dom.CSSStyleDeclarationImpl;
3739
import org.htmlunit.cssparser.dom.CSSStyleRuleImpl;
@@ -739,6 +741,29 @@ public void atRuleFontFaceComplex2() throws Exception {
739741
rule.getCssText());
740742
}
741743

744+
/**
745+
* @throws Exception if the test fails
746+
*/
747+
@Test
748+
public void invalidFontFaceRule_isSkipped_andFollowingRulesStillParsed() throws Exception {
749+
final String css =
750+
"@font-face { font-family: Gentium; ) }\n"
751+
+ "p { color: blue; }\n";
752+
753+
// If fontFaceRule() currently aborts parsing, this test will FAIL today.
754+
// That’s OK: it captures the desired behavior.
755+
final CSSStyleSheetImpl sheet = parse(css, 1, 0, 1);
756+
757+
final CSSRuleListImpl rules = sheet.getCssRules();
758+
assertEquals(2, rules.getLength());
759+
760+
assertTrue(rules.getRules().get(0) instanceof CSSFontFaceRuleImpl);
761+
assertEquals("@font-face { font-family: Gentium; }", rules.getRules().get(0).getCssText());
762+
763+
assertTrue(rules.getRules().get(1) instanceof CSSStyleRuleImpl);
764+
assertEquals("p { color: blue; }", rules.getRules().get(1).getCssText());
765+
}
766+
742767
/**
743768
* @see <a href="http://www.w3.org/TR/CSS21/syndata.html#at-rules">
744769
* http://www.w3.org/TR/CSS21/syndata.html#at-rules</a>
@@ -4004,6 +4029,27 @@ private void pageSelectors(final String css, final String expected,
40044029
}
40054030
}
40064031

4032+
/**
4033+
* @throws Exception if the test fails
4034+
*/
4035+
@Test
4036+
public void invalidPageRule_isSkipped_andFollowingRulesStillParsed() throws Exception {
4037+
final String css =
4038+
"@page :left { margin: 3cm; ) }\n" // missing closing '}'
4039+
+ "p { color: blue; }";
4040+
4041+
final CSSStyleSheetImpl sheet = parse(css, 1, 0, 1);
4042+
4043+
final CSSRuleListImpl rules = sheet.getCssRules();
4044+
assertEquals(2, rules.getLength());
4045+
4046+
assertTrue(rules.getRules().get(0) instanceof CSSPageRuleImpl);
4047+
assertEquals("@page :left { margin: 3cm; }", rules.getRules().get(0).getCssText());
4048+
4049+
assertTrue(rules.getRules().get(1) instanceof CSSStyleRuleImpl);
4050+
assertEquals("p { color: blue; }", rules.getRules().get(1).getCssText());
4051+
}
4052+
40074053
/**
40084054
* Test keyframes at rule.
40094055
*

src/test/java/org/htmlunit/cssparser/parser/media/CSS3MediaTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
import org.htmlunit.cssparser.dom.AbstractCSSRuleImpl;
2424
import org.htmlunit.cssparser.dom.CSSMediaRuleImpl;
25+
import org.htmlunit.cssparser.dom.CSSRuleListImpl;
26+
import org.htmlunit.cssparser.dom.CSSStyleRuleImpl;
2527
import org.htmlunit.cssparser.dom.CSSStyleSheetImpl;
2628
import org.htmlunit.cssparser.dom.CSSValueImpl;
2729
import org.htmlunit.cssparser.dom.MediaListImpl;
@@ -304,4 +306,47 @@ public void parseMediaComplexRule() throws Exception {
304306
properties = mediaQuery.getProperties();
305307
assertEquals("device-aspect-ratio: 16 / 9", properties.get(0).toString());
306308
}
309+
310+
/**
311+
* @throws Exception if the test fails
312+
*/
313+
@Test
314+
public void invalidMediaRule_isSkipped_andFollowingRulesStillParsed() throws Exception {
315+
final String css =
316+
"@media screen and (max-width: 30em { h1 { color: red } }\n" // missing ')'
317+
+ "p { color: blue; }\n";
318+
319+
// Expect: 1 error (invalid media rule), 0 fatal, and at least 1 warning (skip).
320+
// If your ErrorHandler counts the skip warning, keep warn=1; otherwise use warn=0.
321+
final CSSStyleSheetImpl sheet = parse(css, 1, 0, 1);
322+
323+
final CSSRuleListImpl rules = sheet.getCssRules();
324+
// The invalid @media should be skipped, leaving the 'p { ... }' rule.
325+
assertEquals(1, rules.getLength());
326+
327+
final AbstractCSSRuleImpl rule = rules.getRules().get(0);
328+
assertTrue(rule instanceof CSSStyleRuleImpl);
329+
assertEquals("p { color: blue; }", rule.getCssText());
330+
}
331+
332+
/**
333+
* @throws Exception if the test fails
334+
*/
335+
@Test
336+
public void validMediaRule_thenInvalidInnerContent_skipsBlock_andContinues() throws Exception {
337+
final String css =
338+
"@media screen { h1 { color: red; } abc } }\n"
339+
+ "p { color: blue; }";
340+
341+
final CSSStyleSheetImpl sheet = parse(css, 1, 0, 1);
342+
343+
final CSSRuleListImpl rules = sheet.getCssRules();
344+
// Depending on how inner errors are handled, you may still keep the @media rule.
345+
// The key expectation: parsing continues and p{...} exists.
346+
assertEquals(2, rules.getLength());
347+
348+
assertTrue(rules.getRules().get(0) instanceof CSSMediaRuleImpl);
349+
assertTrue(rules.getRules().get(1) instanceof CSSStyleRuleImpl);
350+
assertEquals("p { color: blue; }", rules.getRules().get(1).getCssText());
351+
}
307352
}

0 commit comments

Comments
 (0)