diff --git a/.changeset/purple-lights-invite.md b/.changeset/purple-lights-invite.md new file mode 100644 index 000000000..80aa90b8d --- /dev/null +++ b/.changeset/purple-lights-invite.md @@ -0,0 +1,5 @@ +--- +'eslint-plugin-vue': minor +--- + +Added `ignorePattern` option to [`vue/no-v-html`](https://eslint.vuejs.org/rules/no-v-html.html) diff --git a/docs/rules/no-v-html.md b/docs/rules/no-v-html.md index 3098683e0..507eaf9b4 100644 --- a/docs/rules/no-v-html.md +++ b/docs/rules/no-v-html.md @@ -32,12 +32,42 @@ This rule reports all uses of `v-html` directive in order to reduce the risk of ## :wrench: Options -Nothing. +```json +{ + "vue/no-v-html": ["error", { + "ignorePattern": "^html" + }] +} +``` + +- `ignorePattern` ... disables reporting when the `v-html` directive references a variable matching this pattern. By default, all `v-html` uses are forbidden. + +### `{ "ignorePattern": "^html" }` + + + +```vue + +``` + + ## :mute: When Not To Use It If you are certain the content passed to `v-html` is sanitized HTML you can disable this rule. +## :couple: Related Rules + +- [vue/no-v-text](./no-v-text.md) +- [vue/no-v-text-v-html-on-component](./no-v-text-v-html-on-component.md) + ## :rocket: Version This rule was introduced in eslint-plugin-vue v4.7.0 diff --git a/docs/rules/no-v-text-v-html-on-component.md b/docs/rules/no-v-text-v-html-on-component.md index 9bbbcf7ab..aa1aceff6 100644 --- a/docs/rules/no-v-text-v-html-on-component.md +++ b/docs/rules/no-v-text-v-html-on-component.md @@ -84,6 +84,11 @@ If you use v-text / v-html on a component, it will overwrite the component's con +## :couple: Related Rules + +- [vue/no-v-text](./no-v-text.md) +- [vue/no-v-html](./no-v-html.md) + ## :rocket: Version This rule was introduced in eslint-plugin-vue v8.4.0 diff --git a/docs/rules/no-v-text.md b/docs/rules/no-v-text.md index 89bedbfbb..3fcd6811b 100644 --- a/docs/rules/no-v-text.md +++ b/docs/rules/no-v-text.md @@ -32,6 +32,11 @@ This rule reports all uses of `v-text` directive. Nothing. +## :couple: Related Rules + +- [vue/no-v-html](./no-v-html.md) +- [vue/no-v-text-v-html-on-component](./no-v-text-v-html-on-component.md) + ## :rocket: Version This rule was introduced in eslint-plugin-vue v7.17.0 diff --git a/lib/rules/no-v-html.js b/lib/rules/no-v-html.js index 355e86b21..512cf4c71 100644 --- a/lib/rules/no-v-html.js +++ b/lib/rules/no-v-html.js @@ -14,16 +14,40 @@ module.exports = { url: 'https://eslint.vuejs.org/rules/no-v-html.html' }, fixable: null, - schema: [], + schema: [ + { + type: 'object', + properties: { + ignorePattern: { + type: 'string' + } + }, + additionalProperties: false + } + ], messages: { unexpected: "'v-html' directive can lead to XSS attack." } }, /** @param {RuleContext} context */ create(context) { + const options = context.options[0] + const ignoreRegEx = options?.ignorePattern + ? new RegExp(options.ignorePattern, 'u') + : undefined + return utils.defineTemplateBodyVisitor(context, { /** @param {VDirective} node */ "VAttribute[directive=true][key.name.name='html']"(node) { + if ( + ignoreRegEx && + node.value && + node.value.expression && + node.value.expression.type === 'Identifier' && + ignoreRegEx.test(node.value.expression.name) + ) { + return + } context.report({ node, loc: node.loc, diff --git a/tests/lib/rules/no-v-html.js b/tests/lib/rules/no-v-html.js index d9ae67ca1..44d3a79c5 100644 --- a/tests/lib/rules/no-v-html.js +++ b/tests/lib/rules/no-v-html.js @@ -28,23 +28,66 @@ ruleTester.run('no-v-html', rule, { { filename: 'test.vue', code: '' + }, + { + filename: 'test.vue', + code: '', + options: [{ ignorePattern: '^html' }] } ], invalid: [ { filename: 'test.vue', code: '', - errors: ["'v-html' directive can lead to XSS attack."] + errors: [ + { + message: "'v-html' directive can lead to XSS attack.", + line: 1, + column: 16, + endLine: 1, + endColumn: 28 + } + ] }, { filename: 'test.vue', code: '', - errors: ["'v-html' directive can lead to XSS attack."] + errors: [ + { + message: "'v-html' directive can lead to XSS attack.", + line: 1, + column: 15, + endLine: 1, + endColumn: 36 + } + ] }, { filename: 'test.vue', code: '', - errors: ["'v-html' directive can lead to XSS attack."] + errors: [ + { + message: "'v-html' directive can lead to XSS attack.", + line: 1, + column: 20, + endLine: 1, + endColumn: 26 + } + ] + }, + { + filename: 'test.vue', + code: '', + options: [{ ignorePattern: '^html' }], + errors: [ + { + message: "'v-html' directive can lead to XSS attack.", + line: 1, + column: 16, + endLine: 1, + endColumn: 37 + } + ] } ] })