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
let a = rawMatches[0]
let b = rawMatches[1]
if a == b and a == i: break
yield substr(s, int(a), int(b)-1)
i = b
@ -260,9 +261,9 @@ template `=~` *(s: string, pattern: Regex): expr =
## else:
## echo("syntax error")
##
bind MaxSubPatterns
bind MaxSubpatterns
when not declaredInScope(matches):
var matches {.inject.}: array[0..MaxSubpatterns-1, string]
var matches {.inject.}: array[MaxSubpatterns, string]
match(s, pattern, matches)
# ------------------------- more string handling ------------------------------
@ -320,7 +321,7 @@ proc replacef*(s: string, sub: Regex, by: string): string =
##
## "var1<-keykey; val2<-key2key2"
result = ""
var caps: array[0..MaxSubpatterns-1, string]
var caps: array[MaxSubpatterns, string]
var prev = 0
while true:
var match = findBounds(s, sub, caps, prev)
@ -338,7 +339,7 @@ proc parallelReplace*(s: string, subs: openArray[
## applied in parallel.
result = ""
var i = 0
var caps: array[0..MaxSubpatterns-1, string]
var caps: array[MaxSubpatterns, string]
while i < s.len:
block searchSubs:
for j in 0..high(subs):
@ -445,7 +446,7 @@ when isMainModule:
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):
assert matches[0] == "d"
assert matches[1] == "g"
@ -492,7 +493,7 @@ when isMainModule:
assert("XYZ".match(re"^\d*") == true)
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):
for i in 0..matches.high:
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)