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.
This commit is contained in:
Andreas Kling 2020-05-26 22:29:37 +02:00
parent 72c52466e0
commit 7ed80ae96c
Notes: sideshowbarker 2024-07-19 06:06:02 +09:00

View file

@ -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;
}
}