Skip to content

Commit f945c3d

Browse files
Don’t index into strings with the theme(…) function (#19111)
Indexing into a string is only ever going to produce a single character and is almost guaranteed to be a mistake. The legacy keypath notation is meant to traverse objects and arrays — not strings. Fixes #19104
1 parent 2cba831 commit f945c3d

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1818
- Fix resolving theme keys when starting with the name of another theme key in JS configs and plugins ([#19097](https://github.com/tailwindlabs/tailwindcss/pull/19097))
1919
- Allow named groups in combination with `not-*`, `has-*`, and `in-*` ([#19100](https://github.com/tailwindlabs/tailwindcss/pull/19100))
2020
- Prevent important utilities from affecting other utilities ([#19110](https://github.com/tailwindlabs/tailwindcss/pull/19110))
21+
- Don’t index into strings with the `theme(…)` function ([#19111](https://github.com/tailwindlabs/tailwindcss/pull/19111))
2122
- Upgrade: Canonicalize utilities containing `0` values ([#19095](https://github.com/tailwindlabs/tailwindcss/pull/19095))
2223

2324
## [4.1.14] - 2025-10-01

packages/tailwindcss/src/compat/config.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,3 +1687,35 @@ test('handles setting theme keys to null', async () => {
16871687
"
16881688
`)
16891689
})
1690+
1691+
test('The theme() function does not try indexing into strings', async () => {
1692+
let compiler = await compile(css`
1693+
@theme default {
1694+
--color-what-50: #f00;
1695+
--color-what-950: #f00;
1696+
}
1697+
1698+
@theme {
1699+
/*
1700+
* The value of this theme variable is > 50 chars because colors.what.50 was previously
1701+
* indexing the string: "light-dark(theme(colors.what.950), theme(colors.what.50))"
1702+
* because the resolved config contained an object with a "what" key that was that string
1703+
*/
1704+
--color-what: light-dark(theme(colors.what.950), theme(colors.what.50));
1705+
}
1706+
1707+
@source inline("text-what");
1708+
1709+
@tailwind utilities;
1710+
`)
1711+
1712+
expect(compiler.build([])).toMatchInlineSnapshot(`
1713+
":root, :host {
1714+
--color-what: light-dark(#f00, #f00);
1715+
}
1716+
.text-what {
1717+
color: var(--color-what);
1718+
}
1719+
"
1720+
`)
1721+
})

packages/tailwindcss/src/compat/plugin-functions.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,11 @@ function get(obj: any, path: string[]) {
233233
continue
234234
}
235235

236+
// We never want to index into strings
237+
if (typeof obj === 'string') {
238+
return undefined
239+
}
240+
236241
obj = obj[key]
237242
}
238243

0 commit comments

Comments
 (0)