Comparing version
77
index.js
@@ -1,39 +0,46 @@ | ||
var parse = require('ret'); | ||
var types = parse.types; | ||
const regexpTree = require('regexp-tree'); | ||
module.exports = function (re, opts) { | ||
if (!opts) opts = {}; | ||
var replimit = opts.limit === undefined ? 25 : opts.limit; | ||
if (isRegExp(re)) re = re.source; | ||
else if (typeof re !== 'string') re = String(re); | ||
try { re = parse(re) } | ||
catch (err) { return false } | ||
var reps = 0; | ||
return (function walk (node, starHeight) { | ||
if (node.type === types.REPETITION) { | ||
starHeight ++; | ||
reps ++; | ||
if (starHeight > 1) return false; | ||
if (reps > replimit) return false; | ||
if (!opts) opts = {}; | ||
const replimit = opts.limit === undefined ? 25 : opts.limit; | ||
let pattern = null; | ||
if (isRegExp(re)) pattern = re.source; | ||
else if (typeof re === 'string') pattern = re; | ||
else pattern = String(re); | ||
let ast = null; | ||
try { | ||
ast = regexpTree.parse(pattern); | ||
} catch (err) { | ||
try { | ||
ast = regexpTree.parse(`/${pattern}/`); } | ||
catch (err) { | ||
return false; | ||
} | ||
} | ||
let currentStarHeight = 0; | ||
let maxObservedStarHeight = 0; | ||
let repetitionCount = 0; | ||
regexpTree.traverse(ast, { | ||
'Repetition': { | ||
pre ({node}) { | ||
repetitionCount++; | ||
currentStarHeight++; | ||
if (maxObservedStarHeight < currentStarHeight) { | ||
maxObservedStarHeight = currentStarHeight; | ||
} | ||
if (node.options) { | ||
for (var i = 0, len = node.options.length; i < len; i++) { | ||
var ok = walk({ stack: node.options[i] }, starHeight); | ||
if (!ok) return false; | ||
} | ||
} | ||
var stack = node.stack || (node.value && node.value.stack); | ||
if (!stack) return true; | ||
for (var i = 0; i < stack.length; i++) { | ||
var ok = walk(stack[i], starHeight); | ||
if (!ok) return false; | ||
} | ||
return true; | ||
})(re, 0); | ||
}, | ||
post ({node}) { | ||
currentStarHeight--; | ||
} | ||
} | ||
}); | ||
return (maxObservedStarHeight <= 1) && (repetitionCount <= replimit); | ||
}; | ||
@@ -40,0 +47,0 @@ |
{ | ||
"name": "safe-regex", | ||
"version": "1.1.0", | ||
"version": "2.0.0", | ||
"description": "detect possibly catastrophic, exponential-time regular expressions", | ||
"main": "index.js", | ||
"dependencies": { | ||
"ret": "~0.1.10" | ||
"regexp-tree": "~0.0.85" | ||
}, | ||
@@ -27,5 +27,5 @@ "devDependencies": { | ||
"type": "git", | ||
"url": "git://github.com/substack/safe-regex.git" | ||
"url": "git://github.com/davisjam/safe-regex.git" | ||
}, | ||
"homepage": "https://github.com/substack/safe-regex", | ||
"homepage": "https://github.com/davisjam/safe-regex", | ||
"keywords": [ | ||
@@ -39,7 +39,7 @@ "catastrophic", | ||
"author": { | ||
"name": "James Halliday", | ||
"email": "mail@substack.net", | ||
"url": "http://substack.net" | ||
"name": "James C. (Jamie) Davis", | ||
"email": "davisjam@vt.edu", | ||
"url": "http://people.cs.vt.edu/~davisjam" | ||
}, | ||
"license": "MIT" | ||
} |
@@ -10,3 +10,7 @@ var safe = require('../'); | ||
/^\d+(1337|404)*\d+$/i, | ||
/(a+)|(b+)/, | ||
RegExp(Array(26).join('a?') + Array(26).join('a')), | ||
// String input. | ||
'aaa', | ||
'/^\d+(1337|404)*\d+$/' | ||
]; | ||
@@ -29,3 +33,10 @@ | ||
/(a+){2}y/, | ||
/(.*){1,32000}[bc]/ | ||
/(.*){1,32000}[bc]/, | ||
// Star height with branching and nesting. | ||
/(a*|b)+$/, | ||
/(a|b*)+$/, | ||
/(((b*)))+$/, | ||
/(((b*))+)$/, | ||
// String input. | ||
'(a+)+' | ||
]; | ||
@@ -32,0 +43,0 @@ |
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
6297
7.27%8
14.29%97
19.75%0
-100%64
-3.03%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed