summaryrefslogtreecommitdiff
path: root/Libraries/LibWeb/Parser/CSSParser.cpp
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-05-26 22:29:37 +0200
committerAndreas Kling <kling@serenityos.org>2020-05-26 22:31:22 +0200
commit7ed80ae96cb4ac731aff9db7629183154ab72f1b (patch)
tree324115c65e25351543116b9ec48782095913b124 /Libraries/LibWeb/Parser/CSSParser.cpp
parent72c52466e0c2a8cb133c3ee6131be484cb3147e0 (diff)
downloadserenity-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.cpp18
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;
}
}