From 5e1a64c14f8fda5e186991b1e09a55f476a64e27 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Tue, 30 Jan 2018 23:08:34 -0800 Subject: [PATCH] [Fix] `no-danger-with-children`: prevent infinite loop Fixes #1571 --- lib/rules/no-danger-with-children.js | 14 +++++++++----- tests/lib/rules/no-danger-with-children.js | 6 ++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/rules/no-danger-with-children.js b/lib/rules/no-danger-with-children.js index b4f4551ce9..b96e3eb6c1 100644 --- a/lib/rules/no-danger-with-children.js +++ b/lib/rules/no-danger-with-children.js @@ -29,7 +29,7 @@ module.exports = { * @param {object} node - ObjectExpression node * @param {string} propName - name of the prop to look for */ - function findObjectProp(node, propName) { + function findObjectProp(node, propName, seenProps) { if (!node.properties) { return false; } @@ -39,7 +39,11 @@ module.exports = { } else if (prop.type === 'ExperimentalSpreadProperty') { const variable = findSpreadVariable(prop.argument.name); if (variable && variable.defs.length && variable.defs[0].node.init) { - return findObjectProp(variable.defs[0].node.init, propName); + if (seenProps.indexOf(prop.argument.name) > -1) { + return false; + } + const newSeenProps = seenProps.concat(prop.argument.name || []); + return findObjectProp(variable.defs[0].node.init, propName, newSeenProps); } } return false; @@ -57,7 +61,7 @@ module.exports = { if (attribute.type === 'JSXSpreadAttribute') { const variable = findSpreadVariable(attribute.argument.name); if (variable && variable.defs.length && variable.defs[0].node.init) { - return findObjectProp(variable.defs[0].node.init, propName); + return findObjectProp(variable.defs[0].node.init, propName, []); } } return attribute.name && attribute.name.name === propName; @@ -113,10 +117,10 @@ module.exports = { } } - const dangerously = findObjectProp(props, 'dangerouslySetInnerHTML'); + const dangerously = findObjectProp(props, 'dangerouslySetInnerHTML', []); if (node.arguments.length === 2) { - if (findObjectProp(props, 'children')) { + if (findObjectProp(props, 'children', [])) { hasChildren = true; } } else { diff --git a/tests/lib/rules/no-danger-with-children.js b/tests/lib/rules/no-danger-with-children.js index bb3db1711f..34068fdb2b 100644 --- a/tests/lib/rules/no-danger-with-children.js +++ b/tests/lib/rules/no-danger-with-children.js @@ -91,6 +91,12 @@ ruleTester.run('no-danger-with-children', rule, { }, { code: 'React.createElement("Hello", undefined, "Children")' + }, + { + code: ` + const props = {...props, scratch: {mode: 'edit'}}; + const component = shallow(); + ` } ], invalid: [