summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/impure/re.nim13
-rw-r--r--tools/nimgrep.nim5
2 files changed, 14 insertions, 4 deletions
diff --git a/lib/impure/re.nim b/lib/impure/re.nim
index 78ea7b002..504d8f22e 100644
--- a/lib/impure/re.nim
+++ b/lib/impure/re.nim
@@ -141,6 +141,10 @@ proc matchOrFind(buf: cstring, pattern: Regex, matches: var openArray[string],
     else: matches[i-1] = ""
   return rawMatches[1] - rawMatches[0]
 
+const MaxReBufSize* = high(cint)
+  ## Maximum PCRE (API 1) buffer start/size equal to `high(cint)`, which even
+  ## for 64-bit systems can be either 2`31`:sup:-1 or 2`63`:sup:-1.
+
 proc findBounds*(buf: cstring, pattern: Regex, matches: var openArray[string],
                  start = 0, bufSize: int): tuple[first, last: int] =
   ## returns the starting position and end position of `pattern` in `buf`
@@ -167,7 +171,8 @@ proc findBounds*(s: string, pattern: Regex, matches: var openArray[string],
   ## and the captured substrings in the array `matches`.
   ## If it does not match, nothing
   ## is written into `matches` and `(-1,0)` is returned.
-  result = findBounds(cstring(s), pattern, matches, start, s.len)
+  result = findBounds(cstring(s), pattern, matches,
+      min(start, MaxReBufSize), min(s.len, MaxReBufSize))
 
 proc findBounds*(buf: cstring, pattern: Regex,
                  matches: var openArray[tuple[first, last: int]],
@@ -197,7 +202,8 @@ proc findBounds*(s: string, pattern: Regex,
   ## and the captured substrings in the array `matches`.
   ## If it does not match, nothing is written into `matches` and
   ## `(-1,0)` is returned.
-  result = findBounds(cstring(s), pattern, matches, start, s.len)
+  result = findBounds(cstring(s), pattern, matches,
+      min(start, MaxReBufSize), min(s.len, MaxReBufSize))
 
 proc findBoundsImpl(buf: cstring, pattern: Regex,
                     start = 0, bufSize = 0, flags = 0): tuple[first, last: int] =
@@ -232,7 +238,8 @@ proc findBounds*(s: string, pattern: Regex,
   ## Note: there is a speed improvement if the matches do not need to be captured.
   runnableExamples:
     assert findBounds("01234abc89", re"abc") == (5,7)
-  result = findBounds(cstring(s), pattern, start, s.len)
+  result = findBounds(cstring(s), pattern,
+      min(start, MaxReBufSize), min(s.len, MaxReBufSize))
 
 proc matchOrFind(buf: cstring, pattern: Regex, start, bufSize: int, flags: cint): cint =
   var
diff --git a/tools/nimgrep.nim b/tools/nimgrep.nim
index a368c40ef..a589cfb14 100644
--- a/tools/nimgrep.nim
+++ b/tools/nimgrep.nim
@@ -649,7 +649,7 @@ template updateCounters(output: Output) =
 proc printInfo(filename:string, output: Output) =
   case output.kind
   of openError:
-    printError("can not open path " & filename & " " & output.msg)
+    printError("cannot open path '" & filename & "': " & output.msg)
   of rejected:
     if optVerbose in options:
       echo "(rejected: ", output.reason, ")"
@@ -719,6 +719,9 @@ iterator searchFile(pattern: Pattern; buffer: string): Output =
                      pre: pre,
                      match: move(curMi))
     i = t.last+1
+  when typeof(pattern) is Regex:
+    if buffer.len > MaxReBufSize:
+      yield Output(kind: openError, msg: "PCRE size limit is " & $MaxReBufSize)
 
 func detectBin(buffer: string): bool =
   for i in 0 ..< min(1024, buffer.len):