re2js 2.6.1 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@
2
2
  * re2js
3
3
  * RE2JS is the JavaScript port of RE2, a regular expression engine that provides linear time matching
4
4
  *
5
- * @version v2.6.1
5
+ * @version v2.7.0
6
6
  * @author Oleksii Vasyliev
7
7
  * @homepage https://github.com/le0pard/re2js#readme
8
8
  * @repository github:le0pard/re2js
@@ -2159,9 +2159,9 @@
2159
2159
  case Inst.NOP:
2160
2160
  return `nop -> ${this.out}`;
2161
2161
  case Inst.LB_WRITE:
2162
- return `lbwrite ${this.lb} -> ${this.out}`;
2162
+ return `lbwrite ${this.arg} -> ${this.out}`;
2163
2163
  case Inst.LB_CHECK:
2164
- return `lbcheck ${this.lb} -> ${this.out}, ${this.arg}`;
2164
+ return `lbcheck ${this.arg} -> ${this.out}`;
2165
2165
  case Inst.RUNE:
2166
2166
  if (this.runes === null) {
2167
2167
  return 'rune <null>';
@@ -2600,17 +2600,17 @@
2600
2600
  continue;
2601
2601
  }
2602
2602
  case Inst.LB_WRITE:
2603
- this.lbTable[Math.abs(inst.lb)] = pos;
2603
+ this.lbTable[Math.abs(inst.arg)] = pos;
2604
2604
  pc = inst.out;
2605
2605
  continue;
2606
2606
  case Inst.LB_CHECK:
2607
- if (inst.lb > 0) {
2607
+ if (inst.arg > 0) {
2608
2608
  // Positive Lookbehind
2609
- if (this.lbTable[inst.lb] === pos) {
2609
+ if (this.lbTable[inst.arg] === pos) {
2610
2610
  pc = inst.out; // Flattened tail recursion
2611
2611
  continue;
2612
2612
  }
2613
- } else if (this.lbTable[-inst.lb] !== pos) {
2613
+ } else if (this.lbTable[-inst.arg] !== pos) {
2614
2614
  // Negative Lookbehind
2615
2615
  pc = inst.out; // Flattened tail recursion
2616
2616
  continue;
@@ -4690,7 +4690,7 @@
4690
4690
  }
4691
4691
  lookBehind(a, lb) {
4692
4692
  const id = this.newInst(Inst.LB_WRITE);
4693
- this.prog.getInst(id.i).lb = lb;
4693
+ this.prog.getInst(id.i).arg = lb;
4694
4694
 
4695
4695
  // Create the prefix wildcard `.*` for the lookbehind automaton
4696
4696
  const any = this.rune(Compiler.ANY_RUNE(), 0);
@@ -4698,7 +4698,7 @@
4698
4698
  const lbAutomaton = this.cat(dotStar, a);
4699
4699
  this.prog.patch(lbAutomaton.out, id.i);
4700
4700
  const checkId = this.newInst(Inst.LB_CHECK);
4701
- this.prog.getInst(checkId.i).lb = lb;
4701
+ this.prog.getInst(checkId.i).arg = lb;
4702
4702
 
4703
4703
  // Save the starting point of this lookbehind automaton
4704
4704
  this.prog.lbStarts.push(lbAutomaton.i);
@@ -5473,6 +5473,7 @@
5473
5473
  static ERR_UNEXPECTED_PAREN = 'unexpected )';
5474
5474
  static ERR_NESTING_DEPTH = 'expression nests too deeply';
5475
5475
  static ERR_LARGE = 'expression too large';
5476
+ static ERR_INVALID_CAPTURE_IN_LOOKBEHIND = 'invalid capture in lookbehind';
5476
5477
 
5477
5478
  // maxHeight is the maximum height of a regexp parse tree.
5478
5479
  // It is somewhat arbitrarily chosen, but the idea is to be large enough
@@ -5876,6 +5877,18 @@
5876
5877
  }
5877
5878
  return x;
5878
5879
  }
5880
+
5881
+ // recursively check for captures
5882
+ static hasCapture(re) {
5883
+ if (re === null) return false;
5884
+ if (re.op === Regexp.Op.CAPTURE) return true;
5885
+ if (re.subs) {
5886
+ for (let sub of re.subs) {
5887
+ if (Parser.hasCapture(sub)) return true;
5888
+ }
5889
+ }
5890
+ return false;
5891
+ }
5879
5892
  constructor(wholeRegexp, flags = 0) {
5880
5893
  this.wholeRegexp = wholeRegexp;
5881
5894
  // Flags control the behavior of the parser and record information about
@@ -6559,7 +6572,7 @@
6559
6572
  case 1:
6560
6573
  // Impossible but handle.
6561
6574
  re.op = Regexp.Op.EMPTY_MATCH;
6562
- re.subs = null;
6575
+ re.subs = Regexp.emptySubs();
6563
6576
  break;
6564
6577
  case 2:
6565
6578
  {
@@ -7010,6 +7023,9 @@
7010
7023
 
7011
7024
  // Handle lookbehinds
7012
7025
  if (re2.lb !== 0) {
7026
+ if (Parser.hasCapture(re1)) {
7027
+ throw new RE2JSSyntaxException(Parser.ERR_INVALID_CAPTURE_IN_LOOKBEHIND, this.wholeRegexp);
7028
+ }
7013
7029
  if (re2.lb > 0) {
7014
7030
  re2.op = Regexp.Op.PLB;
7015
7031
  } else {