mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:27:35 +00:00
LibWeb: Fix CSS attribute and ID selector parsing
There were several crashes here from out-of-bounds memory access.
This commit is contained in:
parent
78d191554a
commit
e5ac5e1fab
1 changed files with 20 additions and 14 deletions
|
@ -231,7 +231,6 @@ Optional<Selector> Parser::parse_single_selector(TokenStream<T>& tokens, bool is
|
||||||
|
|
||||||
auto parse_simple_selector = [&]() -> Optional<Selector::SimpleSelector> {
|
auto parse_simple_selector = [&]() -> Optional<Selector::SimpleSelector> {
|
||||||
auto current_value = tokens.next_token();
|
auto current_value = tokens.next_token();
|
||||||
dbgln("parse_simple_selector, start token: {}", current_value.to_string());
|
|
||||||
if (check_for_eof_or_whitespace(current_value))
|
if (check_for_eof_or_whitespace(current_value))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -267,11 +266,19 @@ Optional<Selector> Parser::parse_single_selector(TokenStream<T>& tokens, bool is
|
||||||
|
|
||||||
type = Selector::SimpleSelector::Type::Class;
|
type = Selector::SimpleSelector::Type::Class;
|
||||||
value = current_value.to_string();
|
value = current_value.to_string();
|
||||||
} else if (current_value.is(Token::Type::Delim) && ((Token)current_value).delim() == "*") {
|
} else if (current_value.is(Token::Type::Delim) && current_value.token().delim() == "*") {
|
||||||
type = Selector::SimpleSelector::Type::Universal;
|
type = Selector::SimpleSelector::Type::Universal;
|
||||||
} else {
|
} else if (current_value.is(Token::Type::Ident)) {
|
||||||
type = Selector::SimpleSelector::Type::TagName;
|
type = Selector::SimpleSelector::Type::TagName;
|
||||||
value = current_value.to_string().to_lowercase();
|
value = current_value.token().ident().to_lowercase_string();
|
||||||
|
} else if ((current_value.is(Token::Type::Delim) && current_value.token().delim() == ":")
|
||||||
|
|| (current_value.is_block() && current_value.block().is_square())) {
|
||||||
|
// FIXME: This is a temporary hack until we make the Selector::SimpleSelector::Type changes.
|
||||||
|
type = Selector::SimpleSelector::Type::Universal;
|
||||||
|
tokens.reconsume_current_input_token();
|
||||||
|
} else {
|
||||||
|
dbgln("Invalid simple selector!");
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
Selector::SimpleSelector simple_selector;
|
Selector::SimpleSelector simple_selector;
|
||||||
|
@ -302,13 +309,10 @@ Optional<Selector> Parser::parse_single_selector(TokenStream<T>& tokens, bool is
|
||||||
simple_selector.attribute_match_type = Selector::SimpleSelector::AttributeMatchType::HasAttribute;
|
simple_selector.attribute_match_type = Selector::SimpleSelector::AttributeMatchType::HasAttribute;
|
||||||
simple_selector.attribute_name = attribute_part.token().ident();
|
simple_selector.attribute_name = attribute_part.token().ident();
|
||||||
|
|
||||||
size_t attribute_index = 0;
|
if (attribute_parts.size() == 1)
|
||||||
while (attribute_parts.at(attribute_index).is(Token::Type::Whitespace)) {
|
return simple_selector;
|
||||||
attribute_index++;
|
|
||||||
if (attribute_index >= attribute_parts.size())
|
|
||||||
return simple_selector;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
size_t attribute_index = 1;
|
||||||
auto& delim_part = attribute_parts.at(attribute_index);
|
auto& delim_part = attribute_parts.at(attribute_index);
|
||||||
if (!delim_part.is(Token::Type::Delim)) {
|
if (!delim_part.is(Token::Type::Delim)) {
|
||||||
dbgln("Expected a delim for attribute comparison, got: '{}'", delim_part.to_string());
|
dbgln("Expected a delim for attribute comparison, got: '{}'", delim_part.to_string());
|
||||||
|
@ -326,7 +330,7 @@ Optional<Selector> Parser::parse_single_selector(TokenStream<T>& tokens, bool is
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& delim_second_part = attribute_parts.at(attribute_index);
|
auto& delim_second_part = attribute_parts.at(attribute_index);
|
||||||
if (!(delim_part.is(Token::Type::Delim) && delim_part.token().delim() == "=")) {
|
if (!(delim_second_part.is(Token::Type::Delim) && delim_second_part.token().delim() == "=")) {
|
||||||
dbgln("Expected a double delim for attribute comparison, got: '{}{}'", delim_part.to_string(), delim_second_part.to_string());
|
dbgln("Expected a double delim for attribute comparison, got: '{}{}'", delim_part.to_string(), delim_second_part.to_string());
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -450,6 +454,8 @@ Optional<Selector> Parser::parse_single_selector(TokenStream<T>& tokens, bool is
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tokens.reconsume_current_input_token();
|
||||||
|
|
||||||
return simple_selector;
|
return simple_selector;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -785,12 +791,12 @@ Optional<StyleDeclarationRule> Parser::consume_a_declaration(TokenStream<T>& tok
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
while (!declaration.m_values.is_empty()) {
|
||||||
auto maybe_whitespace = declaration.m_values.at(declaration.m_values.size() - 1);
|
auto maybe_whitespace = declaration.m_values.last();
|
||||||
if (!(maybe_whitespace.is(Token::Type::Whitespace))) {
|
if (!(maybe_whitespace.is(Token::Type::Whitespace))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
declaration.m_values.remove(declaration.m_values.size() - 1);
|
declaration.m_values.take_last();
|
||||||
}
|
}
|
||||||
|
|
||||||
return declaration;
|
return declaration;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue