Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
if (!DOUBLE_SPACE.test(rawPattern)) {
return;
}
const characterClassNodes = [];
let regExpAST;
try {
regExpAST = regExpParser.parsePattern(pattern, 0, pattern.length, flags.includes("u"));
} catch (e) {
// Ignore regular expressions with syntax errors
return;
}
regexpp.visitRegExpAST(regExpAST, {
onCharacterClassEnter(ccNode) {
characterClassNodes.push(ccNode);
}
});
const spacesPattern = /( {2,})(?: [+*{?]|[^+*{?]|$)/gu;
let match;
while ((match = spacesPattern.exec(pattern))) {
const { 1: { length }, index } = match;
// Report only consecutive spaces that are not in character classes.
if (
characterClassNodes.every(({ start, end }) => index < start || end <= index)
) {
context.report({
/**
* @fileoverview Validate strings passed to the RegExp constructor
* @author Michael Ficarra
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const RegExpValidator = require("regexpp").RegExpValidator;
const validator = new RegExpValidator({ ecmaVersion: 2018 });
const validFlags = /[gimuys]/gu;
const undefined1 = void 0;
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = {
meta: {
type: "problem",
docs: {
description: "disallow invalid regular expression strings in `RegExp` constructors",
category: "Possible Errors",
recommended: true,
url: "https://eslint.org/docs/rules/no-invalid-regexp"
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const astUtils = require("./utils/ast-utils");
const regexpp = require("regexpp");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
const regExpParser = new regexpp.RegExpParser();
const DOUBLE_SPACE = / {2}/u;
/**
* Check if node is a string
* @param {ASTNode} node node to evaluate
* @returns {boolean} True if its a string
* @private
*/
function isString(node) {
return node && node.type === "Literal" && typeof node.value === "string";
}
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const {
CALL,
CONSTRUCT,
ReferenceTracker,
getStringIfConstant
} = require("eslint-utils");
const regexpp = require("regexpp");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
const parser = new regexpp.RegExpParser();
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = {
meta: {
type: "suggestion",
docs: {
description: "enforce using named capture group in regular expression",
category: "Best Practices",
recommended: false,
url: "https://eslint.org/docs/rules/prefer-named-capture-group"
},
function checkRegex(regex, node, uFlag) {
let ast;
try {
ast = parser.parsePattern(regex, 0, regex.length, uFlag);
} catch (_) {
// ignore regex syntax errors
return;
}
regexpp.visitRegExpAST(ast, {
onCapturingGroupEnter(group) {
if (!group.name) {
const locNode = node.type === "Literal" ? node : node.arguments[0];
context.report({
node,
messageId: "required",
loc: {
start: {
line: locNode.loc.start.line,
column: locNode.loc.start.column + group.start + 1
},
end: {
line: locNode.loc.start.line,
column: locNode.loc.start.column + group.end + 1
}
let patternNode;
try {
patternNode = parser.parsePattern(
pattern,
0,
pattern.length,
flags.includes("u")
);
} catch (e) {
// Ignore regular expressions with syntax errors
return;
}
visitRegExpAST(patternNode, {
onCharacterClassEnter(ccNode) {
for (const chars of iterateCharacterSequence(ccNode.elements)) {
for (const kind of kinds) {
has[kind] = has[kind] || hasCharacterSequence[kind](chars);
}
}
}
});
for (const kind of kinds) {
if (has[kind]) {
context.report({ node, messageId: kind });
}
}
}
function parseRegExp(node) {
const evaluated = eslint_utils_1.getStaticValue(node, globalScope);
if (evaluated == null || !(evaluated.value instanceof RegExp)) {
return null;
}
const { pattern, flags } = regexpp_1.parseRegExpLiteral(evaluated.value);
if (pattern.alternatives.length !== 1 ||
flags.ignoreCase ||
flags.global) {
return null;
}
// Check if it can determine a unique string.
const chars = pattern.alternatives[0].elements;
if (!chars.every(c => c.type === 'Character')) {
return null;
}
// To string.
return String.fromCodePoint(...chars.map(c => c.value));
}
return {
function parseRegExp(node: TSESTree.Node): string | null {
const evaluated = getStaticValue(node, globalScope);
if (evaluated == null || !(evaluated.value instanceof RegExp)) {
return null;
}
const { pattern, flags } = parseRegExpLiteral(evaluated.value);
if (
pattern.alternatives.length !== 1 ||
flags.ignoreCase ||
flags.global
) {
return null;
}
// Check if it can determine a unique string.
const chars = pattern.alternatives[0].elements;
if (!chars.every(c => c.type === 'Character')) {
return null;
}
// To string.
return String.fromCodePoint(
function forEachCapturingGroup(pattern, callback) {
let number = 0;
visitRegExpAST(pattern, {
onCapturingGroupEnter(node) {
callback({
group: node,
number: ++number
});
}
});
}
function verify(context, node, pattern, flags) {
try {
let found = false
new RegExpValidator({
onUnicodePropertyCharacterSet() {
found = true
},
}).validatePattern(pattern, 0, pattern.length, flags.includes("u"))
if (found) {
context.report({ node, messageId: "forbidden" })
}
} catch (error) {
//istanbul ignore else
if (error.message.startsWith("Invalid regular expression:")) {
return
}
//istanbul ignore next
throw error
}