Don't treat \ as an escape inside CSS comments
Per the CSS Syntax spec, a comment ends at the first `*/`; escapes are not processed inside comments. The parser skipped the character after a `\`, so a comment like `/* C:\temp\*/` was never closed and swallowed (or corrupted) the CSS that followed it.
This commit is contained in:
parent
41d9cae8e5
commit
8fc1bb848e
3 changed files with 45 additions and 13 deletions
|
|
@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Only normalize top-level `and`, `or`, and `not` keywords in `supports-[…]` variants (e.g. `selector(a: not (.foo))` → `selector(a:not(.foo))`) ([#20420](https://github.com/tailwindlabs/tailwindcss/pull/20420))
|
||||
- Don't warn about Angular's `::ng-deep` and `:host-context()` when optimizing CSS ([#20434](https://github.com/tailwindlabs/tailwindcss/pull/20434))
|
||||
- Don't generate CSS for candidates containing an empty additional modifier (e.g. `bg-red-500/50/` and `group-hover/foo//bar:flex`) ([#20466](https://github.com/tailwindlabs/tailwindcss/pull/20466))
|
||||
- Ensure CSS comments ending with `\*/` are closed correctly instead of swallowing the CSS that follows (e.g. `/* C:\temp\*/`)
|
||||
|
||||
## [4.3.3] - 2026-07-16
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,23 @@ describe.each(['Unix', 'Windows'])('Line endings: %s', (lineEndings) => {
|
|||
).toEqual([])
|
||||
})
|
||||
|
||||
it('should end a comment at `*/` even when it is preceded by a `\\`', () => {
|
||||
expect(
|
||||
parse(css`
|
||||
/* C:\temp\*/
|
||||
.foo {
|
||||
color: red;
|
||||
}
|
||||
`),
|
||||
).toEqual([
|
||||
{
|
||||
kind: 'rule',
|
||||
selector: '.foo',
|
||||
nodes: [{ kind: 'declaration', property: 'color', value: 'red', important: false }],
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
it('should parse a comment inside of a selector and ignore it', () => {
|
||||
expect(
|
||||
parse(css`
|
||||
|
|
@ -448,6 +465,28 @@ describe.each(['Unix', 'Windows'])('Line endings: %s', (lineEndings) => {
|
|||
])
|
||||
})
|
||||
|
||||
it('should end a comment in a custom property at `*/` even when it is preceded by a `\\`', () => {
|
||||
expect(
|
||||
parse(css`
|
||||
--foo: /* C:\temp\*/ bar;
|
||||
--bar: /* baz */ qux;
|
||||
`),
|
||||
).toEqual([
|
||||
{
|
||||
kind: 'declaration',
|
||||
property: '--foo',
|
||||
value: '/* C:\\temp\\*/ bar',
|
||||
important: false,
|
||||
},
|
||||
{
|
||||
kind: 'declaration',
|
||||
property: '--bar',
|
||||
value: '/* baz */ qux',
|
||||
important: false,
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
it('should parse empty custom properties', () => {
|
||||
expect(
|
||||
parse(css`
|
||||
|
|
|
|||
|
|
@ -134,13 +134,9 @@ export function parse(input: string, opts?: ParseOptions) {
|
|||
for (let j = i + 2; j < input.length; j++) {
|
||||
peekChar = input.charCodeAt(j)
|
||||
|
||||
// Current character is a `\` therefore the next character is escaped.
|
||||
if (peekChar === BACKSLASH) {
|
||||
j += 1
|
||||
}
|
||||
|
||||
// End of the comment
|
||||
else if (peekChar === ASTERISK && input.charCodeAt(j + 1) === SLASH) {
|
||||
// End of the comment. Escapes are not processed inside of comments,
|
||||
// so a `\` right before the closing `*/` does not escape it.
|
||||
if (peekChar === ASTERISK && input.charCodeAt(j + 1) === SLASH) {
|
||||
i = j + 1
|
||||
break
|
||||
}
|
||||
|
|
@ -224,13 +220,9 @@ export function parse(input: string, opts?: ParseOptions) {
|
|||
else if (peekChar === SLASH && input.charCodeAt(j + 1) === ASTERISK) {
|
||||
for (let k = j + 2; k < input.length; k++) {
|
||||
peekChar = input.charCodeAt(k)
|
||||
// Current character is a `\` therefore the next character is escaped.
|
||||
if (peekChar === BACKSLASH) {
|
||||
k += 1
|
||||
}
|
||||
|
||||
// End of the comment
|
||||
else if (peekChar === ASTERISK && input.charCodeAt(k + 1) === SLASH) {
|
||||
// End of the comment. Escapes are not processed inside of comments.
|
||||
if (peekChar === ASTERISK && input.charCodeAt(k + 1) === SLASH) {
|
||||
j = k + 1
|
||||
break
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue