diff --git a/CHANGELOG.md b/CHANGELOG.md index 3188c031a6..91505a7a30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange * [`no-array-index-key`]: catch `.toString` and `String()` usage ([#2813][] @RedTn) * [`function-component-definition`]: do not break on dollar signs ([#3207][] @ljharb) * [`prefer-stateless-function`]: avoid a crash inside `doctrine` ([#2596][] @ljharb) +* [`prop-types`]: catch infinite loop ([#2861][] @ljharb) ### Changed * [readme] change [`jsx-runtime`] link from branch to sha ([#3160][] @tatsushitoji) @@ -56,6 +57,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange [#3160]: https://github.com/yannickcr/eslint-plugin-react/pull/3160 [#3133]: https://github.com/yannickcr/eslint-plugin-react/pull/3133 [#2921]: https://github.com/yannickcr/eslint-plugin-react/pull/2921 +[#2861]: https://github.com/yannickcr/eslint-plugin-react/issues/2861 [#2813]: https://github.com/yannickcr/eslint-plugin-react/pull/2813 [#2753]: https://github.com/yannickcr/eslint-plugin-react/pull/2753 [#2614]: https://github.com/yannickcr/eslint-plugin-react/issues/2614 diff --git a/lib/util/propTypes.js b/lib/util/propTypes.js index 97022028f0..8da9fb9f15 100644 --- a/lib/util/propTypes.js +++ b/lib/util/propTypes.js @@ -1187,7 +1187,11 @@ module.exports = function propTypesInstructions(context, components, utils) { if (!component) { return; } - markPropTypesAsDeclared(component.node, node.parent.right || node.parent); + try { + markPropTypesAsDeclared(component.node, node.parent.right || node.parent); + } catch (e) { + if (e.constructor !== RangeError) { throw e; } + } } }, diff --git a/tests/lib/rules/prop-types.js b/tests/lib/rules/prop-types.js index 8ba945d7ef..090e8493ca 100644 --- a/tests/lib/rules/prop-types.js +++ b/tests/lib/rules/prop-types.js @@ -3753,19 +3753,19 @@ ruleTester.run('prop-types', rule, { value: string, error: string, } - + type Form = { fields: { [string]: Field, }, formError: string, } - + type Props = { bankDetails: Form, onBankDetailsUpdate: any => void, } - + const Provider = (props:Props) => { return
{props.name}
; }; - + return getNameDiv(); }; - + DisplayName.propTypes = { name: PropTypes.string.isRequired, }; @@ -3832,10 +3832,10 @@ ruleTester.run('prop-types', rule, { function renderComponent() { return
{props.name}
} - + return renderComponent(); } - + SomeComponent.propTypes = { name: PropTypes.string } @@ -3845,29 +3845,29 @@ ruleTester.run('prop-types', rule, { code: ` import React from 'react'; import { MyType } from './types'; - + function Component(props: Props): JSX.Element | null { const { array } = props; - + function renderFound(): JSX.Element | null { const found = array.find(x => x.id === id); // issue here - + if (!found) { return null; } - + return (
{found.id}
); } - + return renderFound(); } - + interface Props { array: MyType[]; } - + export default Component; `, features: ['types'], @@ -3916,9 +3916,9 @@ ruleTester.run('prop-types', rule, { code: ` import PropTypes from 'prop-types'; import React from 'react'; - + import { Link } from '..'; - + const LinkWrapper = ({ primaryLinks }) => ( <> {primaryLinks.map((x, index) => ( @@ -3928,7 +3928,7 @@ ruleTester.run('prop-types', rule, { ))} ); - + LinkWrapper.propTypes = { primaryLinks: PropTypes.arrayOf( PropTypes.shape({ @@ -3936,9 +3936,35 @@ ruleTester.run('prop-types', rule, { }) ), }; - + export default LinkWrapper; `, + }, + { + code: ` + const projectType = PropTypes.shape({ + id: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, + }); + + const nodesType = PropTypes.arrayOf( + PropTypes.shape({ project: projectType, children: nodesType }), + ); + + class ProjectNode extends React.Component { + render() { + return
; + } + } + + ProjectNode.propTypes = { + project: projectType.isRequired, + nodes: nodesType, + depth: PropTypes.number.isRequired, + setActiveProject: PropTypes.func.isRequired, + activeProject: projectType, + }; + `, } )),