1 | const analyzer = require('./lib/analyzer');
|
2 | const analyzerFamily = require('./lib/analyzer-family');
|
3 |
|
4 | const DEFAULT_SAFE_REP_LIMIT = 25;
|
5 | const RET_IS_SAFE = true;
|
6 | const RET_IS_VULNERABLE = false;
|
7 |
|
8 | class Args {
|
9 | constructor(regExp, analyzerOptions) {
|
10 | this.regExp = regExp;
|
11 | this.analyzerOptions = analyzerOptions;
|
12 | }
|
13 | }
|
14 |
|
15 | function safeRegex(re, opts) {
|
16 | try {
|
17 | const args = buildArgs(re, opts);
|
18 | const analyzerResponses = askAnalyzersIfVulnerable(args);
|
19 |
|
20 |
|
21 | if (analyzerResponses.find((isVulnerable) => isVulnerable)) {
|
22 | return RET_IS_VULNERABLE;
|
23 | } else {
|
24 | return RET_IS_SAFE;
|
25 | }
|
26 | } catch (err) {
|
27 |
|
28 | return false;
|
29 | }
|
30 | }
|
31 |
|
32 | function buildArgs(re, opts) {
|
33 |
|
34 | if (!opts) opts = {};
|
35 | const heuristic_replimit = opts.limit === undefined ? DEFAULT_SAFE_REP_LIMIT : opts.limit;
|
36 |
|
37 | const analyzerOptions = new analyzer.AnalyzerOptions(heuristic_replimit);
|
38 |
|
39 |
|
40 | let regExp = null;
|
41 |
|
42 | if (re instanceof RegExp) {
|
43 | regExp = re;
|
44 | } else if (typeof re === 'string') {
|
45 | regExp = new RegExp(re);
|
46 | } else {
|
47 | regExp = new RegExp(String(re));
|
48 | }
|
49 |
|
50 | return new Args(regExp, analyzerOptions);
|
51 | }
|
52 |
|
53 | function askAnalyzersIfVulnerable(args) {
|
54 | let analyzerSaysVulnerable = [];
|
55 |
|
56 |
|
57 | let Analyzer;
|
58 | for (Analyzer of analyzerFamily) {
|
59 | try {
|
60 | const analyzer = new Analyzer(args.analyzerOptions);
|
61 | analyzerSaysVulnerable.push(analyzer.isVulnerable(args.regExp));
|
62 | } catch (err) {
|
63 |
|
64 | analyzerSaysVulnerable.push(false);
|
65 | }
|
66 | }
|
67 |
|
68 | return analyzerSaysVulnerable;
|
69 | }
|
70 |
|
71 |
|
72 |
|
73 | module.exports = safeRegex; |
\ | No newline at end of file |