mirror of
https://github.com/tenrok/vue-meta.git
synced 2026-06-23 00:40:35 +03:00
test: add missing test for sanitizeByTagId
fix: broken sanitizeByTagId implementation
This commit is contained in:
committed by
Alexander Lichter
parent
da4bb27a4b
commit
ce7eaf56d3
+12
-9
@@ -3,7 +3,9 @@ import isArray from './isArray'
|
|||||||
import { isString, isObject } from './typeof'
|
import { isString, isObject } from './typeof'
|
||||||
|
|
||||||
// sanitizes potentially dangerous characters
|
// sanitizes potentially dangerous characters
|
||||||
export default function escape(info, { tagIDKeyName }, escapeSequences = []) {
|
export default function escape(info, options, escapeOptions) {
|
||||||
|
const { tagIDKeyName } = options
|
||||||
|
const { doEscape = v => v } = escapeOptions
|
||||||
const escaped = {}
|
const escaped = {}
|
||||||
|
|
||||||
for (const key in info) {
|
for (const key in info) {
|
||||||
@@ -16,32 +18,33 @@ export default function escape(info, { tagIDKeyName }, escapeSequences = []) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let [ disableKey ] = disableOptionKeys
|
let [ disableKey ] = disableOptionKeys
|
||||||
if (info[disableKey] && info[disableKey].includes(key)) {
|
if (escapeOptions[disableKey] && escapeOptions[disableKey].includes(key)) {
|
||||||
// this info[key] doesnt need to escaped if the option is listed in __dangerouslyDisableSanitizers
|
// this info[key] doesnt need to escaped if the option is listed in __dangerouslyDisableSanitizers
|
||||||
escaped[key] = value
|
escaped[key] = value
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info[tagIDKeyName]) {
|
const tagId = info[tagIDKeyName]
|
||||||
|
if (tagId) {
|
||||||
disableKey = disableOptionKeys[1]
|
disableKey = disableOptionKeys[1]
|
||||||
|
|
||||||
// items which vmid is listed in __dangerouslyDisableSanitizersByTagID do not need to be escaped
|
// keys which are listed in __dangerouslyDisableSanitizersByTagID for the current vmid do not need to be escaped
|
||||||
if (info[disableKey] && info[disableKey][key] && info[disableKey][key].includes(info[tagIDKeyName])) {
|
if (escapeOptions[disableKey] && escapeOptions[disableKey][tagId] && escapeOptions[disableKey][tagId].includes(key)) {
|
||||||
escaped[key] = value
|
escaped[key] = value
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isString(value)) {
|
if (isString(value)) {
|
||||||
escaped[key] = escapeSequences.reduce((val, [v, r]) => val.replace(v, r), value)
|
escaped[key] = doEscape(value)
|
||||||
} else if (isArray(value)) {
|
} else if (isArray(value)) {
|
||||||
escaped[key] = value.map((v) => {
|
escaped[key] = value.map((v) => {
|
||||||
return isObject(v)
|
return isObject(v)
|
||||||
? escape(v, { tagIDKeyName }, escapeSequences)
|
? escape(v, options, escapeOptions)
|
||||||
: escapeSequences.reduce((val, [v, r]) => val.replace(v, r), v)
|
: doEscape(v)
|
||||||
})
|
})
|
||||||
} else if (isObject(value)) {
|
} else if (isObject(value)) {
|
||||||
escaped[key] = escape(value, { tagIDKeyName }, escapeSequences)
|
escaped[key] = escape(value, options, escapeOptions)
|
||||||
} else {
|
} else {
|
||||||
escaped[key] = value
|
escaped[key] = value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,21 +33,28 @@ export default function getMetaInfo(options = {}, component, escapeSequences = [
|
|||||||
info.base = Object.keys(info.base).length ? [info.base] : []
|
info.base = Object.keys(info.base).length ? [info.base] : []
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const index in disableOptionKeys) {
|
const escapeOptions = {
|
||||||
const disableKey = disableOptionKeys[index]
|
doEscape: value => escapeSequences.reduce((val, [v, r]) => val.replace(v, r), value)
|
||||||
|
}
|
||||||
|
|
||||||
|
disableOptionKeys.forEach((disableKey, index) => {
|
||||||
if (!info[disableKey]) {
|
if (!info[disableKey]) {
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
ensureIsArray(info, disableKey)
|
ensureIsArray(info, disableKey)
|
||||||
} else if (index === 1) {
|
} else if (index === 1) {
|
||||||
info[disableKey].forEach(key => ensureIsArray(info[disableKey], key))
|
for (const key in info[disableKey]) {
|
||||||
|
ensureIsArray(info[disableKey], key)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
escapeOptions[disableKey] = info[disableKey]
|
||||||
|
})
|
||||||
|
|
||||||
// begin sanitization
|
// begin sanitization
|
||||||
info = escape(info, options, escapeSequences)
|
info = escape(info, options, escapeOptions)
|
||||||
|
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,4 +34,37 @@ describe('escaping', () => {
|
|||||||
__dangerouslyDisableSanitizersByTagID: {}
|
__dangerouslyDisableSanitizersByTagID: {}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('special chars are escaped unless disabled by vmid', () => {
|
||||||
|
const component = new Vue({
|
||||||
|
metaInfo: {
|
||||||
|
title: 'Hello',
|
||||||
|
script: [
|
||||||
|
{ vmid: 'yescape', innerHTML: 'Hello & Goodbye' },
|
||||||
|
{ vmid: 'noscape', innerHTML: 'Hello & Goodbye' }
|
||||||
|
],
|
||||||
|
__dangerouslyDisableSanitizersByTagID: { noscape: ['innerHTML'] }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(getMetaInfo(component, [[/&/g, '&']])).toEqual({
|
||||||
|
title: 'Hello',
|
||||||
|
titleChunk: 'Hello',
|
||||||
|
titleTemplate: '%s',
|
||||||
|
htmlAttrs: {},
|
||||||
|
headAttrs: {},
|
||||||
|
bodyAttrs: {},
|
||||||
|
meta: [],
|
||||||
|
base: [],
|
||||||
|
link: [],
|
||||||
|
style: [],
|
||||||
|
script: [
|
||||||
|
{ innerHTML: 'Hello & Goodbye', vmid: 'yescape' },
|
||||||
|
{ innerHTML: 'Hello & Goodbye', vmid: 'noscape' }
|
||||||
|
],
|
||||||
|
noscript: [],
|
||||||
|
__dangerouslyDisableSanitizers: [],
|
||||||
|
__dangerouslyDisableSanitizersByTagID: { noscape: ['innerHTML'] }
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user