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:
committed by
Alexander Lichter
parent
da4bb27a4b
commit
ce7eaf56d3
+12
-9
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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'] }
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user