Skip to content

fix: reject attribute operators without a value - #352

Merged
MoOx merged 2 commits into
postcss:mainfrom
SAY-5:fix-missing-attribute-value-20261019
Nov 12, 2026
Merged

MoOx merged 2 commits 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.

Reject attribute selectors that silently discard an incomplete matcher or an operator without a value. [href=], [href$], [href*], [href~], [href|], and [href^] now report syntax errors through the existing parser error path. Quoted empty values such as [href=""], attribute namespaces, escaped matcher characters, and interpolated names remain supported.

Rebased onto current main after #335, preserving its missing-name validation. The five existing trailing-matcher tests now require syntax errors, and one changelog entry covers the combined behavior change.

The 69 regression tests cover all six complete operators, incomplete matchers, whitespace, comments, namespaces, synchronous/asynchronous APIs, and PostCSS error locations. Before the fix, 52 tests fail and 17 pass; all 69 pass with the fix. The already-rejected [href|/**/] case remains a control.

Validation on macOS with Node 26.3.0 and the exact locked dependencies: npm test passes all 1,088 tests, including lint, type checking, build, and coverage thresholds (95.49% lines, 96.16% branches, 97.85% functions). Lint reports two warnings in unchanged upstream exceptions.mjs. Changed JavaScript files pass formatting; the full format check reports only unchanged upstream exceptions.mjs and pseudos.mjs.

All four Ubuntu/Windows CI jobs passed on 98338ce51531cf81e54bb7860c0c8b5b19dcf667.

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.

@SAY-5
SAY-5 force-pushed the fix-missing-attribute-value-20261019 branch from 5512a84 to 98338ce Compare November 11, 2026 21:18
@SAY-5

SAY-5 commented Nov 11, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto main after #335 and extended the fix to all five trailing matcher characters, including ^. The missing-name validation, namespaces, escaped characters, interpolation, and quoted empty values are preserved, with one changelog note.

The regression file goes from 52 failures / 17 passes to 69 passes, and the full local pipeline passes all 1,088 tests and coverage thresholds. All four Ubuntu/Windows CI jobs passed on 98338ce51531cf81e54bb7860c0c8b5b19dcf667.

@MoOx
MoOx merged commit 44deaeb into postcss:main Nov 12, 2026
4 checks passed
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