fix: keep comment-like text inside attribute-selector strings#654
Open
spokodev wants to merge 1 commit into
Open
fix: keep comment-like text inside attribute-selector strings#654spokodev wants to merge 1 commit into
spokodev wants to merge 1 commit into
Conversation
The selector parser stripped `/* ... */` from the whole selector string
before splitting on commas, ignoring quoted strings. A `/*` inside a
quoted attribute value is literal string content, not a comment, so this
silently destroyed the value:
parse('a[title="/*x*/"]{color:red}').stylesheet.rules[0].selectors
// was: ['a[title=""]'] -> now: ['a[title="/*x*/"]']
parse('a[data="a/*b*/c"]{color:red}').stylesheet.rules[0].selectors
// was: ['a[data="ac"]'] -> now: ['a[data="a/*b*/c"]']
Per CSS Syntax Level 3, comment tokens are only recognized at the top
level; once a string token begins, `/*` does not start a comment.
Add removeCommentWithQuoteSupport to the existing stringSearch utility,
mirroring its quote-aware scanning, and use it in selector() instead of
the naive regex replace. Real comments outside strings are still removed
(a:not(/*x*/.b) -> a:not(.b), a /*c*/ b -> a b). The declaration-value
comment strip is left unchanged.
5ee5c08 to
f7b8cd8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The selector parser strips
/* ... */from the entire selector string before splitting on commas, without checking for quoted strings. A/*that appears inside a quoted attribute value is literal string content, not a comment, so the value is silently destroyed:This is silent data corruption: the AST holds a different selector than the input, so
stringify(parse(s))emits a rule that no longer matches the same elements.Spec
CSS Syntax Level 3 recognizes comment tokens only at the top level of tokenization. Once a string token has begun (after
"or'),/*does not start a comment, so[title="/*x*/"]has the literal attribute value/*x*/.Fix
Add
removeCommentWithQuoteSupportto the existingstringSearchutility, mirroring the quote-aware scanning already used byindexOfArrayWithBracketAndQuoteSupport(it reusesindexOfArrayNonEscapedto find the matching close quote and respects backslash escapes).selector()now calls it instead of the naivecommentRegexreplace.Real comments outside strings are still stripped, so existing behavior is preserved:
a:not(/*x*/.b)->a:not(.b)a /*c*/ b->a bhead, /* footer, */body/*, nav */->["head", "body"](issue Incorrect comment handling in some edge-case #175 case, still green)The declaration-value comment strip (
declaration()) is left untouched.Tests
Added a
describeblock intest/parse.test.tscovering the corrupted cases (double-quoted, single-quoted, spliced, real-comment-adjacent) plus guard cases that assert real comments are still removed. Full suite: 228 passing, lint clean.