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({
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 forEachCapturingGroup(pattern, callback) {
let number = 0;
visitRegExpAST(pattern, {
onCapturingGroupEnter(node) {
callback({
group: node,
number: ++number
});
}
});
}
const findLowercaseEscape = value => {
const ast = parseRegExpLiteral(value);
let escapeNodePosition;
visitRegExpAST(ast, {
/**
Record escaped node position in regexpp ASTNode. Returns undefined if not found.
@param {ASTNode} node A regexpp ASTNode. Note that it is of different type to the ASTNode of ESLint parsers
@returns {undefined}
*/
onCharacterLeave(node) {
if (escapeNodePosition) {
return;
}
const matches = node.raw.match(escapePatternWithLowercase);
if (matches && matches[2].slice(1).match(hasLowercaseCharacter)) {
escapeNodePosition = [node.start, node.end];
}
}
const patternNode = parser.parsePattern(
pattern,
0,
pattern.length,
flags.includes("u")
);
const has = {
surrogatePairWithoutUFlag: false,
combiningClass: false,
variationSelector: false,
emojiModifier: false,
regionalIndicatorSymbol: false,
zwj: false
};
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 });
}
}
}