From c435347695827612952c8cf475f470c5027598dd Mon Sep 17 00:00:00 2001 From: Sergei Startsev Date: Sat, 30 Nov 2019 02:36:02 +0300 Subject: [PATCH] [New] `jsx-no-script-url`: minor adjustments --- lib/rules/jsx-no-script-url.js | 59 ++++++++++++++-------------- tests/lib/rules/jsx-no-script-url.js | 2 +- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/lib/rules/jsx-no-script-url.js b/lib/rules/jsx-no-script-url.js index 0bbce3d8cc..63cf7dd023 100644 --- a/lib/rules/jsx-no-script-url.js +++ b/lib/rules/jsx-no-script-url.js @@ -20,6 +20,28 @@ function hasJavaScriptProtocol(attr) { isJavaScriptProtocol.test(attr.value.value); } +function shouldVerifyElement(node, config) { + const name = node.name && node.name.name; + return name === 'a' || config.find(i => i.name === name); +} + +function shouldVerifyProp(node, config) { + const name = node.name && node.name.name; + const parentName = node.parent.name && node.parent.name.name; + + if (parentName === 'a' && name === 'href') { + return true; + } + + const el = config.find(i => i.name === parentName); + if (!el) { + return false; + } + + const props = el.props || []; + return node.name && props.indexOf(name) !== -1; +} + module.exports = { meta: { docs: { @@ -30,6 +52,7 @@ module.exports = { }, schema: [{ type: 'array', + uniqueItems: true, items: { type: 'object', properties: { @@ -51,38 +74,16 @@ module.exports = { }, create(context) { - const configuration = context.options[0] || []; - const elements = configuration.map(i => i.name); - - function shouldVerifyElement(node) { - const name = node.name && node.name.name; - return name === 'a' || elements.indexOf(name) !== -1; - } - - function shouldVerifyProp(node) { - const name = node.name && node.name.name; - const parentName = node.parent.name && node.parent.name.name; - - if (parentName === 'a' && name === 'href') { - return true; - } - - if (elements.indexOf(parentName) === -1) { - return false; - } - - const el = configuration.find(i => i.name === parentName); - const props = el && el.props || []; - - return node.name && props.indexOf(name) !== -1; - } - + const config = context.options[0] || []; return { JSXAttribute(node) { const parent = node.parent; - if (shouldVerifyElement(parent) && shouldVerifyProp(node) && hasJavaScriptProtocol(node)) { - context.report(node, 'A future version of React will block javascript: URLs as a security precaution. ' + - 'Use event handlers instead if you can. If you need to generate unsafe HTML try using dangerouslySetInnerHTML instead.'); + if (shouldVerifyElement(parent, config) && shouldVerifyProp(node, config) && hasJavaScriptProtocol(node)) { + context.report({ + node, + message: 'A future version of React will block javascript: URLs as a security precaution. ' + + 'Use event handlers instead if you can. If you need to generate unsafe HTML, try using dangerouslySetInnerHTML instead.' + }); } } }; diff --git a/tests/lib/rules/jsx-no-script-url.js b/tests/lib/rules/jsx-no-script-url.js index edb800aa42..bd2355bede 100644 --- a/tests/lib/rules/jsx-no-script-url.js +++ b/tests/lib/rules/jsx-no-script-url.js @@ -26,7 +26,7 @@ const parserOptions = { const ruleTester = new RuleTester({parserOptions}); const message = 'A future version of React will block javascript: URLs as a security precaution. ' + - 'Use event handlers instead if you can. If you need to generate unsafe HTML try using dangerouslySetInnerHTML instead.'; + 'Use event handlers instead if you can. If you need to generate unsafe HTML, try using dangerouslySetInnerHTML instead.'; const defaultErrors = [{message}]; ruleTester.run('jsx-no-script-url', rule, {