Skip to content

Commit 7ca7c4c

Browse files
Add support for regexes to allow property values
Closes Gh-26. Reviewed-by: Titus Wormer <[email protected]>
1 parent ee07ff2 commit 7ca7c4c

File tree

3 files changed

+41
-10
lines changed

3 files changed

+41
-10
lines changed

Diff for: lib/index.js

+14-8
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
* Possible property values
1010
* @typedef {string|number|boolean} PrimitivePropertyValue
1111
* Possible primitive HTML attribute values
12-
* @typedef {string|[string, ...Array<PrimitivePropertyValue>]} AttributeValue
13-
* @typedef {Record<string, Array<PrimitivePropertyValue>>} AttributeMap
12+
* @typedef {string|[string, ...Array<PrimitivePropertyValue|RegExp>]} AttributeValue
13+
* @typedef {Record<string, Array<PrimitivePropertyValue|RegExp>>} AttributeMap
1414
*
1515
* @typedef Schema Sanitization configuration
1616
* @property {Record<string, Array<AttributeValue>>} [attributes]
@@ -236,7 +236,7 @@ function handleProperties(schema, properties, node, stack) {
236236
for (key in props) {
237237
if (own.call(props, key)) {
238238
let value = props[key]
239-
/** @type {Array<PrimitivePropertyValue>} */
239+
/** @type {Array<PrimitivePropertyValue|RegExp>} */
240240
let definition
241241

242242
if (own.call(allowed, key)) {
@@ -281,9 +281,10 @@ function handleDoctypeName() {
281281
/**
282282
* Sanitize `tagName`.
283283
*
284-
* @type {Handler}
285-
* @param {unknown} tagName
284+
* @param {Schema} schema
285+
* @param {string} tagName
286286
* @param {Node} _
287+
* @param {Array<string>} stack
287288
* @returns {string|false}
288289
*/
289290
function handleTagName(schema, tagName, _, stack) {
@@ -354,7 +355,7 @@ function allow(_, value) {
354355
* @param {Schema} schema
355356
* @param {Array<unknown>} values
356357
* @param {string} prop
357-
* @param {Array<PrimitivePropertyValue>} definition
358+
* @param {Array<PrimitivePropertyValue|RegExp>} definition
358359
* @returns {Array<string|number>}
359360
*/
360361
function handlePropertyValues(schema, values, prop, definition) {
@@ -380,7 +381,7 @@ function handlePropertyValues(schema, values, prop, definition) {
380381
* @param {Schema} schema
381382
* @param {unknown} value
382383
* @param {string} prop
383-
* @param {Array<PropertyValue>} definition
384+
* @param {Array<PropertyValue|RegExp>} definition
384385
* @returns {PropertyValue}
385386
*/
386387
function handlePropertyValue(schema, value, prop, definition) {
@@ -389,7 +390,12 @@ function handlePropertyValue(schema, value, prop, definition) {
389390
typeof value === 'number' ||
390391
typeof value === 'string') &&
391392
safeProtocol(schema, value, prop) &&
392-
(definition.length === 0 || definition.includes(value))
393+
(definition.length === 0 ||
394+
definition.some((allowed) =>
395+
allowed && typeof allowed === 'object' && 'flags' in allowed
396+
? allowed.test(String(value))
397+
: allowed === value
398+
))
393399
) {
394400
return schema.clobberPrefix &&
395401
schema.clobber &&

Diff for: readme.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,9 @@ attributes: {
192192

193193
Instead of a single string (such as `type`), which allows any [*property
194194
value*][value] of that [*property name*][name], it’s also possible to provide
195-
an array (such as `['type', 'checkbox']`), where the first entry is the
196-
*property name*, and all other entries allowed *property values*.
195+
an array (such as `['type', 'checkbox']` or `['className', /^hljs-/]`),
196+
where the first entry is the *property name*, and all other entries are
197+
*property values* allowed (or regular expressions that are tested with values).
197198
This is how the default GitHub schema allows only disabled checkbox inputs:
198199

199200
```js

Diff for: test.js

+24
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,30 @@ test('sanitize()', (t) => {
610610
'should support a list of valid values on new attributes'
611611
)
612612

613+
t.deepEqual(
614+
sanitize(
615+
h('div', [
616+
h('span', {className: 'a-one'}),
617+
h('span', {className: 'a-two'}),
618+
h('span', {className: 'b-one'}),
619+
h('span', {className: 'b-two'}),
620+
h('span', {className: 'a-one a-two b-one b-two'})
621+
]),
622+
deepmerge(defaultSchema, {
623+
tagNames: ['span'],
624+
attributes: {span: [['className', /^a-/, 'b-one']]}
625+
})
626+
),
627+
h('div', [
628+
h('span', {className: 'a-one'}),
629+
h('span', {className: 'a-two'}),
630+
h('span', {className: 'b-one'}),
631+
h('span', {className: []}),
632+
h('span', {className: 'a-one a-two b-one'})
633+
]),
634+
'should support RegExp in the list of valid values'
635+
)
636+
613637
t.deepEqual(
614638
sanitize(
615639
h('div', [

0 commit comments

Comments
 (0)