Files
Robin Malfait 2ce6652f1c Don't let quotes in Pug regex literals hide the end of an attribute list (#20572)
This is a follow-up to
https://github.com/tailwindlabs/tailwindcss/pull/20547.

That PR tracks strings inside Pug attribute lists, so that brackets in
values like `a(title="a (b")` are ignored. But a quote that isn't a
string delimiter, like the `"` in a regex such as
`input(pattern=/"/.source)`, opened a string that never closed. That
string hid the `)` of the attribute list. The list stayed open, so dots
in class shorthands on later lines were not turned into spaces, and
classes like `underline` in `span.underline.font-bold` were not
extracted.

```pug
input(pattern=/"/.source)
span.underline.font-bold km
```

## Solution

Only template literals can span lines in JavaScript. So when a `'` or
`"` string reaches the end of its line without a closing quote, it was
not a string. In that case, we go back to just after the quote and scan
the rest of the line again, with quotes as plain text. Each line is
scanned at most twice, so this stays linear.

Detecting regex literals directly needs a JavaScript tokenizer, because
a `/` can also be a division. This approach also covers other unpaired
quotes, like `// don't cache` in a `script.` block.

The regression is not released yet, so there is no changelog entry: the
existing entry of https://github.com/tailwindlabs/tailwindcss/pull/20547
covers it.

## Test plan

Added cases to `test_unbalanced_brackets_in_quoted_attribute_values` in
`pug.rs`. They fail without this change.

```
cargo test -p tailwindcss-oxide
```
2026-10-14 19:07:28 +02:00
..