diff options
author | Andreas Kling <kling@serenityos.org> | 2020-05-26 22:29:37 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-05-26 22:31:22 +0200 |
commit | 7ed80ae96cb4ac731aff9db7629183154ab72f1b (patch) | |
tree | 324115c65e25351543116b9ec48782095913b124 /Libraries/LibWeb/Parser/CSSParser.cpp | |
parent | 72c52466e0c2a8cb133c3ee6131be484cb3147e0 (diff) | |
download | serenity-7ed80ae96cb4ac731aff9db7629183154ab72f1b.zip |
LibWeb: Make the CSS parser a little more tolerant to invalid CSS
Sometimes people put a '}' where it doesn't belong, or various other
things go wrong. 99% of the time, it's our fault, but either way,
this patch makes us not crash or infinite-loop in some common cases.
The real solution here is to write a proper CSS lexer-parser according
to the language spec, this is just a hack fix to make more sites load
at all.
Diffstat (limited to 'Libraries/LibWeb/Parser/CSSParser.cpp')
-rw-r--r-- | Libraries/LibWeb/Parser/CSSParser.cpp | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/Libraries/LibWeb/Parser/CSSParser.cpp b/Libraries/LibWeb/Parser/CSSParser.cpp index e7ded2342a..0ba115e7e9 100644 --- a/Libraries/LibWeb/Parser/CSSParser.cpp +++ b/Libraries/LibWeb/Parser/CSSParser.cpp @@ -39,6 +39,11 @@ ASSERT_NOT_REACHED(); \ } +#define PARSE_ERROR() \ + do { \ + dbg() << "CSS parse error"; \ + } while (0) + namespace Web { static CSS::ValueID value_id_for_palette_string(const StringView& string) @@ -348,7 +353,9 @@ public: if (peek() != ch) { dbg() << "peek() != '" << ch << "'"; } - PARSE_ASSERT(peek() == ch); + if (peek() != ch) { + PARSE_ERROR(); + } PARSE_ASSERT(index < css.length()); ++index; return ch; @@ -512,7 +519,6 @@ public: auto pseudo_name = String::copy(buffer); buffer.clear(); - // Ignore for now, otherwise we produce a "false positive" selector // and apply styles to the element itself, not its pseudo element if (is_pseudo_element) @@ -590,12 +596,16 @@ public: Vector<Selector::ComplexSelector> complex_selectors; for (;;) { + auto index_before = index; auto complex_selector = parse_complex_selector(); if (complex_selector.has_value()) complex_selectors.append(complex_selector.value()); consume_whitespace_or_comments(); if (!peek() || peek() == ',' || peek() == '{') break; + // HACK: If we didn't move forward, just let go. + if (index == index_before) + break; } if (complex_selectors.is_empty()) @@ -616,6 +626,7 @@ public: void parse_selector_list() { for (;;) { + auto index_before = index; parse_selector(); consume_whitespace_or_comments(); if (peek() == ',') { @@ -624,6 +635,9 @@ public: } if (peek() == '{') break; + // HACK: If we didn't move forward, just let go. + if (index_before == index) + break; } } |