Skip to content

Commit c98c01e

Browse files
feat: Add ignorePattern to no-v-html
This allows configuring the rule such that certain variables are allowed in v-html=. For instance, we would like to allowlist variables named “*Html” (as in the test), where the name already marks them as containing safe HTML that’s expected to be used with v-html=.
1 parent 6f1fae3 commit c98c01e

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

.changeset/purple-lights-invite.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'eslint-plugin-vue': minor
3+
---
4+
5+
Added `ignorePattern` option to [`vue/no-v-html`](https://eslint.vuejs.org/rules/no-v-html.html)

lib/rules/no-v-html.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55
'use strict'
66
const utils = require('../utils')
7+
const { toRegExp } = require('../utils/regexp')
78

89
module.exports = {
910
meta: {
@@ -14,16 +15,32 @@ module.exports = {
1415
url: 'https://eslint.vuejs.org/rules/no-v-html.html'
1516
},
1617
fixable: null,
17-
schema: [],
18+
schema: [{
19+
type: 'object',
20+
properties: {
21+
ignorePattern: {
22+
type: 'string'
23+
}
24+
}
25+
}],
1826
messages: {
1927
unexpected: "'v-html' directive can lead to XSS attack."
2028
}
2129
},
2230
/** @param {RuleContext} context */
2331
create(context) {
32+
const options = context.options[0]
33+
let ignoredVarMatcher = null
34+
if (options?.ignorePattern) {
35+
ignoredVarMatcher = toRegExp(options.ignorePattern, { remove: 'g' })
36+
}
37+
2438
return utils.defineTemplateBodyVisitor(context, {
2539
/** @param {VDirective} node */
2640
"VAttribute[directive=true][key.name.name='html']"(node) {
41+
if (ignoredVarMatcher !== null && node.value.expression.type === 'Identifier' && ignoredVarMatcher.test(node.value.expression.name)) {
42+
return
43+
}
2744
context.report({
2845
node,
2946
loc: node.loc,

tests/lib/rules/no-v-html.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ ruleTester.run('no-v-html', rule, {
2828
{
2929
filename: 'test.vue',
3030
code: '<template><div v-if="foo" v-bind="bar"></div></template>'
31+
},
32+
{
33+
filename: 'test.vue',
34+
code: '<template><div v-html="knownHtml"></div></template>',
35+
options: [{ignorePattern: '/^(?:html|.+Html)$/'}]
3136
}
3237
],
3338
invalid: [
@@ -45,6 +50,12 @@ ruleTester.run('no-v-html', rule, {
4550
filename: 'test.vue',
4651
code: '<template><section v-html/></template>',
4752
errors: ["'v-html' directive can lead to XSS attack."]
53+
},
54+
{
55+
filename: 'test.vue',
56+
code: '<template><div v-html="unsafeString"></div></template>',
57+
options: [{ignorePattern: '^(?:html|.+Html)$'}],
58+
errors: ["'v-html' directive can lead to XSS attack."]
4859
}
4960
]
5061
})

0 commit comments

Comments
 (0)