LibWeb/CSS: Disallow invalid <counter-name> values

We now parse `<counter-name>` values as a `<custom-ident>`. This
disallows `default` and CSS-wide keywords as counter names. The
specification additionally disallows `none` as a counter name.
This commit is contained in:
Tim Ledbetter 2025-03-12 14:59:39 +00:00 committed by Sam Atkins
parent 76aa99a626
commit ad4ade3f07
Notes: github-actions[bot] 2025-03-13 05:24:17 +00:00
7 changed files with 151 additions and 3 deletions

View file

@ -895,12 +895,15 @@ RefPtr<CSSStyleValue> Parser::parse_counter_definitions_value(TokenStream<Compon
CounterDefinition definition {};
// <counter-name> | <reversed-counter-name>
auto& token = tokens.consume_a_token();
if (token.is(Token::Type::Ident)) {
definition.name = token.token().ident();
auto& token = tokens.next_token();
// A <counter-name> name cannot match the keyword none; such an identifier is invalid as a <counter-name>.
if (auto counter_name = parse_custom_ident_value(tokens, { { "none"sv } })) {
definition.name = counter_name->custom_ident();
definition.is_reversed = false;
} else if (allow_reversed == AllowReversed::Yes && token.is_function("reversed"sv)) {
TokenStream function_tokens { token.function().value };
tokens.discard_a_token();
function_tokens.discard_whitespace();
auto& name_token = function_tokens.consume_a_token();
if (!name_token.is(Token::Type::Ident))

View file

@ -0,0 +1,18 @@
Harness status: OK
Found 13 tests
13 Pass
Pass e.style['counter-increment'] = "none chapter" should not set the property value
Pass e.style['counter-increment'] = "reversed(none)" should not set the property value
Pass e.style['counter-increment'] = "reversed(chapter)" should not set the property value
Pass e.style['counter-increment'] = "3" should not set the property value
Pass e.style['counter-increment'] = "99 imagenum" should not set the property value
Pass e.style['counter-increment'] = "section -1, imagenum 99" should not set the property value
Pass e.style['counter-increment'] = "section 3.14" should not set the property value
Pass e.style['counter-increment'] = "inherit 1" should not set the property value
Pass e.style['counter-increment'] = "initial 1" should not set the property value
Pass e.style['counter-increment'] = "unset 1" should not set the property value
Pass e.style['counter-increment'] = "default 1" should not set the property value
Pass e.style['counter-increment'] = "revert 1" should not set the property value
Pass e.style['counter-increment'] = "revert-layer 1" should not set the property value

View file

@ -0,0 +1,20 @@
Harness status: OK
Found 15 tests
15 Pass
Pass e.style['counter-reset'] = "none chapter" should not set the property value
Pass e.style['counter-reset'] = "reversed(none)" should not set the property value
Pass e.style['counter-reset'] = "reversed(chapter) none" should not set the property value
Pass e.style['counter-reset'] = "3" should not set the property value
Pass e.style['counter-reset'] = "reversed(3)" should not set the property value
Pass e.style['counter-reset'] = "99 imagenum" should not set the property value
Pass e.style['counter-reset'] = "99 reversed(imagenum)" should not set the property value
Pass e.style['counter-reset'] = "section -1, imagenum 99" should not set the property value
Pass e.style['counter-reset'] = "section 3.14" should not set the property value
Pass e.style['counter-reset'] = "inherit 0" should not set the property value
Pass e.style['counter-reset'] = "initial 0" should not set the property value
Pass e.style['counter-reset'] = "unset 0" should not set the property value
Pass e.style['counter-reset'] = "default 0" should not set the property value
Pass e.style['counter-reset'] = "revert 0" should not set the property value
Pass e.style['counter-reset'] = "revert-layer 0" should not set the property value

View file

@ -0,0 +1,18 @@
Harness status: OK
Found 13 tests
13 Pass
Pass e.style['counter-set'] = "none chapter" should not set the property value
Pass e.style['counter-set'] = "reversed(none)" should not set the property value
Pass e.style['counter-set'] = "reversed(chapter)" should not set the property value
Pass e.style['counter-set'] = "3" should not set the property value
Pass e.style['counter-set'] = "99 imagenum" should not set the property value
Pass e.style['counter-set'] = "section -1, imagenum 99" should not set the property value
Pass e.style['counter-set'] = "section 3.14" should not set the property value
Pass e.style['counter-set'] = "inherit 2" should not set the property value
Pass e.style['counter-set'] = "initial 2" should not set the property value
Pass e.style['counter-set'] = "unset 2" should not set the property value
Pass e.style['counter-set'] = "default 2" should not set the property value
Pass e.style['counter-set'] = "revert 2" should not set the property value
Pass e.style['counter-set'] = "revert-layer 2" should not set the property value

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Lists: parsing counter-increment with invalid values</title>
<link rel="help" href="https://drafts.csswg.org/css-lists-3/#propdef-counter-increment">
<meta name="assert" content="counter-increment supports only the grammar '[ <counter-name> <integer>? ]+ | none'.">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../css/support/parsing-testcommon.js"></script>
</head>
<body>
<script>
test_invalid_value('counter-increment', 'none chapter');
test_invalid_value('counter-increment', 'reversed(none)');
test_invalid_value('counter-increment', 'reversed(chapter)');
test_invalid_value('counter-increment', '3');
test_invalid_value('counter-increment', '99 imagenum');
test_invalid_value('counter-increment', 'section -1, imagenum 99');
test_invalid_value('counter-increment', 'section 3.14');
test_invalid_value('counter-increment', 'inherit 1');
test_invalid_value('counter-increment', 'initial 1');
test_invalid_value('counter-increment', 'unset 1');
test_invalid_value('counter-increment', 'default 1');
test_invalid_value('counter-increment', 'revert 1');
test_invalid_value('counter-increment', 'revert-layer 1');
</script>
</body>
</html>

View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Lists: parsing counter-reset with invalid values</title>
<link rel="help" href="https://drafts.csswg.org/css-lists-3/#propdef-counter-reset">
<meta name="assert" content="counter-reset supports only the grammar '[ <counter-name> <integer>? | <reversed-counter-name> <integer>? ]+ | none'.">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../css/support/parsing-testcommon.js"></script>
</head>
<body>
<script>
test_invalid_value('counter-reset', 'none chapter');
test_invalid_value('counter-reset', 'reversed(none)');
test_invalid_value('counter-reset', 'reversed(chapter) none');
test_invalid_value('counter-reset', '3');
test_invalid_value('counter-reset', 'reversed(3)');
test_invalid_value('counter-reset', '99 imagenum');
test_invalid_value('counter-reset', '99 reversed(imagenum)');
test_invalid_value('counter-reset', 'section -1, imagenum 99');
test_invalid_value('counter-reset', 'section 3.14');
test_invalid_value('counter-reset', 'inherit 0');
test_invalid_value('counter-reset', 'initial 0');
test_invalid_value('counter-reset', 'unset 0');
test_invalid_value('counter-reset', 'default 0');
test_invalid_value('counter-reset', 'revert 0');
test_invalid_value('counter-reset', 'revert-layer 0');
</script>
</body>
</html>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Lists: parsing counter-set with invalid values</title>
<link rel="help" href="https://drafts.csswg.org/css-lists-3/#propdef-counter-set">
<meta name="assert" content="counter-set supports only the grammar '[ <counter-name> <integer>? ]+ | none'.">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../css/support/parsing-testcommon.js"></script>
</head>
<body>
<script>
test_invalid_value('counter-set', 'none chapter');
test_invalid_value('counter-set', 'reversed(none)');
test_invalid_value('counter-set', 'reversed(chapter)');
test_invalid_value('counter-set', '3');
test_invalid_value('counter-set', '99 imagenum');
test_invalid_value('counter-set', 'section -1, imagenum 99');
test_invalid_value('counter-set', 'section 3.14');
test_invalid_value('counter-set', 'inherit 2');
test_invalid_value('counter-set', 'initial 2');
test_invalid_value('counter-set', 'unset 2');
test_invalid_value('counter-set', 'default 2');
test_invalid_value('counter-set', 'revert 2');
test_invalid_value('counter-set', 'revert-layer 2');
</script>
</body>
</html>