Disallow multi-selector arbitrary variants (#10655)
* Allow escaping in `splitAtTopLevelOnly` * Correctly parse arbitrary variants that have multiple selectors * Explicitly disallow multiple selector arbitrary variants Now that we parse them correctly we can restrict them to explicitly supporting only a single selector * Add test to verify that multiple selector arbitrary variants are dropped * Add test * Make prettier happy * Fix CS * Update changelog
This commit is contained in:
parent
d6121f0ede
commit
9bbdd9b10d
4 changed files with 73 additions and 6 deletions
|
|
@ -205,17 +205,26 @@ function applyVariant(variant, matches, context) {
|
|||
|
||||
// Register arbitrary variants
|
||||
if (isArbitraryValue(variant) && !context.variantMap.has(variant)) {
|
||||
let selector = normalize(variant.slice(1, -1))
|
||||
let sort = context.offsets.recordVariant(variant)
|
||||
|
||||
if (!isValidVariantFormatString(selector)) {
|
||||
let selector = normalize(variant.slice(1, -1))
|
||||
let selectors = splitAtTopLevelOnly(selector, ',')
|
||||
|
||||
// We do not support multiple selectors for arbitrary variants
|
||||
if (selectors.length > 1) {
|
||||
return []
|
||||
}
|
||||
|
||||
let fn = parseVariant(selector)
|
||||
if (!selectors.every(isValidVariantFormatString)) {
|
||||
return []
|
||||
}
|
||||
|
||||
let sort = context.offsets.recordVariant(variant)
|
||||
let records = selectors.map((sel, idx) => [
|
||||
context.offsets.applyParallelOffset(sort, idx),
|
||||
parseVariant(sel.trim()),
|
||||
])
|
||||
|
||||
context.variantMap.set(variant, [[sort, fn]])
|
||||
context.variantMap.set(variant, records)
|
||||
}
|
||||
|
||||
if (context.variantMap.has(variant)) {
|
||||
|
|
|
|||
|
|
@ -17,17 +17,24 @@ export function splitAtTopLevelOnly(input, separator) {
|
|||
let stack = []
|
||||
let parts = []
|
||||
let lastPos = 0
|
||||
let isEscaped = false
|
||||
|
||||
for (let idx = 0; idx < input.length; idx++) {
|
||||
let char = input[idx]
|
||||
|
||||
if (stack.length === 0 && char === separator[0]) {
|
||||
if (stack.length === 0 && char === separator[0] && !isEscaped) {
|
||||
if (separator.length === 1 || input.slice(idx, idx + separator.length) === separator) {
|
||||
parts.push(input.slice(lastPos, idx))
|
||||
lastPos = idx + separator.length
|
||||
}
|
||||
}
|
||||
|
||||
if (isEscaped) {
|
||||
isEscaped = false
|
||||
} else if (char === '\\') {
|
||||
isEscaped = true
|
||||
}
|
||||
|
||||
if (char === '(' || char === '[' || char === '{') {
|
||||
stack.push(char)
|
||||
} else if (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue