Skip to content

Commit a198b52

Browse files
lucaswerkmeisterFloEdelmannwaynzhCopilot
authored
feat: Add ignorePattern to no-v-html (#2857)
Co-authored-by: Flo Edelmann <[email protected]> Co-authored-by: Wayne Zhang <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent 27d5c05 commit a198b52

File tree

6 files changed

+117
-5
lines changed

6 files changed

+117
-5
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)

docs/rules/no-v-html.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,42 @@ This rule reports all uses of `v-html` directive in order to reduce the risk of
3232

3333
## :wrench: Options
3434

35-
Nothing.
35+
```json
36+
{
37+
"vue/no-v-html": ["error", {
38+
"ignorePattern": "^html"
39+
}]
40+
}
41+
```
42+
43+
- `ignorePattern` ... disables reporting when the `v-html` directive references a variable matching this pattern. By default, all `v-html` uses are forbidden.
44+
45+
### `{ "ignorePattern": "^html" }`
46+
47+
<eslint-code-block :rules="{'vue/no-v-html': ['error', { 'ignorePattern': '^html' }]}">
48+
49+
```vue
50+
<template>
51+
<!-- ✓ GOOD -->
52+
<h2>{{ userName }}</h2>
53+
<span v-html="htmlUserLink" />
54+
55+
<!-- ✗ BAD -->
56+
<span v-html="userName" />
57+
</template>
58+
```
59+
60+
</eslint-code-block>
3661

3762
## :mute: When Not To Use It
3863

3964
If you are certain the content passed to `v-html` is sanitized HTML you can disable this rule.
4065

66+
## :couple: Related Rules
67+
68+
- [vue/no-v-text](./no-v-text.md)
69+
- [vue/no-v-text-v-html-on-component](./no-v-text-v-html-on-component.md)
70+
4171
## :rocket: Version
4272

4373
This rule was introduced in eslint-plugin-vue v4.7.0

docs/rules/no-v-text-v-html-on-component.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ If you use v-text / v-html on a component, it will overwrite the component's con
8484

8585
</eslint-code-block>
8686

87+
## :couple: Related Rules
88+
89+
- [vue/no-v-text](./no-v-text.md)
90+
- [vue/no-v-html](./no-v-html.md)
91+
8792
## :rocket: Version
8893

8994
This rule was introduced in eslint-plugin-vue v8.4.0

docs/rules/no-v-text.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ This rule reports all uses of `v-text` directive.
3232

3333
Nothing.
3434

35+
## :couple: Related Rules
36+
37+
- [vue/no-v-html](./no-v-html.md)
38+
- [vue/no-v-text-v-html-on-component](./no-v-text-v-html-on-component.md)
39+
3540
## :rocket: Version
3641

3742
This rule was introduced in eslint-plugin-vue v7.17.0

lib/rules/no-v-html.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,40 @@ module.exports = {
1414
url: 'https://eslint.vuejs.org/rules/no-v-html.html'
1515
},
1616
fixable: null,
17-
schema: [],
17+
schema: [
18+
{
19+
type: 'object',
20+
properties: {
21+
ignorePattern: {
22+
type: 'string'
23+
}
24+
},
25+
additionalProperties: false
26+
}
27+
],
1828
messages: {
1929
unexpected: "'v-html' directive can lead to XSS attack."
2030
}
2131
},
2232
/** @param {RuleContext} context */
2333
create(context) {
34+
const options = context.options[0]
35+
const ignoreRegEx = options?.ignorePattern
36+
? new RegExp(options.ignorePattern, 'u')
37+
: undefined
38+
2439
return utils.defineTemplateBodyVisitor(context, {
2540
/** @param {VDirective} node */
2641
"VAttribute[directive=true][key.name.name='html']"(node) {
42+
if (
43+
ignoreRegEx &&
44+
node.value &&
45+
node.value.expression &&
46+
node.value.expression.type === 'Identifier' &&
47+
ignoreRegEx.test(node.value.expression.name)
48+
) {
49+
return
50+
}
2751
context.report({
2852
node,
2953
loc: node.loc,

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

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,66 @@ 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="htmlKnownToBeSafe"></div></template>',
35+
options: [{ ignorePattern: '^html' }]
3136
}
3237
],
3338
invalid: [
3439
{
3540
filename: 'test.vue',
3641
code: '<template><div v-html="foo"></div></template>',
37-
errors: ["'v-html' directive can lead to XSS attack."]
42+
errors: [
43+
{
44+
message: "'v-html' directive can lead to XSS attack.",
45+
line: 1,
46+
column: 16,
47+
endLine: 1,
48+
endColumn: 28
49+
}
50+
]
3851
},
3952
{
4053
filename: 'test.vue',
4154
code: '<template><ul v-html:aaa="userHTML"></ul></template>',
42-
errors: ["'v-html' directive can lead to XSS attack."]
55+
errors: [
56+
{
57+
message: "'v-html' directive can lead to XSS attack.",
58+
line: 1,
59+
column: 15,
60+
endLine: 1,
61+
endColumn: 36
62+
}
63+
]
4364
},
4465
{
4566
filename: 'test.vue',
4667
code: '<template><section v-html/></template>',
47-
errors: ["'v-html' directive can lead to XSS attack."]
68+
errors: [
69+
{
70+
message: "'v-html' directive can lead to XSS attack.",
71+
line: 1,
72+
column: 20,
73+
endLine: 1,
74+
endColumn: 26
75+
}
76+
]
77+
},
78+
{
79+
filename: 'test.vue',
80+
code: '<template><div v-html="unsafeString"></div></template>',
81+
options: [{ ignorePattern: '^html' }],
82+
errors: [
83+
{
84+
message: "'v-html' directive can lead to XSS attack.",
85+
line: 1,
86+
column: 16,
87+
endLine: 1,
88+
endColumn: 37
89+
}
90+
]
4891
}
4992
]
5093
})

0 commit comments

Comments
 (0)