Skip to content

fix: reject attribute operators without a value - #352

Open
SAY-5 wants to merge 1 commit into
postcss:mainfrom
SAY-5:fix-missing-attribute-value-20261019
Open

SAY-5 wants to merge 1 commit into
postcss:mainfrom
SAY-5:fix-missing-attribute-value-20261019

Conversation

@SAY-5

@SAY-5 SAY-5 commented Oct 19, 2026

Copy link
Copy Markdown
Contributor

Fixes #199.

Attribute selectors such as [href=] currently parse without an error and stringify as [href], silently dropping the operator. Require a value whenever an attribute operator is present, using the parser's existing error path. Quoted empty values such as [href=""] remain valid.

The regression tests cover all six attribute operators, whitespace, comments, namespaces, synchronous and asynchronous APIs, and PostCSS error locations. On the original code, 16 expected-error tests fail while 13 valid-input controls pass; all 29 pass with the fix.

Validation: npm test passes all 926 tests, including lint, type checking, the build and coverage thresholds. Changed files pass formatting. The full formatting command reports the same two unchanged upstream files (exceptions.mjs and pseudos.mjs) on both the original and patched trees.

AI assistance was used to develop and review this change.

@MoOx

MoOx commented Nov 8, 2026

Copy link
Copy Markdown
Collaborator

Sorry for the three weeks of silence, that is on me.

The code is not the problem. Three lines, and I measured it on a corpus of 1176 generated attribute selectors: 96 inputs move from parsing to erroring, no output changes, and nothing that parsed before stops parsing. That is as surgical as you describe.

What holds me back is that it settles one fifth of a question. On current main these five are all invalid CSS and all behave the same way:

[href=]  ->  [href]
[href$]  ->  [href]
[href*]  ->  [href]
[href~]  ->  [href]
[href|]  ->  [href]

Your PR makes the first an error and leaves the other four silent, so the parser would end up refusing one invalid form and swallowing four. Chrome, lightningcss, css-tree and dart-sass reject all five, and the grammar agrees: <attr-matcher> = [ '~' | '|' | '^' | '$' | '*' ]? '=' always ends in =, so none of the five has a valid reading.

Would you be willing to extend it to the other four operators? I would rather settle all of them in one release, with one changelog note, than decide this a third at a time across three versions.

You will need a rebase either way: #335 has just landed and covers the neighbouring case, an attribute selector with no name at all. A trailing operator after a valid name is dropped there, which is exactly the behaviour your PR would replace.

If you would rather keep it narrow, say so and I will take it as it stands in a later minor rather than leave it sitting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

doesn't throw error on invalid attribute

2 participants