Ensure arbitrary values only support valid values (#5293)
* ensure arbitrary values only support valid values
* ensure we validate balancing [], () and {}
This commit is contained in:
parent
048a29ef34
commit
fa3d454d06
3 changed files with 112 additions and 0 deletions
|
|
@ -125,6 +125,64 @@ function withIdentifiers(styles) {
|
|||
})
|
||||
}
|
||||
|
||||
let matchingBrackets = new Map([
|
||||
['{', '}'],
|
||||
['[', ']'],
|
||||
['(', ')'],
|
||||
])
|
||||
let inverseMatchingBrackets = new Map(
|
||||
Array.from(matchingBrackets.entries()).map(([k, v]) => [v, k])
|
||||
)
|
||||
|
||||
let quotes = new Set(['"', "'", '`'])
|
||||
|
||||
// Arbitrary values must contain balanced brackets (), [] and {}. Escaped
|
||||
// values don't count, and brackets inside quotes also don't count.
|
||||
//
|
||||
// E.g.: w-[this-is]w-[weird-and-invalid]
|
||||
// E.g.: w-[this-is\\]w-\\[weird-but-valid]
|
||||
// E.g.: content-['this-is-also-valid]-weirdly-enough']
|
||||
function isValidArbitraryValue(value) {
|
||||
let stack = []
|
||||
let inQuotes = false
|
||||
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
let char = value[i]
|
||||
|
||||
// Non-escaped quotes allow us to "allow" anything in between
|
||||
if (quotes.has(char) && value[i - 1] !== '\\') {
|
||||
inQuotes = !inQuotes
|
||||
}
|
||||
|
||||
if (inQuotes) continue
|
||||
if (value[i - 1] === '\\') continue // Escaped
|
||||
|
||||
if (matchingBrackets.has(char)) {
|
||||
stack.push(char)
|
||||
} else if (inverseMatchingBrackets.has(char)) {
|
||||
let inverse = inverseMatchingBrackets.get(char)
|
||||
|
||||
// Nothing to pop from, therefore it is unbalanced
|
||||
if (stack.length <= 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Popped value must match the inverse value, otherwise it is unbalanced
|
||||
if (stack.pop() !== inverse) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there is still something on the stack, it is also unbalanced
|
||||
if (stack.length > 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
// All good, totally balanced!
|
||||
return true
|
||||
}
|
||||
|
||||
function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offsets }) {
|
||||
function getConfigValue(path, defaultValue) {
|
||||
return path ? dlv(tailwindConfig, path, defaultValue) : tailwindConfig
|
||||
|
|
@ -273,6 +331,10 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
|||
return []
|
||||
}
|
||||
|
||||
if (!isValidArbitraryValue(value)) {
|
||||
return []
|
||||
}
|
||||
|
||||
let includedRules = []
|
||||
let ruleSets = []
|
||||
.concat(
|
||||
|
|
|
|||
|
|
@ -93,6 +93,28 @@
|
|||
.w-\[calc\(100\%\/3-1rem\*2\)\] {
|
||||
width: calc(100% / 3 - 1rem * 2);
|
||||
}
|
||||
.w-\[\{\}\] {
|
||||
width: {
|
||||
}
|
||||
}
|
||||
.w-\[\{\{\}\}\] {
|
||||
width: {
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
.w-\[\(\)\] {
|
||||
width: ();
|
||||
}
|
||||
.w-\[\(\(\)\)\] {
|
||||
width: (());
|
||||
}
|
||||
.w-\[\'\)\(\)\'\] {
|
||||
width: ')()';
|
||||
}
|
||||
.w-\[\'\}\{\}\'\] {
|
||||
width: '}{}';
|
||||
}
|
||||
.min-w-\[3\.23rem\] {
|
||||
min-width: 3.23rem;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,5 +116,33 @@
|
|||
<div class="delay-[var(--delay)]"></div>
|
||||
<div class="content-['hello']"></div>
|
||||
<div class="content-[attr(content-before)]"></div>
|
||||
|
||||
<!-- Balancing issues, this is not checking the validity of the actual value, but purely syntax-wise -->
|
||||
<div class="w-[do-not-generate-this]w-[it-is-invalid-syntax]"></div><!-- INVALID -->
|
||||
<div class="grid-cols-[[linename],1fr,auto]"></div><!-- VALID -->
|
||||
<div class="w-[{}]"></div><!-- VALID -->
|
||||
<div class="w-[{{}}]"></div><!-- VALID -->
|
||||
<div class="w-[[]]"></div><!-- VALID -->
|
||||
<div class="w-[[[]]]"></div><!-- VALID -->
|
||||
<div class="w-[()]"></div><!-- VALID -->
|
||||
<div class="w-[(())]"></div><!-- VALID -->
|
||||
<div class="w-[][]"></div><!-- INVALID -->
|
||||
<div class="w-[)(]"></div><!-- INVALID -->
|
||||
<div class="w-[}{]"></div><!-- INVALID -->
|
||||
<div class="w-[][]]"></div><!-- INVALID -->
|
||||
<div class="w-[)()]"></div><!-- INVALID -->
|
||||
<div class="w-[}{}]"></div><!-- INVALID -->
|
||||
<div class="w-['][]']"></div><!-- VALID -->
|
||||
<div class="w-[')()']"></div><!-- VALID -->
|
||||
<div class="w-['}{}']"></div><!-- VALID -->
|
||||
<div class="w-[[']']]"></div><!-- VALID -->
|
||||
<div class="w-[(')')]"></div><!-- VALID -->
|
||||
<div class="w-[{'}'}]"></div><!-- VALID -->
|
||||
<div class="w-[{[}]]"></div><!-- INVALID -->
|
||||
<div class="w-[[{]}]"></div><!-- INVALID -->
|
||||
<div class="w-[{(})]"></div><!-- INVALID -->
|
||||
<div class="w-[({)}]"></div><!-- INVALID -->
|
||||
<div class="w-[([)]]"></div><!-- INVALID -->
|
||||
<div class="w-[[(])]"></div><!-- INVALID -->
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue