Reject invalid custom and arbitrary variants (#8345)

* WIP

Still need to write error message

* Update error message

first pass at something better

* Detect invalid variant formats returned by functions

* Add proper error message

Co-authored-by: Jordan Pittman <jordan@cryptica.me>
This commit is contained in:
Adam Wathan 2022-05-14 13:58:02 -04:00 • committed by GitHub
parent e41bf3d2a7
commit 7fa2a200b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 90 additions and 2 deletions

View file

@ -9,7 +9,7 @@ import * as sharedState from './sharedState'
import { formatVariantSelector, finalizeSelector } from '../util/formatVariantSelector'
import { asClass } from '../util/nameClass'
import { normalize } from '../util/dataTypes'
import { parseVariant } from './setupContextUtils'
import { isValidVariantFormatString, parseVariant } from './setupContextUtils'
import isValidArbitraryValue from '../util/isValidArbitraryValue'
import { splitAtTopLevelOnly } from '../util/splitAtTopLevelOnly.js'
@ -131,6 +131,10 @@ function applyVariant(variant, matches, context) {
if (isArbitraryValue(variant) && !context.variantMap.has(variant)) {
let selector = normalize(variant.slice(1, -1))
if (!isValidVariantFormatString(selector)) {
return []
}
let fn = parseVariant(selector)
let sort = Array.from(context.variantOrder.values()).pop() << 1n

View file

@ -170,6 +170,10 @@ function withIdentifiers(styles) {
})
}
export function isValidVariantFormatString(format) {
return format.startsWith('@') || format.includes('&')
}
export function parseVariant(variant) {
variant = variant
.replace(/\n+/g, '')
@ -221,10 +225,24 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
if (typeof variantFunction !== 'string') {
// Safelist public API functions
return ({ modifySelectors, container, separator }) => {
return variantFunction({ modifySelectors, container, separator })
let result = variantFunction({ modifySelectors, container, separator })
if (typeof result === 'string' && !isValidVariantFormatString(result)) {
throw new Error(
`Your custom variant \`${variantName}\` has an invalid format string. Make sure it's an at-rule or contains a \`&\` placeholder.`
)
}
return result
}
}
if (!isValidVariantFormatString(variantFunction)) {
throw new Error(
`Your custom variant \`${variantName}\` has an invalid format string. Make sure it's an at-rule or contains a \`&\` placeholder.`
)
}
return parseVariant(variantFunction)
})