2
0
mirror of https://github.com/tenrok/vue-meta.git synced 2026-06-06 02:12:25 +03:00

test: add missing test for sanitizeByTagId

fix: broken sanitizeByTagId implementation
This commit is contained in:
pimlie
2019-03-08 18:53:13 +01:00
committed by Alexander Lichter
parent da4bb27a4b
commit ce7eaf56d3
3 changed files with 58 additions and 15 deletions
+12 -9
View File
@@ -3,7 +3,9 @@ import isArray from './isArray'
import { isString, isObject } from './typeof'
// 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 = {}
for (const key in info) {
@@ -16,32 +18,33 @@ export default function escape(info, { tagIDKeyName }, escapeSequences = []) {
}
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
escaped[key] = value
continue
}
if (info[tagIDKeyName]) {
const tagId = info[tagIDKeyName]
if (tagId) {
disableKey = disableOptionKeys[1]
// items which vmid is listed in __dangerouslyDisableSanitizersByTagID do not need to be escaped
if (info[disableKey] && info[disableKey][key] && info[disableKey][key].includes(info[tagIDKeyName])) {
// keys which are listed in __dangerouslyDisableSanitizersByTagID for the current vmid do not need to be escaped
if (escapeOptions[disableKey] && escapeOptions[disableKey][tagId] && escapeOptions[disableKey][tagId].includes(key)) {
escaped[key] = value
continue
}
}
if (isString(value)) {
escaped[key] = escapeSequences.reduce((val, [v, r]) => val.replace(v, r), value)
escaped[key] = doEscape(value)
} else if (isArray(value)) {
escaped[key] = value.map((v) => {
return isObject(v)
? escape(v, { tagIDKeyName }, escapeSequences)
: escapeSequences.reduce((val, [v, r]) => val.replace(v, r), v)
? escape(v, options, escapeOptions)
: doEscape(v)
})
} else if (isObject(value)) {
escaped[key] = escape(value, { tagIDKeyName }, escapeSequences)
escaped[key] = escape(value, options, escapeOptions)
} else {
escaped[key] = value
}
+13 -6
View File
@@ -33,21 +33,28 @@ export default function getMetaInfo(options = {}, component, escapeSequences = [
info.base = Object.keys(info.base).length ? [info.base] : []
}
for (const index in disableOptionKeys) {
const disableKey = disableOptionKeys[index]
const escapeOptions = {
doEscape: value => escapeSequences.reduce((val, [v, r]) => val.replace(v, r), value)
}
disableOptionKeys.forEach((disableKey, index) => {
if (!info[disableKey]) {
continue
return
}
if (index === 0) {
ensureIsArray(info, disableKey)
} 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
info = escape(info, options, escapeSequences)
info = escape(info, options, escapeOptions)
return info
}
+33
View File
@@ -34,4 +34,37 @@ describe('escaping', () => {
__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'] }
})
})
})