You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP →

eslint-plugin-regexp

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-regexp - npm Package Compare versions

Comparing version

to
0.6.2

@@ -8,2 +8,89 @@ "use strict";

const replacements_utils_1 = require("../utils/replacements-utils");
class CapturingData {
constructor(node, flags) {
this.unused = new Set();
this.unusedNames = new Map();
this.indexToCapturingGroup = new Map();
this.countOfCapturingGroup = 0;
this.state = {
used: false,
track: true,
};
this.node = node;
this.flags = flags;
}
getUnused() {
const unusedCapturingGroups = new Set(this.unused);
const unusedNames = new Set();
for (const cgNodes of this.unusedNames.values()) {
for (const cgNode of cgNodes) {
if (!unusedCapturingGroups.has(cgNode)) {
unusedNames.add(cgNode);
}
}
}
return {
unusedCapturingGroups,
unusedNames,
};
}
usedIndex(ref) {
const cgNode = this.indexToCapturingGroup.get(ref);
if (cgNode) {
this.unused.delete(cgNode);
}
}
usedName(ref) {
const cgNodes = this.unusedNames.get(ref);
if (cgNodes) {
this.unusedNames.delete(ref);
for (const cgNode of cgNodes) {
this.unused.delete(cgNode);
}
}
}
usedAllNames() {
for (const cgNodes of this.unusedNames.values()) {
for (const cgNode of cgNodes) {
this.unused.delete(cgNode);
}
}
this.unusedNames.clear();
}
isAllUsed() {
return !this.unused.size && !this.unusedNames.size;
}
markAsUsed() {
this.state.used = true;
}
markAsCannotTrack() {
this.state.track = false;
}
isNeedReport() {
return this.state.used && this.state.track && !this.isAllUsed();
}
visitor() {
return {
onCapturingGroupEnter: (cgNode) => {
this.countOfCapturingGroup++;
if (!cgNode.references.length) {
this.unused.add(cgNode);
this.indexToCapturingGroup.set(this.countOfCapturingGroup, cgNode);
}
else if (cgNode.references.some((ref) => typeof ref.ref === "string")) {
return;
}
if (cgNode.name) {
const array = this.unusedNames.get(cgNode.name);
if (array) {
array.push(cgNode);
}
else {
this.unusedNames.set(cgNode.name, [cgNode]);
}
}
},
};
}
}
function getProperty(node) {

@@ -161,23 +248,21 @@ if (node.type === "MemberExpression") {

}
function report(cgNode, data, messageId) {
context.report({
node: data.node,
loc: utils_1.getRegexpLocation(sourceCode, data.node, cgNode),
messageId: messageId !== null && messageId !== void 0 ? messageId : (cgNode.name
? "unusedNamedCapturingGroup"
: "unusedCapturingGroup"),
data: cgNode.name ? { name: cgNode.name } : {},
});
}
function reportUnused(capturingData, unusedCapturingGroups, unusedNames) {
function reportUnused(capturingData) {
const { unusedCapturingGroups, unusedNames, } = capturingData.getUnused();
for (const cgNode of unusedCapturingGroups) {
report(cgNode, capturingData, null);
context.report({
node: capturingData.node,
loc: utils_1.getRegexpLocation(sourceCode, capturingData.node, cgNode),
messageId: cgNode.name
? "unusedNamedCapturingGroup"
: "unusedCapturingGroup",
data: cgNode.name ? { name: cgNode.name } : {},
});
}
for (const cgNodes of unusedNames.values()) {
for (const cgNode of cgNodes) {
if (unusedCapturingGroups.has(cgNode)) {
continue;
}
report(cgNode, capturingData, "unusedName");
}
for (const cgNode of unusedNames) {
context.report({
node: capturingData.node,
loc: utils_1.getRegexpLocation(sourceCode, capturingData.node, cgNode),
messageId: "unusedName",
data: { name: cgNode.name },
});
}

@@ -187,3 +272,3 @@ }

const capturingData = getCapturingData(node.arguments[0]);
if (capturingData == null || !capturingData.unused.size) {
if (capturingData == null || capturingData.isAllUsed()) {
return;

@@ -195,7 +280,6 @@ }

if (capturingData.flags.includes("g")) {
for (const cgNode of capturingData.unused) {
report(cgNode, capturingData, null);
}
capturingData.markAsUsed();
}
else {
capturingData.markAsUsed();
verifyForExecResult(node, capturingData);

@@ -206,3 +290,3 @@ }

const capturingData = getCapturingData(node.arguments[0]);
if (capturingData == null || !capturingData.unused.size) {
if (capturingData == null || capturingData.isAllUsed()) {
return;

@@ -213,9 +297,7 @@ }

}
for (const cgNode of capturingData.unused) {
report(cgNode, capturingData, null);
}
capturingData.markAsUsed();
}
function verifyForTest(node) {
const capturingData = getCapturingData(node.callee.object);
if (capturingData == null || !capturingData.unused.size) {
if (capturingData == null || capturingData.isAllUsed()) {
return;

@@ -226,9 +308,7 @@ }

}
for (const cgNode of capturingData.unused) {
report(cgNode, capturingData, null);
}
capturingData.markAsUsed();
}
function verifyForReplace(node) {
const capturingData = getCapturingData(node.arguments[0]);
if (capturingData == null || !capturingData.unused.size) {
if (capturingData == null || capturingData.isAllUsed()) {
return;

@@ -242,2 +322,3 @@ }

replacementNode.type === "ArrowFunctionExpression") {
capturingData.markAsUsed();
verifyForReplaceFunction(replacementNode, capturingData);

@@ -248,4 +329,6 @@ }

if (!evaluated || typeof evaluated.value !== "string") {
capturingData.markAsCannotTrack();
return;
}
capturingData.markAsUsed();
verifyForReplacePattern(evaluated.value, capturingData);

@@ -255,31 +338,18 @@ }

function verifyForReplacePattern(replacementPattern, capturingData) {
const unusedCapturingGroups = new Set(capturingData.unused);
const unusedNames = new Map(capturingData.unusedNames);
for (const replacement of replacements_utils_1.parseReplacementsForString(replacementPattern)) {
if (replacement.type === "ReferenceElement") {
if (typeof replacement.ref === "number") {
const cgNode = capturingData.unusedIndexes.get(replacement.ref);
if (cgNode) {
unusedCapturingGroups.delete(cgNode);
}
capturingData.usedIndex(replacement.ref);
}
else {
const cgNodes = unusedNames.get(replacement.ref);
if (cgNodes) {
unusedNames.delete(replacement.ref);
for (const cgNode of cgNodes) {
unusedCapturingGroups.delete(cgNode);
}
}
capturingData.usedName(replacement.ref);
}
}
}
reportUnused(capturingData, unusedCapturingGroups, unusedNames);
}
function verifyForReplaceFunction(replacementNode, capturingData) {
const unusedCapturingGroups = new Set(capturingData.unused);
const unusedNames = new Map(capturingData.unusedNames);
for (let index = 0; index < replacementNode.params.length; index++) {
const arg = replacementNode.params[index];
if (arg.type === "RestElement") {
capturingData.markAsCannotTrack();
return;

@@ -290,22 +360,13 @@ }

}
else if (index <= capturingData.count) {
const cgNode = capturingData.unusedIndexes.get(index);
if (cgNode) {
unusedCapturingGroups.delete(cgNode);
}
else if (index <= capturingData.countOfCapturingGroup) {
capturingData.usedIndex(index);
}
else if (capturingData.count + 3 <= index) {
for (const cgNodes of unusedNames.values()) {
for (const cgNode of cgNodes) {
unusedCapturingGroups.delete(cgNode);
}
}
unusedNames.clear();
else if (capturingData.countOfCapturingGroup + 3 <= index) {
capturingData.usedAllNames();
}
}
reportUnused(capturingData, unusedCapturingGroups, unusedNames);
}
function verifyForExec(node) {
const capturingData = getCapturingData(node.callee.object);
if (capturingData == null || !capturingData.unused.size) {
if (capturingData == null || capturingData.isAllUsed()) {
return;

@@ -316,2 +377,3 @@ }

}
capturingData.markAsUsed();
verifyForExecResult(node, capturingData);

@@ -322,6 +384,5 @@ }

if (refs == null) {
capturingData.markAsCannotTrack();
return;
}
const unusedCapturingGroups = new Set(capturingData.unused);
const unusedNames = new Map(capturingData.unusedNames);
for (const ref of refs) {

@@ -331,18 +392,7 @@ if (ref.ref === "groups") {

if (sub == null) {
for (const cgNodes of unusedNames.values()) {
for (const cgNode of cgNodes) {
unusedCapturingGroups.delete(cgNode);
}
}
unusedNames.clear();
capturingData.usedAllNames();
}
else {
for (const namedRef of sub) {
const cgNodes = unusedNames.get(namedRef.ref);
if (cgNodes) {
unusedNames.delete(namedRef.ref);
for (const cgNode of cgNodes) {
unusedCapturingGroups.delete(cgNode);
}
}
capturingData.usedName(namedRef.ref);
}

@@ -352,13 +402,9 @@ }

else {
const cgNode = capturingData.unusedIndexes.get(Number(ref.ref));
if (cgNode) {
unusedCapturingGroups.delete(cgNode);
}
capturingData.usedIndex(Number(ref.ref));
}
}
reportUnused(capturingData, unusedCapturingGroups, unusedNames);
}
function verifyForMatchAll(node) {
const capturingData = getCapturingData(node.arguments[0]);
if (capturingData == null || !capturingData.unused.size) {
if (capturingData == null || capturingData.isAllUsed()) {
return;

@@ -369,8 +415,8 @@ }

}
capturingData.markAsUsed();
const refs = extractUsedReferencesForIteration(node);
if (refs == null) {
capturingData.markAsCannotTrack();
return;
}
const unusedCapturingGroups = new Set(capturingData.unused);
const unusedNames = new Map(capturingData.unusedNames);
for (const ref of refs) {

@@ -380,18 +426,7 @@ if (ref.ref === "groups") {

if (sub == null) {
for (const cgNodes of unusedNames.values()) {
for (const cgNode of cgNodes) {
unusedCapturingGroups.delete(cgNode);
}
}
unusedNames.clear();
capturingData.usedAllNames();
}
else {
for (const namedRef of sub) {
const cgNodes = unusedNames.get(namedRef.ref);
if (cgNodes) {
unusedNames.delete(namedRef.ref);
for (const cgNode of cgNodes) {
unusedCapturingGroups.delete(cgNode);
}
}
capturingData.usedName(namedRef.ref);
}

@@ -401,9 +436,5 @@ }

else {
const cgNode = capturingData.unusedIndexes.get(Number(ref.ref));
if (cgNode) {
unusedCapturingGroups.delete(cgNode);
}
capturingData.usedIndex(Number(ref.ref));
}
}
reportUnused(capturingData, unusedCapturingGroups, unusedNames);
function extractUsedReferencesForIteration(expr) {

@@ -457,36 +488,15 @@ const parent = expr.parent;

function createVisitor(node, _pattern, flags, regexpNode) {
const capturingData = {
unused: new Set(),
unusedIndexes: new Map(),
unusedNames: new Map(),
count: 0,
flags,
node,
};
const capturingData = new CapturingData(node, flags);
capturingDataMap.set(regexpNode, capturingData);
return {
onCapturingGroupEnter(cgNode) {
capturingData.count++;
if (!cgNode.references.length) {
capturingData.unused.add(cgNode);
capturingData.unusedIndexes.set(capturingData.count, cgNode);
}
else if (cgNode.references.some((ref) => typeof ref.ref === "string")) {
return;
}
if (cgNode.name) {
const array = capturingData.unusedNames.get(cgNode.name);
if (array) {
array.push(cgNode);
}
else {
capturingData.unusedNames.set(cgNode.name, [cgNode]);
}
}
},
};
return capturingData.visitor();
}
return Object.assign(Object.assign({}, utils_1.defineRegexpVisitor(context, {
createVisitor,
})), { "CallExpression:exit"(node) {
})), { "Program:exit"() {
for (const capturingData of capturingDataMap.values()) {
if (capturingData.isNeedReport()) {
reportUnused(capturingData);
}
}
}, "CallExpression:exit"(node) {
if (!ast_utils_1.isKnownMethodCall(node, {

@@ -493,0 +503,0 @@ match: 1,

{
"name": "eslint-plugin-regexp",
"version": "0.6.1",
"version": "0.6.2",
"description": "ESLint plugin for finding RegExp mistakes and RegExp style guide violations.",

@@ -49,3 +49,3 @@ "main": "dist/index.js",

"devDependencies": {
"@ota-meshi/eslint-plugin": "^0.4.0",
"@ota-meshi/eslint-plugin": "^0.5.0",
"@types/eslint": "^7.2.0",

@@ -68,3 +68,3 @@ "@types/eslint-scope": "^3.7.0",

"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-regexp": "^0.5.0",
"eslint-plugin-regexp": "^0.6.0",
"eslint-plugin-vue": "^7.5.0",

@@ -71,0 +71,0 @@ "eslint-plugin-yml": "^0.9.0",