Skip to content

Commit 9d7f253

Browse files
Don't extract links as arbitrary properties (#17129)
Closes #17128 This PR prevents extraction of links inside square brackets as valid candidate: ``` [https://example/] ``` We do this by throwing out arbitrary properties when the value starts with a slash (`/`). ## Test plan - Added unit test --------- Co-authored-by: Robin Malfait <[email protected]>
1 parent 785cade commit 9d7f253

File tree

2 files changed

+11
-0
lines changed

2 files changed

+11
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2424
- Treat starting single quote as verbatim text in Slim ([#17085](https://github.com/tailwindlabs/tailwindcss/pull/17085))
2525
- Ensure `.node` and `.wasm` files are not scanned for utilities ([#17123](https://github.com/tailwindlabs/tailwindcss/pull/17123))
2626
- Improve performance when scanning `JSON` files ([#17125](https://github.com/tailwindlabs/tailwindcss/pull/17125))
27+
- Don't create invalid CSS when encountering a link wrapped in square brackets ([#17129](https://github.com/tailwindlabs/tailwindcss/pull/17129))
2728

2829
## [4.0.12] - 2025-03-07
2930

crates/oxide/src/extractor/arbitrary_property_machine.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ impl Machine for ArbitraryPropertyMachine<ParsingValueState> {
163163
#[inline]
164164
fn next(&mut self, cursor: &mut cursor::Cursor<'_>) -> MachineState {
165165
let len = cursor.input.len();
166+
let start_of_value_pos = cursor.pos;
166167
while cursor.pos < len {
167168
match cursor.curr.into() {
168169
Class::Escape => match cursor.next.into() {
@@ -222,6 +223,9 @@ impl Machine for ArbitraryPropertyMachine<ParsingValueState> {
222223
// Any kind of whitespace is not allowed
223224
Class::Whitespace => return self.restart(),
224225

226+
// URLs are not allowed
227+
Class::Slash if start_of_value_pos == cursor.pos => return self.restart(),
228+
225229
// Everything else is valid
226230
_ => cursor.advance(),
227231
};
@@ -278,6 +282,9 @@ enum Class {
278282
#[bytes(b':')]
279283
Colon,
280284

285+
#[bytes(b'/')]
286+
Slash,
287+
281288
#[bytes(b' ', b'\t', b'\n', b'\r', b'\x0C')]
282289
Whitespace,
283290

@@ -341,6 +348,9 @@ mod tests {
341348
("[:red]", vec![]),
342349
// Empty brackets are not allowed
343350
("[]", vec![]),
351+
// URLs
352+
("[http://example.com]", vec![]),
353+
("[https://example.com]", vec![]),
344354
// Missing colon in more complex example
345355
(r#"[CssClass("gap-y-4")]"#, vec![]),
346356
// Brackets must be balanced

0 commit comments

Comments
 (0)