Skip to content

Commit 4911e39

Browse files
authored
PS-3239: error on too complex regex pattern (#1)
1 parent ccacf66 commit 4911e39

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

pm/pm.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ import (
55
"fmt"
66
)
77

8-
const EOS = -1
9-
const _UNKNOWN = -2
8+
const (
9+
EOS = -1
10+
_UNKNOWN = -2
11+
maxRecursionLevel = 100000
12+
)
1013

1114
/* Error {{{ */
1215

@@ -524,7 +527,11 @@ func compilePattern(p pattern, ps ...*iptr) []inst {
524527

525528
// Simple recursive virtual machine based on the
526529
// "Regular Expression Matching: the Virtual Machine Approach" (https://swtch.com/~rsc/regexp/regexp2.html)
527-
func recursiveVM(src []byte, insts []inst, pc, sp int, ms ...*MatchData) (bool, int, *MatchData) {
530+
func recursiveVM(src []byte, insts []inst, pc, sp, recLevel int, ms ...*MatchData) (bool, int, *MatchData) {
531+
recLevel++
532+
if recLevel > maxRecursionLevel {
533+
panic(newError(_UNKNOWN, "pattern/input too complex"))
534+
}
528535
var m *MatchData
529536
if len(ms) == 0 {
530537
m = newMatchState()
@@ -549,14 +556,14 @@ redo:
549556
pc = inst.Operand1
550557
goto redo
551558
case opSplit:
552-
if ok, nsp, _ := recursiveVM(src, insts, inst.Operand1, sp, m); ok {
559+
if ok, nsp, _ := recursiveVM(src, insts, inst.Operand1, sp, recLevel, m); ok {
553560
return true, nsp, m
554561
}
555562
pc = inst.Operand2
556563
goto redo
557564
case opSave:
558565
s := m.setCapture(inst.Operand1, sp)
559-
if ok, nsp, _ := recursiveVM(src, insts, pc+1, sp, m); ok {
566+
if ok, nsp, _ := recursiveVM(src, insts, pc+1, sp, recLevel, m); ok {
560567
return true, nsp, m
561568
}
562569
m.restoreCapture(inst.Operand1, s)
@@ -620,7 +627,7 @@ func Find(p string, src []byte, offset, limit int) (matches []*MatchData, err er
620627
insts := compilePattern(pat)
621628
matches = []*MatchData{}
622629
for sp := offset; sp <= len(src); {
623-
ok, nsp, ms := recursiveVM(src, insts, 0, sp)
630+
ok, nsp, ms := recursiveVM(src, insts, 0, sp, 0)
624631
sp++
625632
if ok {
626633
if sp < nsp {

0 commit comments

Comments
 (0)