diff --git a/CHANGELOG.md b/CHANGELOG.md index d2d440c808..703ac049f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,22 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## Unreleased +## [7.26.1] - 2021.09.29 + +### Fixed +* [`no-namespace`]: fix crash on non-string React.createElement name ([#3082] @ljharb) +* [`no-namespace`]: avoid crash on non-string createElement values ([#3085] @ljharb) +* [`jsx-no-target-blank`]: improve error messages ([#3088] @cutiful) + +### Changed +* [Docs] [`jsx-max-props-per-line`]: fix options example ([#3083] @MrRaiter) + +[7.26.1]: https://github.com/yannickcr/eslint-plugin-react/compare/v7.26.0...v7.26.1 +[#3088]: https://github.com/yannickcr/eslint-plugin-react/pull/3088 +[#3085]: https://github.com/yannickcr/eslint-plugin-react/issue/3085 +[#3083]: https://github.com/yannickcr/eslint-plugin-react/pull/3083 +[#3082]: https://github.com/yannickcr/eslint-plugin-react/pull/3082 + ## [7.26.0] - 2021.09.20 ### Added diff --git a/docs/rules/jsx-max-props-per-line.md b/docs/rules/jsx-max-props-per-line.md index 5bae2076cf..182dc05d33 100644 --- a/docs/rules/jsx-max-props-per-line.md +++ b/docs/rules/jsx-max-props-per-line.md @@ -43,7 +43,7 @@ Examples of **correct** code for this rule: // OR ... -"react/jsx-max-props-per-line": [, { "maximum": { single multi: } }] +"react/jsx-max-props-per-line": [, { "maximum": { "single": , "multi": } }] ... ``` diff --git a/docs/rules/jsx-no-target-blank.md b/docs/rules/jsx-no-target-blank.md index 0f5cfbee92..ea13747d3f 100644 --- a/docs/rules/jsx-no-target-blank.md +++ b/docs/rules/jsx-no-target-blank.md @@ -20,8 +20,8 @@ This rule aims to prevent user generated link hrefs and form actions from creati ... ``` -* `allowReferrer`: optional boolean. If `true` does not require `noreferrer`. Defaults to `false`. -* `enabled`: for enabling the rule. 0=off, 1=warn, 2=error. Defaults to 0. +* `allowReferrer`: optional boolean. If `true` does not require `noreferrer` (i. e. `noopener` alone is enough, this leaves IE vulnerable). Defaults to `false`. +* `enabled`: for enabling the rule. * `enforceDynamicLinks`: optional string, 'always' or 'never' * `warnOnSpreadAttributes`: optional boolean. Defaults to `false`. * `enforceDynamicLinks` - enforce: optional string, 'always' or 'never' @@ -125,6 +125,8 @@ This rule supports the ability to use custom components for forms. To enable thi For links to a trusted host (e.g. internal links to your own site, or links to a another host you control, where you can be certain this security vulnerability does not exist), you may want to keep the HTTP Referer header for analytics purposes. +If you do not support Internet Explorer (any version), Chrome < 49, Opera < 36, Firefox < 52, desktop Safari < 10.1 or iOS Safari < 10.3, you may set `allowReferrer` to `true`, keep the HTTP Referer header and only add `rel="noopener"` to your links. + ## When Not To Use It If you do not have any external links or forms, you can disable this rule. diff --git a/docs/rules/react-in-jsx-scope.md b/docs/rules/react-in-jsx-scope.md index b3357dc671..8f0fc7598d 100644 --- a/docs/rules/react-in-jsx-scope.md +++ b/docs/rules/react-in-jsx-scope.md @@ -44,4 +44,4 @@ var Hello =
Hello {this.props.name}
; If you are not using JSX, or if you are setting `React` as a global variable. -If you are using the [new JSX transform from React 17](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html#removing-unused-react-imports), you should disable this rule by extending [`react/jsx-runtime`](https://github.com/yannickcr/eslint-plugin-react/blob/HEAD/index.js#L163-L176) in your eslint config (add `"plugin:react/jsx-runtime"` to `"extends"`). \ No newline at end of file +If you are using the [new JSX transform from React 17](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html#removing-unused-react-imports), you should disable this rule by extending [`react/jsx-runtime`](https://github.com/yannickcr/eslint-plugin-react/blob/8cf47a8ac2242ee00ea36eac4b6ae51956ba4411/index.js#L165-L179) in your eslint config (add `"plugin:react/jsx-runtime"` to `"extends"`). diff --git a/lib/rules/jsx-no-target-blank.js b/lib/rules/jsx-no-target-blank.js index d73c8e4f9d..18e056575c 100644 --- a/lib/rules/jsx-no-target-blank.js +++ b/lib/rules/jsx-no-target-blank.js @@ -97,7 +97,8 @@ function hasSecureRel(node, allowReferrer, warnOnSpreadAttributes, spreadAttribu } const messages = { - noTargetBlank: 'Using target="_blank" without rel="noreferrer" is a security risk: see https://html.spec.whatwg.org/multipage/links.html#link-type-noopener' + noTargetBlankWithoutNoreferrer: 'Using target="_blank" without rel="noreferrer" (which implies rel="noopener") is a security risk in older browsers: see https://mathiasbynens.github.io/rel-noopener/#recommendations', + noTargetBlankWithoutNoopener: 'Using target="_blank" without rel="noreferrer" or rel="noopener" (the former implies the latter and is preferred due to wider support) is a security risk: see https://mathiasbynens.github.io/rel-noopener/#recommendations' }; module.exports = { @@ -173,7 +174,8 @@ module.exports = { const hasDangerousLink = hasExternalLink(node, linkAttribute, warnOnSpreadAttributes, spreadAttributeIndex) || (enforceDynamicLinks === 'always' && hasDynamicLink(node, linkAttribute)); if (hasDangerousLink && !hasSecureRel(node, allowReferrer, warnOnSpreadAttributes, spreadAttributeIndex)) { - report(context, messages.noTargetBlank, 'noTargetBlank', { + const messageId = allowReferrer ? 'noTargetBlankWithoutNoopener' : 'noTargetBlankWithoutNoreferrer'; + report(context, messages[messageId], messageId, { node, fix(fixer) { // eslint 5 uses `node.attributes`; eslint 6+ uses `node.parent.attributes` @@ -244,7 +246,8 @@ module.exports = { hasExternalLink(node, formAttribute) || (enforceDynamicLinks === 'always' && hasDynamicLink(node, formAttribute)) ) { - report(context, messages.noTargetBlank, 'noTargetBlank', { + const messageId = allowReferrer ? 'noTargetBlankWithoutNoopener' : 'noTargetBlankWithoutNoreferrer'; + report(context, messages[messageId], messageId, { node }); } diff --git a/lib/rules/no-namespace.js b/lib/rules/no-namespace.js index 18a257592d..dfd0a0be8c 100644 --- a/lib/rules/no-namespace.js +++ b/lib/rules/no-namespace.js @@ -40,7 +40,7 @@ module.exports = { CallExpression(node) { if (isCreateElement(node, context) && node.arguments.length > 0 && node.arguments[0].type === 'Literal') { const name = node.arguments[0].value; - if (name.indexOf(':') === -1) return undefined; + if (typeof name !== 'string' || name.indexOf(':') === -1) return undefined; report(context, messages.noNamespace, 'noNamespace', { node, data: { @@ -51,7 +51,7 @@ module.exports = { }, JSXOpeningElement(node) { const name = elementType(node); - if (name.indexOf(':') === -1) return undefined; + if (typeof name !== 'string' || name.indexOf(':') === -1) return undefined; report(context, messages.noNamespace, 'noNamespace', { node, data: { diff --git a/package.json b/package.json index 24f4b0cd40..f607b51634 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-react", - "version": "7.26.0", + "version": "7.26.1", "author": "Yannick Croissant ", "description": "React specific linting rules for ESLint", "main": "index.js", diff --git a/tests/lib/rules/jsx-no-target-blank.js b/tests/lib/rules/jsx-no-target-blank.js index ce2402325f..38302d6a7d 100644 --- a/tests/lib/rules/jsx-no-target-blank.js +++ b/tests/lib/rules/jsx-no-target-blank.js @@ -25,7 +25,7 @@ const parserOptions = { // ------------------------------------------------------------------------------ const ruleTester = new RuleTester({parserOptions}); -const defaultErrors = [{messageId: 'noTargetBlank'}]; +const defaultErrors = [{messageId: 'noTargetBlankWithoutNoreferrer'}]; ruleTester.run('jsx-no-target-blank', rule, { valid: [ @@ -249,7 +249,7 @@ ruleTester.run('jsx-no-target-blank', rule, { code: '', output: '', options: [{allowReferrer: true}], - errors: defaultErrors + errors: [{messageId: 'noTargetBlankWithoutNoopener'}] }, { code: '', diff --git a/tests/lib/rules/no-namespace.js b/tests/lib/rules/no-namespace.js index c3f6b3ef5d..fa381ccfe4 100644 --- a/tests/lib/rules/no-namespace.js +++ b/tests/lib/rules/no-namespace.js @@ -74,6 +74,12 @@ ruleTester.run('no-namespace', rule, { code: '' }, { code: 'React.createElement("Object.TestComponent")' + }, { + code: 'React.createElement(null)' + }, { + code: 'React.createElement(true)' + }, { + code: 'React.createElement({})' }], invalid: [{