From 498bc10543154704879028ec58847350173402ca Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 30 Nov 2019 00:06:47 +0800 Subject: [PATCH 1/8] Fix `regex-shorthand` crush bug --- rules/regex-shorthand.js | 11 ++++++++++- test/regex-shorthand.js | 4 +++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/rules/regex-shorthand.js b/rules/regex-shorthand.js index 63e3b2f426..ac7149fa54 100644 --- a/rules/regex-shorthand.js +++ b/rules/regex-shorthand.js @@ -31,8 +31,17 @@ const create = context => { return; } + const optimized = optimize(value); + + // Optimized RegExp might broken and crush ESLint + try { + optimized.toRegExp(); + } catch (_) { + return; + } + const originalRegex = generate(parsedSource).toString(); - const optimizedRegex = optimize(value).toString(); + const optimizedRegex = optimized.toString(); if (originalRegex === optimizedRegex) { return; diff --git a/test/regex-shorthand.js b/test/regex-shorthand.js index d1a6fd6f20..49c369d010 100644 --- a/test/regex-shorthand.js +++ b/test/regex-shorthand.js @@ -31,7 +31,9 @@ ruleTester.run('regex-shorthand', rule, { 'const foo = new RegExp(/\\d/ig)', 'const foo = new RegExp(/\\d/, \'ig\')', 'const foo = new RegExp(/\\d*?/)', - 'const foo = new RegExp(/[a-z]/, \'i\')' + 'const foo = new RegExp(/[a-z]/, \'i\')', + // Should not crush eslint #446 + 'const foo = /\\{\\{verificationUrl\\}\\}/gu', ], invalid: [ { From a81300c926d03e5c8116e295d9c95ccc524c71b9 Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 30 Nov 2019 00:22:10 +0800 Subject: [PATCH 2/8] style --- test/regex-shorthand.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/regex-shorthand.js b/test/regex-shorthand.js index 49c369d010..604d042f32 100644 --- a/test/regex-shorthand.js +++ b/test/regex-shorthand.js @@ -33,7 +33,7 @@ ruleTester.run('regex-shorthand', rule, { 'const foo = new RegExp(/\\d*?/)', 'const foo = new RegExp(/[a-z]/, \'i\')', // Should not crush eslint #446 - 'const foo = /\\{\\{verificationUrl\\}\\}/gu', + 'const foo = /\\{\\{verificationUrl\\}\\}/gu' ], invalid: [ { From 69cd1cea479b7f7cef3fcb3629c6b55f44779c9e Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Fri, 29 Nov 2019 23:31:04 +0700 Subject: [PATCH 3/8] Update regex-shorthand.js --- test/regex-shorthand.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/regex-shorthand.js b/test/regex-shorthand.js index 604d042f32..7fbab1ddbe 100644 --- a/test/regex-shorthand.js +++ b/test/regex-shorthand.js @@ -32,7 +32,7 @@ ruleTester.run('regex-shorthand', rule, { 'const foo = new RegExp(/\\d/, \'ig\')', 'const foo = new RegExp(/\\d*?/)', 'const foo = new RegExp(/[a-z]/, \'i\')', - // Should not crush eslint #446 + // Should not crash ESLint (#446) 'const foo = /\\{\\{verificationUrl\\}\\}/gu' ], invalid: [ From 832b3177c9facaf10b93a31cf1fae924e69ac7f1 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Fri, 29 Nov 2019 23:31:33 +0700 Subject: [PATCH 4/8] Update regex-shorthand.js --- rules/regex-shorthand.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/regex-shorthand.js b/rules/regex-shorthand.js index ac7149fa54..99d883b7f2 100644 --- a/rules/regex-shorthand.js +++ b/rules/regex-shorthand.js @@ -33,7 +33,7 @@ const create = context => { const optimized = optimize(value); - // Optimized RegExp might broken and crush ESLint + // The optimized regex might be broken and crash ESLint try { optimized.toRegExp(); } catch (_) { From d529c87d1e204266b9aab4b4b79fc3a0738ca3b5 Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 30 Nov 2019 00:31:45 +0800 Subject: [PATCH 5/8] add issue 448 test --- test/regex-shorthand.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/test/regex-shorthand.js b/test/regex-shorthand.js index 604d042f32..8752ab0d9e 100644 --- a/test/regex-shorthand.js +++ b/test/regex-shorthand.js @@ -3,11 +3,8 @@ import avaRuleTester from 'eslint-ava-rule-tester'; import rule from '../rules/regex-shorthand'; const ruleTester = avaRuleTester(test, { - env: { - es6: true - }, parserOptions: { - sourceType: 'module' + ecmaVersion: 2020 } }); @@ -32,8 +29,9 @@ ruleTester.run('regex-shorthand', rule, { 'const foo = new RegExp(/\\d/, \'ig\')', 'const foo = new RegExp(/\\d*?/)', 'const foo = new RegExp(/[a-z]/, \'i\')', - // Should not crush eslint #446 - 'const foo = /\\{\\{verificationUrl\\}\\}/gu' + // Should not crush eslint #446 and #448 + '/\\{\\{verificationUrl\\}\\}/gu', + '/^test-(?[a-zA-Z-\\d]+)$/u' ], invalid: [ { From a79c04cc9a0e85e61c5662255e3476056492fa8b Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 30 Nov 2019 01:23:21 +0800 Subject: [PATCH 6/8] add issue 447 test --- test/regex-shorthand.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/regex-shorthand.js b/test/regex-shorthand.js index ef4e4faafa..a8265f6c15 100644 --- a/test/regex-shorthand.js +++ b/test/regex-shorthand.js @@ -29,9 +29,14 @@ ruleTester.run('regex-shorthand', rule, { 'const foo = new RegExp(/\\d/, \'ig\')', 'const foo = new RegExp(/\\d*?/)', 'const foo = new RegExp(/[a-z]/, \'i\')', + // Should not crash ESLint (#446 and #448) '/\\{\\{verificationUrl\\}\\}/gu', - '/^test-(?[a-zA-Z-\\d]+)$/u' + '/^test-(?[a-zA-Z-\\d]+)$/u', + + // Should not suggest wrong regex (#447) + '/(\\s|\\.|@|_|-)/u', + '/[\\s.@_-]/u' ], invalid: [ { From 2f57da8c58a2ce9fab22928aa32f112c651d676b Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 30 Nov 2019 01:45:15 +0800 Subject: [PATCH 7/8] skip all `u` flag --- rules/regex-shorthand.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/rules/regex-shorthand.js b/rules/regex-shorthand.js index 99d883b7f2..78ebf302e4 100644 --- a/rules/regex-shorthand.js +++ b/rules/regex-shorthand.js @@ -31,17 +31,14 @@ const create = context => { return; } - const optimized = optimize(value); - - // The optimized regex might be broken and crash ESLint - try { - optimized.toRegExp(); - } catch (_) { + // `u` flag regex is not well handled by `regexp-tree` + // https://github.com/DmitrySoshnikov/regexp-tree/issues/162 + if (parsedSource.flags.includes('u')) { return; } const originalRegex = generate(parsedSource).toString(); - const optimizedRegex = optimized.toString(); + const optimizedRegex = optimize(value).toString(); if (originalRegex === optimizedRegex) { return; From 9df07542c040f633266ee546bf45b50fe24e0e30 Mon Sep 17 00:00:00 2001 From: fisker Date: Sat, 30 Nov 2019 10:17:42 +0800 Subject: [PATCH 8/8] skip u flag before parse --- rules/regex-shorthand.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rules/regex-shorthand.js b/rules/regex-shorthand.js index 78ebf302e4..1494ef49c0 100644 --- a/rules/regex-shorthand.js +++ b/rules/regex-shorthand.js @@ -9,12 +9,18 @@ const message = 'Use regex shorthands to improve readability.'; const create = context => { return { 'Literal[regex]': node => { - const {type, value} = context.getSourceCode().getFirstToken(node); + const {type, value, regex} = context.getSourceCode().getFirstToken(node); if (type !== 'RegularExpression') { return; } + // Regex with `u` flag is not well handled by `regexp-tree` + // https://github.com/DmitrySoshnikov/regexp-tree/issues/162 + if (regex.flags.includes('u')) { + return; + } + let parsedSource; try { parsedSource = parse(value); @@ -31,12 +37,6 @@ const create = context => { return; } - // `u` flag regex is not well handled by `regexp-tree` - // https://github.com/DmitrySoshnikov/regexp-tree/issues/162 - if (parsedSource.flags.includes('u')) { - return; - } - const originalRegex = generate(parsedSource).toString(); const optimizedRegex = optimize(value).toString();