Merge pull request #2502 from def-/pcre

Fix infinite loop in re.findAll
This commit is contained in:
Andreas Rumpf 2015-04-10 01:16:01 +02:00
commit 2b8f8bbf19
2 changed files with 55 additions and 45 deletions

View file

@ -231,6 +231,7 @@ iterator findAll*(s: string, pattern: Regex, start = 0): string =
if res < 0'i32: break if res < 0'i32: break
let a = rawMatches[0] let a = rawMatches[0]
let b = rawMatches[1] let b = rawMatches[1]
if a == b and a == i: break
yield substr(s, int(a), int(b)-1) yield substr(s, int(a), int(b)-1)
i = b i = b
@ -260,9 +261,9 @@ template `=~` *(s: string, pattern: Regex): expr =
## else: ## else:
## echo("syntax error") ## echo("syntax error")
## ##
bind MaxSubPatterns bind MaxSubpatterns
when not declaredInScope(matches): when not declaredInScope(matches):
var matches {.inject.}: array[0..MaxSubpatterns-1, string] var matches {.inject.}: array[MaxSubpatterns, string]
match(s, pattern, matches) match(s, pattern, matches)
# ------------------------- more string handling ------------------------------ # ------------------------- more string handling ------------------------------
@ -320,7 +321,7 @@ proc replacef*(s: string, sub: Regex, by: string): string =
## ##
## "var1<-keykey; val2<-key2key2" ## "var1<-keykey; val2<-key2key2"
result = "" result = ""
var caps: array[0..MaxSubpatterns-1, string] var caps: array[MaxSubpatterns, string]
var prev = 0 var prev = 0
while true: while true:
var match = findBounds(s, sub, caps, prev) var match = findBounds(s, sub, caps, prev)
@ -338,7 +339,7 @@ proc parallelReplace*(s: string, subs: openArray[
## applied in parallel. ## applied in parallel.
result = "" result = ""
var i = 0 var i = 0
var caps: array[0..MaxSubpatterns-1, string] var caps: array[MaxSubpatterns, string]
while i < s.len: while i < s.len:
block searchSubs: block searchSubs:
for j in 0..high(subs): for j in 0..high(subs):
@ -445,7 +446,7 @@ when isMainModule:
assert find("_____abc_______", re"abc") == 5 assert find("_____abc_______", re"abc") == 5
var matches: array[0..5, string] var matches: array[6, string]
if match("abcdefg", re"c(d)ef(g)", matches, 2): if match("abcdefg", re"c(d)ef(g)", matches, 2):
assert matches[0] == "d" assert matches[0] == "d"
assert matches[1] == "g" assert matches[1] == "g"
@ -492,7 +493,7 @@ when isMainModule:
assert("XYZ".match(re"^\d*") == true) assert("XYZ".match(re"^\d*") == true)
block: block:
var matches: array[0..15, string] var matches: array[16, string]
if match("abcdefghijklmnop", re"(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)(m)(n)(o)(p)", matches): if match("abcdefghijklmnop", re"(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)(m)(n)(o)(p)", matches):
for i in 0..matches.high: for i in 0..matches.high:
assert matches[i] == $chr(i + 'a'.ord) assert matches[i] == $chr(i + 'a'.ord)

9
tests/stdlib/treloop.nim Normal file
View file

@ -0,0 +1,9 @@
discard """
output: "@[(, +, 1, 2, )]"
"""
import re
let str = "(+ 1 2)"
var tokenRE = re"""[\s,]*(~@|[\[\]{}()'`~^@]|"(?:\\.|[^\\"])*"|;.*|[^\s\[\]{}('"`,;)]*)"""
echo str.findAll(tokenRE)