Skip to content

Commit

Permalink
Make regexp execution loop interruptible #1189 (#1440)
Browse files Browse the repository at this point in the history
* Make regexp execution loop interruptible #1189

Uses Thread.currentThread.isInterrupted() so that the interruption flag remains set to true,
we only terminate the RegExp evaluation loop, but other (potentially third-party calling)
code may still have to check for the interrupted flag to stop its execution as well.

I also added a test with a long-running regexp that fails without the interrupt check.

Co-authored-by: Andre Wachsmuth <awa@xima.de>
  • Loading branch information
blutorange and awa-xima committed Apr 27, 2024
1 parent 0f214b9 commit dcd8e05
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 3 deletions.
9 changes: 6 additions & 3 deletions src/org/mozilla/javascript/regexp/NativeRegExp.java
Original file line number Diff line number Diff line change
Expand Up @@ -1857,7 +1857,8 @@ private static int simpleMatch(
return -1;
}

private static boolean executeREBytecode(REGlobalData gData, String input, int end) {
private static boolean executeREBytecode(
Context cx, REGlobalData gData, String input, int end) {
int pc = 0;
byte[] program = gData.regexp.program;
int continuationOp = REOP_END;
Expand Down Expand Up @@ -1887,6 +1888,7 @@ private static boolean executeREBytecode(REGlobalData gData, String input, int e
}

for (; ; ) {
ScriptRuntime.addInstructionCount(cx, 5);

if (reopIsSimple(op)) {
int match = simpleMatch(gData, input, op, program, pc, end, true);
Expand Down Expand Up @@ -2316,6 +2318,7 @@ && simpleMatch(gData, input, op, program, pc, end, false) < 0) {
}

private static boolean matchRegExp(
Context cx,
REGlobalData gData,
RECompiled re,
String input,
Expand Down Expand Up @@ -2369,7 +2372,7 @@ && upcase(matchCh) == upcase((char) anchorCh))) {
for (int j = 0; j < re.parenCount; j++) {
gData.parens[j] = -1L;
}
boolean result = executeREBytecode(gData, input, end);
boolean result = executeREBytecode(cx, gData, input, end);

gData.backTrackStackTop = null;
gData.stateStackTop = null;
Expand Down Expand Up @@ -2403,7 +2406,7 @@ Object executeRegExp(
//
// Call the recursive matcher to do the real work.
//
boolean matches = matchRegExp(gData, re, str, start, end, res.multiline);
boolean matches = matchRegExp(cx, gData, re, str, start, end, res.multiline);
if (!matches) {
if (matchType != PREFIX) return null;
return Undefined.instance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,11 @@ public void forever() {
String source = "for(;;);";
baseCase(source);
}

@Test
public void longRunningRegExp() {
String source =
"/(.*){1,32000}[bc]/.test(\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\");";
baseCase(source);
}
}

0 comments on commit dcd8e05

Please sign in to comment.