Skip to content

Commit

Permalink
[css-syntax-3] Prevent invalid custom props from parsing as rules, pe…
Browse files Browse the repository at this point in the history
…r resolution.
  • Loading branch information
tabatkins committed May 11, 2023
1 parent 59e4322 commit 14a0f8c
Showing 1 changed file with 53 additions and 1 deletion.
54 changes: 53 additions & 1 deletion css-syntax-3/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -2584,7 +2584,59 @@ Consume a qualified rule</h4>

<dt><a href="#tokendef-open-curly">&lt;{-token></a>
<dd>
[=Consume a block=] from |input|,
If the first two non-<<whitespace-token>> values
of |rule|'s prelude are
an <<ident-token>> whose value starts with "--"
followed by a <<colon-token>>,
[=consume the remnants of a bad declaration=] from |input|,
with |nested|,
and return nothing.

<details class=note>
<summary>What's this check for?</summary>

[=Declarations=] and [=qualified rules=]
overlap in their generic syntax;
<code>foo:bar {};</code>
could be a <css>foo</css> property
with a value of <css>bar {}</css>,
or a qualified rule
with a <css>foo:bar</css> prelude
and an empty block.

Validity checking ensures that they're parsed correctly,
but this still allows an <em>invalid</em> declaration
to get parsed as a rule.
This isn't generally a problem--
the CSSWG has not yet defined any declarations
with {}-blocks in their values,
so [=consume a qualified rule=] will hit the semicolon and stop,
consuming the same amount of tokens as the declaration would have.
(And if we do define such a declaration,
we'll take care to preserve this aspect.)

[=Custom properties=], however, don't have the CSSWG
carefully vetting their syntax.
Authors <em>can</em> write a custom property
that takes a {}-block in its value;
if that custom property is then invalid
(due to an invalidly-written ''var()'' function, for example),
when it's parsed by [=consume a qualified rule=]
it will stop early, at the {}-block.
The remaining tokens of the custom property's value
will then get parsed as a fresh construct,
potentially causing unexpected declarations or rules
to be created.

To avoid this (admittedly very niche) corner-case,
we subtract the syntax of a [=custom property=]
from that of a [=qualified rule=];
if you somehow end up parsing a rule
that looks like a [=custom property=],
you've messed up and need to treat it like an (invalid) property.
</details>

Otherwise, [=consume a block=] from |input|,
and assign the results to |rule|'s
lists of [=declarations=] and child [=rules=].

Expand Down

0 comments on commit 14a0f8c

Please sign in to comment.