Skip to content

Commit 9c309e5

Browse files
committed
parse: stop on fatal event handler error
1 parent 24d53ec commit 9c309e5

File tree

1 file changed

+105
-69
lines changed

1 file changed

+105
-69
lines changed

src/parse/parse.c

Lines changed: 105 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,31 @@ css_error eatWS(css_parser *parser)
714714
return CSS_OK;
715715
}
716716

717+
/**
718+
* Emit an event
719+
*
720+
* \param parser The parser instance
721+
* \param type The event type
722+
* \param tokens Token vector associated with event
723+
* \param graceful Whether to gracefully handle CSS_INVALID
724+
* \return CSS_OK on success, appropriate error otherwise
725+
*/
726+
static css_error emit(css_parser *parser, css_parser_event type,
727+
const parserutils_vector *tokens, bool graceful)
728+
{
729+
css_error error = CSS_OK;
730+
731+
if (parser->event != NULL) {
732+
error = parser->event(type, tokens, parser->event_pw);
733+
}
734+
735+
if (graceful && error == CSS_INVALID) {
736+
error = CSS_OK;
737+
}
738+
739+
return error;
740+
}
741+
717742
/******************************************************************************
718743
* Parser stages *
719744
******************************************************************************/
@@ -731,9 +756,9 @@ css_error parseStart(css_parser *parser)
731756
#if !defined(NDEBUG) && defined(DEBUG_EVENTS)
732757
printf("Begin stylesheet\n");
733758
#endif
734-
if (parser->event != NULL) {
735-
parser->event(CSS_PARSER_START_STYLESHEET, NULL,
736-
parser->event_pw);
759+
error = emit(parser, CSS_PARSER_START_STYLESHEET, NULL, true);
760+
if (error != CSS_OK) {
761+
return error;
737762
}
738763

739764
error = eatWS(parser);
@@ -760,9 +785,9 @@ css_error parseStart(css_parser *parser)
760785
parserutils_vector_dump(parser->tokens, __func__, tprinter);
761786
printf("End stylesheet\n");
762787
#endif
763-
if (parser->event != NULL) {
764-
parser->event(CSS_PARSER_END_STYLESHEET, NULL,
765-
parser->event_pw);
788+
error = emit(parser, CSS_PARSER_END_STYLESHEET, NULL, true);
789+
if (error != CSS_OK) {
790+
return error;
766791
}
767792

768793
discard_tokens(parser);
@@ -881,15 +906,15 @@ css_error parseRuleset(css_parser *parser)
881906
#if !defined(NDEBUG) && defined(DEBUG_EVENTS)
882907
printf("Begin ruleset\n");
883908
#endif
884-
if (parser->event != NULL) {
885-
if (parser->event(CSS_PARSER_START_RULESET,
886-
NULL, parser->event_pw) ==
887-
CSS_INVALID) {
888-
parser_state to =
889-
{ sMalformedSelector, Initial };
890-
891-
return transitionNoRet(parser, to);
892-
}
909+
error = emit(parser, CSS_PARSER_START_RULESET, NULL,
910+
false);
911+
if (error == CSS_INVALID) {
912+
parser_state to =
913+
{ sMalformedSelector, Initial };
914+
915+
return transitionNoRet(parser, to);
916+
} else if (error != CSS_OK) {
917+
return error;
893918
}
894919

895920
state->substate = WS;
@@ -938,11 +963,14 @@ css_error parseRuleset(css_parser *parser)
938963
printf("Begin ruleset\n");
939964
parserutils_vector_dump(parser->tokens, __func__, tprinter);
940965
#endif
941-
if (parser->parseError == false && parser->event != NULL) {
942-
if (parser->event(CSS_PARSER_START_RULESET,
943-
parser->tokens, parser->event_pw) ==
944-
CSS_INVALID)
966+
if (parser->parseError == false) {
967+
error = emit(parser, CSS_PARSER_START_RULESET,
968+
parser->tokens, false);
969+
if (error == CSS_INVALID) {
945970
parser->parseError = true;
971+
} else if (error != CSS_OK) {
972+
return error;
973+
}
946974
}
947975

948976
/* Re-read the brace */
@@ -1045,8 +1073,9 @@ css_error parseRulesetEnd(css_parser *parser)
10451073
#if !defined(NDEBUG) && defined(DEBUG_EVENTS)
10461074
printf("End ruleset\n");
10471075
#endif
1048-
if (parser->event != NULL) {
1049-
parser->event(CSS_PARSER_END_RULESET, NULL, parser->event_pw);
1076+
error = emit(parser, CSS_PARSER_END_RULESET, NULL, true);
1077+
if (error != CSS_OK) {
1078+
return error;
10501079
}
10511080

10521081
return done(parser);
@@ -1140,14 +1169,14 @@ css_error parseAtRuleEnd(css_parser *parser)
11401169
printf("Begin at-rule\n");
11411170
parserutils_vector_dump(parser->tokens, __func__, tprinter);
11421171
#endif
1143-
if (parser->event != NULL) {
1144-
if (parser->event(CSS_PARSER_START_ATRULE,
1145-
parser->tokens, parser->event_pw) ==
1146-
CSS_INVALID) {
1147-
parser_state to = { sMalformedAtRule, Initial };
1172+
error = emit(parser, CSS_PARSER_START_ATRULE, parser->tokens,
1173+
false);
1174+
if (error == CSS_INVALID) {
1175+
parser_state to = { sMalformedAtRule, Initial };
11481176

1149-
return transitionNoRet(parser, to);
1150-
}
1177+
return transitionNoRet(parser, to);
1178+
} else if (error != CSS_OK) {
1179+
return error;
11511180
}
11521181

11531182
error = getToken(parser, &token);
@@ -1197,8 +1226,9 @@ css_error parseAtRuleEnd(css_parser *parser)
11971226
#if !defined(NDEBUG) && defined(DEBUG_EVENTS)
11981227
printf("End at-rule\n");
11991228
#endif
1200-
if (parser->event != NULL) {
1201-
parser->event(CSS_PARSER_END_ATRULE, NULL, parser->event_pw);
1229+
error = emit(parser, CSS_PARSER_END_ATRULE, NULL, true);
1230+
if (error != CSS_OK) {
1231+
return error;
12021232
}
12031233

12041234
return done(parser);
@@ -1222,9 +1252,9 @@ css_error parseBlock(css_parser *parser)
12221252
#if !defined(NDEBUG) && defined(DEBUG_EVENTS)
12231253
printf("Begin block\n");
12241254
#endif
1225-
if (parser->event != NULL) {
1226-
parser->event(CSS_PARSER_START_BLOCK, NULL,
1227-
parser->event_pw);
1255+
error = emit(parser, CSS_PARSER_START_BLOCK, NULL, true);
1256+
if (error != CSS_OK) {
1257+
return error;
12281258
}
12291259

12301260
if (token->type != CSS_TOKEN_CHAR ||
@@ -1286,8 +1316,9 @@ css_error parseBlock(css_parser *parser)
12861316
#if !defined(NDEBUG) && defined(DEBUG_EVENTS)
12871317
printf("End block\n");
12881318
#endif
1289-
if (parser->event != NULL) {
1290-
parser->event(CSS_PARSER_END_BLOCK, NULL, parser->event_pw);
1319+
error = emit(parser, CSS_PARSER_END_BLOCK, NULL, true);
1320+
if (error != CSS_OK) {
1321+
return error;
12911322
}
12921323

12931324
discard_tokens(parser);
@@ -1335,11 +1366,11 @@ css_error parseBlockContent(css_parser *parser)
13351366
parserutils_vector_dump(parser->tokens,
13361367
__func__, tprinter);
13371368
#endif
1338-
if (parser->event != NULL) {
1339-
parser->event(
1369+
error = emit(parser,
13401370
CSS_PARSER_BLOCK_CONTENT,
1341-
parser->tokens,
1342-
parser->event_pw);
1371+
parser->tokens, true);
1372+
if (error != CSS_OK) {
1373+
return error;
13431374
}
13441375

13451376
discard_tokens(parser);
@@ -1359,11 +1390,11 @@ css_error parseBlockContent(css_parser *parser)
13591390
parserutils_vector_dump(parser->tokens,
13601391
__func__, tprinter);
13611392
#endif
1362-
if (parser->event != NULL) {
1363-
parser->event(
1393+
error = emit(parser,
13641394
CSS_PARSER_BLOCK_CONTENT,
1365-
parser->tokens,
1366-
parser->event_pw);
1395+
parser->tokens, true);
1396+
if (error != CSS_OK) {
1397+
return error;
13671398
}
13681399

13691400
error = getToken(parser, &token);
@@ -1386,11 +1417,11 @@ css_error parseBlockContent(css_parser *parser)
13861417
parserutils_vector_dump(parser->tokens,
13871418
__func__, tprinter);
13881419
#endif
1389-
if (parser->event != NULL) {
1390-
parser->event(
1420+
error = emit(parser,
13911421
CSS_PARSER_END_BLOCK_CONTENT,
1392-
parser->tokens,
1393-
parser->event_pw);
1422+
parser->tokens, true);
1423+
if (error != CSS_OK) {
1424+
return error;
13941425
}
13951426

13961427
discard_tokens(parser);
@@ -1406,10 +1437,10 @@ css_error parseBlockContent(css_parser *parser)
14061437
parserutils_vector_dump(parser->tokens,
14071438
__func__, tprinter);
14081439
#endif
1409-
if (parser->event != NULL) {
1410-
parser->event(CSS_PARSER_BLOCK_CONTENT,
1411-
parser->tokens,
1412-
parser->event_pw);
1440+
error = emit(parser, CSS_PARSER_BLOCK_CONTENT,
1441+
parser->tokens, true);
1442+
if (error != CSS_OK) {
1443+
return error;
14131444
}
14141445

14151446
discard_tokens(parser);
@@ -1544,9 +1575,10 @@ css_error parseDeclaration(css_parser *parser)
15441575
#if !defined(NDEBUG) && defined(DEBUG_EVENTS)
15451576
parserutils_vector_dump(parser->tokens, __func__, tprinter);
15461577
#endif
1547-
if (parser->event != NULL) {
1548-
parser->event(CSS_PARSER_DECLARATION, parser->tokens,
1549-
parser->event_pw);
1578+
error = emit(parser, CSS_PARSER_DECLARATION, parser->tokens,
1579+
true);
1580+
if (error != CSS_OK) {
1581+
return error;
15501582
}
15511583
break;
15521584
}
@@ -2420,14 +2452,16 @@ css_error parseInlineStyle(css_parser *parser)
24202452
/* Emit fake events such that the language parser knows
24212453
* no different from a normal parse. */
24222454

2423-
if (parser->event != NULL) {
2424-
/* 1) begin stylesheet */
2425-
parser->event(CSS_PARSER_START_STYLESHEET, NULL,
2426-
parser->event_pw);
2455+
/* 1) begin stylesheet */
2456+
error = emit(parser, CSS_PARSER_START_STYLESHEET, NULL, true);
2457+
if (error != CSS_OK) {
2458+
return error;
2459+
}
24272460

2428-
/* 2) begin ruleset */
2429-
parser->event(CSS_PARSER_START_RULESET, NULL,
2430-
parser->event_pw);
2461+
/* 2) begin ruleset */
2462+
error = emit(parser, CSS_PARSER_START_RULESET, NULL, true);
2463+
if (error != CSS_OK) {
2464+
return error;
24312465
}
24322466

24332467
/* Fall through */
@@ -2450,14 +2484,16 @@ css_error parseInlineStyle(css_parser *parser)
24502484
discard_tokens(parser);
24512485

24522486
/* Emit remaining fake events to end the parse */
2453-
if (parser->event != NULL) {
2454-
/* 1) end ruleset */
2455-
parser->event(CSS_PARSER_END_RULESET, NULL,
2456-
parser->event_pw);
2457-
2458-
/* 2) end stylesheet */
2459-
parser->event(CSS_PARSER_END_STYLESHEET, NULL,
2460-
parser->event_pw);
2487+
/* 1) end ruleset */
2488+
error = emit(parser, CSS_PARSER_END_RULESET, NULL, true);
2489+
if (error != CSS_OK) {
2490+
return error;
2491+
}
2492+
2493+
/* 2) end stylesheet */
2494+
error = emit(parser, CSS_PARSER_END_STYLESHEET, NULL, true);
2495+
if (error != CSS_OK) {
2496+
return error;
24612497
}
24622498

24632499
break;

0 commit comments

Comments
 (0)