1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 08:08:12 +00:00

LibWeb: Make the ad-hoc CSS parser a little more tolerant

Just bail when encountering some unexpected character. This makes it
much more tolerable to type a stylesheet into TextEditor with live
HTML preview enabled.
This commit is contained in:
Andreas Kling 2020-12-12 11:47:11 +01:00
parent b60801a9ba
commit ec89302fbe

View file

@ -442,17 +442,22 @@ public:
return 0; return 0;
} }
char consume_specific(char ch) bool consume_specific(char ch)
{ {
if (peek() != ch) { if (peek() != ch) {
dbg() << "peek() != '" << ch << "'"; dbgln("CSSParser: Peeked '{:c}' wanted specific '{:c}'", peek(), ch);
}
if (!peek()) {
PARSE_ERROR();
return false;
} }
if (peek() != ch) { if (peek() != ch) {
PARSE_ERROR(); PARSE_ERROR();
++index;
return false;
} }
PARSE_ASSERT(index < css.length());
++index; ++index;
return ch; return true;
} }
char consume_one() char consume_one()
@ -600,10 +605,13 @@ public:
simple_selector.attribute_match_type = attribute_match_type; simple_selector.attribute_match_type = attribute_match_type;
simple_selector.attribute_name = attribute_name; simple_selector.attribute_name = attribute_name;
simple_selector.attribute_value = attribute_value; simple_selector.attribute_value = attribute_value;
if (expected_end_of_attribute_selector != ']') if (expected_end_of_attribute_selector != ']') {
consume_specific(expected_end_of_attribute_selector); if (!consume_specific(expected_end_of_attribute_selector))
return {};
}
consume_whitespace_or_comments(); consume_whitespace_or_comments();
consume_specific(']'); if (!consume_specific(']'))
return {};
} }
if (peek() == ':') { if (peek() == ':') {
@ -618,10 +626,14 @@ public:
buffer.append(consume_one()); buffer.append(consume_one());
buffer.append(consume_one()); buffer.append(consume_one());
buffer.append(consume_one()); buffer.append(consume_one());
buffer.append(consume_specific('(')); if (!consume_specific('('))
return {};
buffer.append('(');
while (peek() != ')') while (peek() != ')')
buffer.append(consume_one()); buffer.append(consume_one());
buffer.append(consume_specific(')')); if (!consume_specific(')'))
return {};
buffer.append(')');
} else { } else {
while (is_valid_selector_char(peek())) while (is_valid_selector_char(peek()))
buffer.append(consume_one()); buffer.append(consume_one());
@ -854,15 +866,18 @@ public:
auto property_name = String::copy(buffer); auto property_name = String::copy(buffer);
buffer.clear(); buffer.clear();
consume_whitespace_or_comments(); consume_whitespace_or_comments();
consume_specific(':'); if (!consume_specific(':'))
return {};
consume_whitespace_or_comments(); consume_whitespace_or_comments();
auto [property_value, important] = consume_css_value(); auto [property_value, important] = consume_css_value();
consume_whitespace_or_comments(); consume_whitespace_or_comments();
if (peek() && peek() != '}') if (peek() && peek() != '}') {
consume_specific(';'); if (!consume_specific(';'))
return {};
}
auto property_id = CSS::property_id_from_string(property_name); auto property_id = CSS::property_id_from_string(property_name);
if (property_id == CSS::PropertyID::Invalid) { if (property_id == CSS::PropertyID::Invalid) {
@ -881,7 +896,7 @@ public:
if (property.has_value()) if (property.has_value())
current_rule.properties.append(property.value()); current_rule.properties.append(property.value());
consume_whitespace_or_comments(); consume_whitespace_or_comments();
if (peek() == '}') if (!peek() || peek() == '}')
break; break;
} }
} }
@ -889,7 +904,7 @@ public:
void parse_rule() void parse_rule()
{ {
consume_whitespace_or_comments(); consume_whitespace_or_comments();
if (index >= css.length()) if (!peek())
return; return;
// FIXME: We ignore @-rules for now. // FIXME: We ignore @-rules for now.
@ -912,9 +927,15 @@ public:
} }
parse_selector_list(); parse_selector_list();
consume_specific('{'); if (!consume_specific('{')) {
PARSE_ERROR();
return;
}
parse_declaration(); parse_declaration();
consume_specific('}'); if (!consume_specific('}')) {
PARSE_ERROR();
return;
}
rules.append(CSS::StyleRule::create(move(current_rule.selectors), CSS::StyleDeclaration::create(move(current_rule.properties)))); rules.append(CSS::StyleRule::create(move(current_rule.selectors), CSS::StyleDeclaration::create(move(current_rule.properties))));
consume_whitespace_or_comments(); consume_whitespace_or_comments();
} }
@ -926,7 +947,7 @@ public:
index += 3; index += 3;
} }
while (index < css.length()) { while (peek()) {
parse_rule(); parse_rule();
} }