diff options
author | bptato <nincsnevem662@gmail.com> | 2023-09-08 22:31:48 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2023-09-08 22:31:48 +0200 |
commit | 3ff3b01f1b93510ef97b9f8b74f1f05595d4fd4f (patch) | |
tree | 2a004429361c95972de40a5d6c265bce8debf977 | |
parent | 7093bf3badd4777529379ce735894236f4416676 (diff) | |
download | chawan-3ff3b01f1b93510ef97b9f8b74f1f05595d4fd4f.tar.gz |
regex: avoid infinite loop
A capture size of 0 (e.g. |) no longer sends the regex matcher into an infinite loop.
-rw-r--r-- | src/js/regex.nim | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/src/js/regex.nim b/src/js/regex.nim index 157e1fbc..81b73700 100644 --- a/src/js/regex.nim +++ b/src/js/regex.nim @@ -1,4 +1,5 @@ # Interface for QuickJS libregexp. +import unicode import bindings/libregexp import bindings/quickjs @@ -149,7 +150,7 @@ proc exec*(regex: Regex, str: string, start = 0, length = -1, nocaps = false): R assert 0 <= start and start <= length, "Start: " & $start & ", length: " & $length & " str: " & $str let captureCount = lre_get_capture_count(regex.bytecode) - var capture: ptr UncheckedArray[int]= nil + var capture: ptr UncheckedArray[int] = nil if captureCount > 0: let size = sizeof(ptr uint8) * captureCount * 2 capture = cast[ptr UncheckedArray[int]](alloc0(size)) @@ -165,6 +166,7 @@ proc exec*(regex: Regex, str: string, start = 0, length = -1, nocaps = false): R if captureCount == 0 or nocaps: break let cstrAddress = cast[int](cstr) + let ps = start start = capture[1] - cstrAddress for i in 0 ..< captureCount: let s = capture[i * 2] - cstrAddress @@ -172,6 +174,10 @@ proc exec*(regex: Regex, str: string, start = 0, length = -1, nocaps = false): R result.captures.add((s, e)) if (flags and LRE_FLAG_GLOBAL) != 1: break + if start >= str.len: + break + if ps == start: + start += runeLenAt(str, i) if captureCount > 0: dealloc(capture) |