summaryrefslogtreecommitdiff
path: root/src/parse/language.c
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2019-12-01 12:14:46 +0000
committerDaniel Silverstone <dsilvers@digital-scurf.org>2019-12-01 12:14:46 +0000
commit682a216c41d55a0c8d76297f2411277b6c699e39 (patch)
treefd92373a13382fa0c0d9d414095d5d7209fd79af /src/parse/language.c
parent1fb312312cdd01b3cf59950eacc7762f01c41a50 (diff)
downloadlibcss-682a216c41d55a0c8d76297f2411277b6c699e39.tar.gz
libcss-682a216c41d55a0c8d76297f2411277b6c699e39.tar.bz2
Add end-block-content parse event
In order to cope with a situation where a block ends with a selector which has no ruleset, add an end-block-content event and in handling it, pop any intermediate states off the language stack so that we're in block mode by the time the event is completed. This fixes an assert situation caused by a ruleset such as: @media screen { dodgy } .outer { top: 10px; } Which has been encountered in the wild (likely a typo). Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
Diffstat (limited to 'src/parse/language.c')
-rw-r--r--src/parse/language.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/parse/language.c b/src/parse/language.c
index 7fbfba7..c2d02d7 100644
--- a/src/parse/language.c
+++ b/src/parse/language.c
@@ -50,6 +50,8 @@ static css_error handleEndBlock(css_language *c,
const parserutils_vector *vector);
static css_error handleBlockContent(css_language *c,
const parserutils_vector *vector);
+static css_error handleEndBlockContent(css_language *c,
+ const parserutils_vector *vector);
static css_error handleDeclaration(css_language *c,
const parserutils_vector *vector);
@@ -219,6 +221,8 @@ css_error language_handle_event(css_parser_event type,
return handleEndBlock(language, tokens);
case CSS_PARSER_BLOCK_CONTENT:
return handleBlockContent(language, tokens);
+ case CSS_PARSER_END_BLOCK_CONTENT:
+ return handleEndBlockContent(language, tokens);
case CSS_PARSER_DECLARATION:
return handleDeclaration(language, tokens);
}
@@ -748,6 +752,40 @@ css_error handleBlockContent(css_language *c, const parserutils_vector *vector)
return CSS_OK;
}
+css_error handleEndBlockContent(css_language *c, const parserutils_vector *vector)
+{
+ context_entry *entry;
+ parserutils_error perror;
+ css_error ret;
+
+ /* First we call handleBlockContent() to deal with any intermediate
+ * tokens we have left
+ */
+ ret = handleBlockContent(c, vector);
+ if (ret != CSS_OK) {
+ return ret;
+ }
+
+ /* Our goal here is to ensure that the language parse stack is in the
+ * right state. We've encountered the end of a BlockContent such as
+ * @media ... { ... }
+ * and we need to ensure that the language stack reflects the end of
+ * that block, not any unfinished business within it such as
+ * @media ... { d }
+ */
+
+ entry = parserutils_stack_get_current(c->context);
+ while (entry != NULL && entry->type != CSS_PARSER_START_BLOCK) {
+ perror = parserutils_stack_pop(c->context, NULL);
+ if (perror != PARSERUTILS_OK) {
+ return css_error_from_parserutils_error(perror);
+ }
+ entry = parserutils_stack_get_current(c->context);
+ }
+
+ return CSS_OK;
+}
+
css_error handleDeclaration(css_language *c, const parserutils_vector *vector)
{
css_error error;