Skip to content

Commit 6c0c6a5

Browse files
authored
Discard invalid variants and utilities with modifiers (tailwindlabs#13977)
* ensure that static utilities do not take a `modifier` * do not allow multiple segments for now Right now, `bg-red-1/2/3` should not parse * add tests for variants that don't accept a modifier * ensure static variants do not accept a modifier * do not accept a modifier for some variants * add tests for utilities that don't accept a modifier * do not accept a modifier for some utilities * update changelog * re-add sorting related test
1 parent de48a76 commit 6c0c6a5

File tree

7 files changed

+2159
-195
lines changed

7 files changed

+2159
-195
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
- Discard invalid classes such as `bg-red-[#000]` ([#13970](https://github.com/tailwindlabs/tailwindcss/pull/13970))
1313
- Fix parsing body-less at-rule without terminating semicolon ([#13978](https://github.com/tailwindlabs/tailwindcss/pull/13978))
1414
- Ensure opacity modifier with variables work with `color-mix()` ([#13972](https://github.com/tailwindlabs/tailwindcss/pull/13972))
15+
- Discard invalid `variants` and `utilities` with modifiers ([#13977](https://github.com/tailwindlabs/tailwindcss/pull/13977))
1516

1617
## [4.0.0-alpha.17] - 2024-07-04
1718

packages/tailwindcss/src/candidate.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,27 @@ it('should not parse a partial utility', () => {
445445
expect(run('bg-', { utilities })).toMatchInlineSnapshot(`null`)
446446
})
447447

448+
it('should not parse static utilities with a modifier', () => {
449+
let utilities = new Utilities()
450+
utilities.static('flex', () => [])
451+
452+
expect(run('flex/foo', { utilities })).toMatchInlineSnapshot(`null`)
453+
})
454+
455+
it('should not parse static utilities with multiple modifiers', () => {
456+
let utilities = new Utilities()
457+
utilities.static('flex', () => [])
458+
459+
expect(run('flex/foo/bar', { utilities })).toMatchInlineSnapshot(`null`)
460+
})
461+
462+
it('should not parse functional utilities with multiple modifiers', () => {
463+
let utilities = new Utilities()
464+
utilities.functional('bg', () => [])
465+
466+
expect(run('bg-red-1/2/3', { utilities })).toMatchInlineSnapshot(`null`)
467+
})
468+
448469
it('should parse a utility with an arbitrary value', () => {
449470
let utilities = new Utilities()
450471
utilities.functional('bg', () => [])

packages/tailwindcss/src/candidate.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,14 @@ export function parseCandidate(input: string, designSystem: DesignSystem): Candi
258258
// ^^^^^^^^^^ -> Base without modifier
259259
// ^^ -> Modifier segment
260260
// ```
261-
let [baseWithoutModifier, modifierSegment = null] = segment(base, '/')
261+
let [baseWithoutModifier, modifierSegment = null, additionalModifier] = segment(base, '/')
262+
263+
// If there's more than one modifier, the utility is invalid.
264+
//
265+
// E.g.:
266+
//
267+
// - `bg-red-500/50/50`
268+
if (additionalModifier) return null
262269

263270
// Arbitrary properties
264271
if (baseWithoutModifier[0] === '[') {
@@ -373,8 +380,12 @@ export function parseCandidate(input: string, designSystem: DesignSystem): Candi
373380
let kind = designSystem.utilities.kind(root)
374381

375382
if (kind === 'static') {
383+
// Static utilities do not have a value
376384
if (value !== null) return null
377385

386+
// Static utilities do not have a modifier
387+
if (modifierSegment !== null) return null
388+
378389
return {
379390
kind: 'static',
380391
root,
@@ -557,8 +568,12 @@ export function parseVariant(variant: string, designSystem: DesignSystem): Varia
557568

558569
switch (designSystem.variants.kind(root)) {
559570
case 'static': {
571+
// Static variants do not have a value
560572
if (value !== null) return null
561573

574+
// Static variants do not have a modifier
575+
if (modifier !== null) return null
576+
562577
return {
563578
kind: 'static',
564579
root,

0 commit comments

Comments
 (0)