Escape quotes for html attributes
This commit is contained in:
parent
63c4a02ce0
commit
edc695263f
|
@ -69,3 +69,9 @@ export function escapeHTML (stringParam: string) {
|
||||||
|
|
||||||
return String(stringParam).replace(/[&<>"'`=/]/g, s => entityMap[s])
|
return String(stringParam).replace(/[&<>"'`=/]/g, s => entityMap[s])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function escapeAttribute (value: string) {
|
||||||
|
if (!value) return ''
|
||||||
|
|
||||||
|
return String(value).replace(/"/g, '\\"')
|
||||||
|
}
|
||||||
|
|
|
@ -265,6 +265,19 @@ describe('Test Open Graph and Twitter cards HTML tags', function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('Escaping', function () {
|
||||||
|
|
||||||
|
it('Should correctly escape values', async function () {
|
||||||
|
await servers[0].users.updateMe({ description: '<strong>"super description"</strong>' })
|
||||||
|
|
||||||
|
const res = await makeGetRequest({ url: servers[0].url, path: '/a/root', accept: 'text/html', expectedStatus: HttpStatusCode.OK_200 })
|
||||||
|
const text = res.text
|
||||||
|
|
||||||
|
expect(text).to.contain(`<meta property="twitter:description" content="\\"super description\\"" />`)
|
||||||
|
expect(text).to.contain(`<meta property="og:description" content="\\"super description\\"" />`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
after(async function () {
|
after(async function () {
|
||||||
await cleanupTests(servers)
|
await cleanupTests(servers)
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { escapeHTML } from '@peertube/peertube-core-utils'
|
import { escapeAttribute, escapeHTML } from '@peertube/peertube-core-utils'
|
||||||
import { CONFIG } from '../../../initializers/config.js'
|
import { CONFIG } from '../../../initializers/config.js'
|
||||||
import { CUSTOM_HTML_TAG_COMMENTS, EMBED_SIZE, WEBSERVER } from '../../../initializers/constants.js'
|
import { CUSTOM_HTML_TAG_COMMENTS, EMBED_SIZE, WEBSERVER } from '../../../initializers/constants.js'
|
||||||
import { MVideo, MVideoPlaylist } from '../../../types/models/index.js'
|
import { MVideo, MVideoPlaylist } from '../../../types/models/index.js'
|
||||||
|
@ -61,7 +61,7 @@ export class TagsHtml {
|
||||||
|
|
||||||
static addDescriptionTag (htmlStringPage: string, escapedTruncatedDescription?: string) {
|
static addDescriptionTag (htmlStringPage: string, escapedTruncatedDescription?: string) {
|
||||||
const content = escapedTruncatedDescription || escapeHTML(CONFIG.INSTANCE.SHORT_DESCRIPTION)
|
const content = escapedTruncatedDescription || escapeHTML(CONFIG.INSTANCE.SHORT_DESCRIPTION)
|
||||||
const descriptionTag = `<meta name="description" content="${content}" />`
|
const descriptionTag = `<meta name="description" content="${escapeAttribute(content)}" />`
|
||||||
|
|
||||||
return htmlStringPage.replace(CUSTOM_HTML_TAG_COMMENTS.DESCRIPTION, descriptionTag)
|
return htmlStringPage.replace(CUSTOM_HTML_TAG_COMMENTS.DESCRIPTION, descriptionTag)
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ export class TagsHtml {
|
||||||
const tagValue = openGraphMetaTags[tagName]
|
const tagValue = openGraphMetaTags[tagName]
|
||||||
if (!tagValue) return
|
if (!tagValue) return
|
||||||
|
|
||||||
tagsStr += `<meta property="${tagName}" content="${tagValue}" />`
|
tagsStr += `<meta property="${tagName}" content="${escapeAttribute(tagValue)}" />`
|
||||||
})
|
})
|
||||||
|
|
||||||
// Standard
|
// Standard
|
||||||
|
@ -101,7 +101,7 @@ export class TagsHtml {
|
||||||
const tagValue = standardMetaTags[tagName]
|
const tagValue = standardMetaTags[tagName]
|
||||||
if (!tagValue) return
|
if (!tagValue) return
|
||||||
|
|
||||||
tagsStr += `<meta property="${tagName}" content="${tagValue}" />`
|
tagsStr += `<meta property="${tagName}" content="${escapeAttribute(tagValue)}" />`
|
||||||
})
|
})
|
||||||
|
|
||||||
// Twitter card
|
// Twitter card
|
||||||
|
@ -109,12 +109,13 @@ export class TagsHtml {
|
||||||
const tagValue = twitterCardMetaTags[tagName]
|
const tagValue = twitterCardMetaTags[tagName]
|
||||||
if (!tagValue) return
|
if (!tagValue) return
|
||||||
|
|
||||||
tagsStr += `<meta property="${tagName}" content="${tagValue}" />`
|
tagsStr += `<meta property="${tagName}" content="${escapeAttribute(tagValue)}" />`
|
||||||
})
|
})
|
||||||
|
|
||||||
// OEmbed
|
// OEmbed
|
||||||
for (const oembedLinkTag of oembedLinkTags) {
|
for (const oembedLinkTag of oembedLinkTags) {
|
||||||
tagsStr += `<link rel="alternate" type="${oembedLinkTag.type}" href="${oembedLinkTag.href}" title="${oembedLinkTag.escapedTitle}" />`
|
// eslint-disable-next-line max-len
|
||||||
|
tagsStr += `<link rel="alternate" type="${oembedLinkTag.type}" href="${oembedLinkTag.href}" title="${escapeAttribute(oembedLinkTag.escapedTitle)}" />`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schema.org
|
// Schema.org
|
||||||
|
|
Loading…
Reference in New Issue