Blob Blame History Raw
From 0c56b664a73764ed01607f47731c8e4607f478d5 Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Sun, 23 Nov 2008 17:25:57 +0100
Subject: [PATCH] Fix line wrapping in PCRE backend

PCRE can't limit the matching to space between newlines (i.e
[^a] will allways match newline, see pcreposix(3) for details),
therefore whe have to split the buffer into lines and match each
line in the buffer separately.

Original ticket: https://bugzilla.redhat.com/show_bug.cgi?id=324781
---
 src/search.c |   33 ++++++++++++++++++++++++++++-----
 1 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/src/search.c b/src/search.c
index 0b3e0e8..7f5f187 100644
--- a/src/search.c
+++ b/src/search.c
@@ -689,9 +689,32 @@ EXECUTE_FCT(Pexecute)
      is just for performance improvement in pcre_exec.  */
   int sub[300];
 
-  int e = pcre_exec (cre, extra, buf, size,
-		     start_ptr ? (start_ptr - buf) : 0, 0,
-		     sub, sizeof sub / sizeof *sub);
+  char *line_buf = buf;
+  int line_size = 0;
+  int e = 0;
+
+  /* PCRE can't limit the matching to space between newlines (i.e
+     [^a] will allways match newline, see pcreposix(3) for details),
+     therefore whe have to match each line in the buffer separately */
+  do {
+    /* We're not at the of buffer or end of line, get another char */
+    if (line_buf + line_size < buf + size && line_buf[line_size++] != eolbyte) {
+      continue;
+    }
+
+    /* Match the part of buffer that constitutes a line */
+    e = pcre_exec (cre, extra, line_buf, line_size - 1,
+		   start_ptr ? (start_ptr - buf) : 0, 0,
+		   sub, sizeof sub / sizeof *sub);
+
+    /* Don't try other lines if this one matched or returned an error */
+    if (e != PCRE_ERROR_NOMATCH)
+      break;
+
+    /* Wrap up */
+    line_buf += line_size;
+    line_size = 0;
+  } while (line_buf < buf + size);
 
   if (e <= 0)
     {
@@ -710,8 +733,8 @@ EXECUTE_FCT(Pexecute)
   else
     {
       /* Narrow down to the line we've found.  */
-      char const *beg = buf + sub[0];
-      char const *end = buf + sub[1];
+      char const *beg = line_buf + sub[0];
+      char const *end = line_buf + sub[1];
       char const *buflim = buf + size;
       char eol = eolbyte;
       if (!start_ptr)
-- 
1.5.5.1