From f34fc0a34ab18d7cb0ff27eacaea43912d797a27 Mon Sep 17 00:00:00 2001
From: Philip Hazel <Philip.Hazel@gmail.com>
Date: Wed, 27 Nov 2024 15:15:45 +0000
Subject: [PATCH] Mend a bug in pcre2grep that caused separator lines to be
 incorrectly inserted in some cases when above/below context lines are
 contiguous. Reported by Alejandro Colomar <alx@kernel.org>. Fixes GitHub
 issue #577.
 
Conflict:adapt context; don't modify ChangeLog; don't use group_separator
because e179a4b8c is not merged
Reference:https://github.com/PCRE2Project/pcre2/commit/f34fc0a34ab18d7cb0ff27eacaea43912d797a27
---
 RunGrepTest         |  7 +++++++
 src/pcre2grep.c     | 19 ++++++++++++++++--
 testdata/grepinput  | 19 ++++++++++++++++++
 testdata/grepoutput | 48 ++++++++++++++++++++++++++++++++++++---------
 4 files changed, 82 insertions(+), 11 deletions(-)
 
diff --git a/RunGrepTest b/RunGrepTest
index 9682c5f..e8ab6e5 100755
--- a/RunGrepTest
+++ b/RunGrepTest
@@ -685,6 +685,13 @@ echo "---------------------------- Test 134 -----------------------------" >>tes
 (cd $srcdir; $valgrind $vjs $pcre2grep -m1 -O '=$x{41}$x423$o{103}$o1045=' 'fox') <$srcdir/testdata/grepinputv >>testtrygrep 2>&1
 echo "RC=$?" >>testtrygrep
 
+echo "---------------------------- Test 160 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -nC3 '^(ert|jkl)' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -n -B4 -A2 '^(ert|dfg)' ./testdata/grepinput) >>testtrygrep
+echo "RC=$?" >>testtrygrep
+
+
 # Now compare the results.
 
 $cf $srcdir/testdata/grepoutput testtrygrep
diff --git a/src/pcre2grep.c b/src/pcre2grep.c
index 72c11bc..7f92f7d 100644
--- a/src/pcre2grep.c
+++ b/src/pcre2grep.c
@@ -2934,12 +2934,15 @@ while (ptr < endptr)
           FWRITE_IGNORE(lastmatchrestart, 1, pp - lastmatchrestart, stdout);
           lastmatchrestart = pp;
           }
+
         if (lastmatchrestart != ptr) hyphenpending = TRUE;
         }
 
-      /* If there were non-contiguous lines printed above, insert hyphens. */
+      /* If hyphenpending is TRUE when there is no "after" context, it means we 
+      are at the start of a new file, having output something from the previous 
+      file. Output a separator if enabled.*/
 
-      if (hyphenpending)
+      else if (hyphenpending)
         {
         fprintf(stdout, "--" STDOUT_NL);
         hyphenpending = FALSE;
@@ -2964,6 +2967,7 @@ while (ptr < endptr)
 
         if (lastmatchnumber > 0 && p > lastmatchrestart && !hyphenprinted)
           fprintf(stdout, "--" STDOUT_NL);
+        hyphenpending = FALSE;
 
         while (p < ptr)
           {
@@ -2977,12 +2981,23 @@ while (ptr < endptr)
           }
         }
 
+      /* If hyphenpending is TRUE here, it was set after outputting some 
+      "after" lines (and there are no "before" lines). */
+
+      else if (hyphenpending)
+        {
+        fprintf(stdout, "--" STDOUT_NL);
+        hyphenpending = FALSE;
+        hyphenprinted = TRUE;
+        }
+
       /* Now print the matching line(s); ensure we set hyphenpending at the end
       of the file if any context lines are being output. */
 
       if (after_context > 0 || before_context > 0)
         endhyphenpending = TRUE;
 
+
       if (printname != NULL) fprintf(stdout, "%s:", printname);
       if (number) fprintf(stdout, "%lu:", linenumber);
 
diff --git a/testdata/grepinput b/testdata/grepinput
index 1e2ceb4..91d3db8 100644
--- a/testdata/grepinput
+++ b/testdata/grepinput
@@ -617,6 +617,25 @@ match 5:
 Rhubarb
 Custard Tart
 
+zxc
+cvb
+bnm
+asd
+qwe
+ert
+tyu
+uio
+ggg
+asd
+dfg
+ghj
+jkl
+abc
+def
+ghi
+xyz
+
+
 PUT NEW DATA ABOVE THIS LINE.
 =============================
 
diff --git a/testdata/grepoutput b/testdata/grepoutput
index 66af4cf..ca52d8b 100644
--- a/testdata/grepoutput
+++ b/testdata/grepoutput
@@ -10,7 +10,7 @@ RC=0
 7:PATTERN at the start of a line.
 8:In the middle of a line, PATTERN appears.
 10:This pattern is in lower case.
-623:Check up on PATTERN near the end.
+642:Check up on PATTERN near the end.
 RC=0
 ---------------------------- Test 4 ------------------------------
 4
@@ -19,7 +19,7 @@ RC=0
 ./testdata/grepinput:7:PATTERN at the start of a line.
 ./testdata/grepinput:8:In the middle of a line, PATTERN appears.
 ./testdata/grepinput:10:This pattern is in lower case.
-./testdata/grepinput:623:Check up on PATTERN near the end.
+./testdata/grepinput:642:Check up on PATTERN near the end.
 ./testdata/grepinputx:3:Here is the pattern again.
 ./testdata/grepinputx:5:Pattern
 ./testdata/grepinputx:42:This line contains pattern not on a line by itself.
@@ -28,7 +28,7 @@ RC=0
 7:PATTERN at the start of a line.
 8:In the middle of a line, PATTERN appears.
 10:This pattern is in lower case.
-623:Check up on PATTERN near the end.
+642:Check up on PATTERN near the end.
 3:Here is the pattern again.
 5:Pattern
 42:This line contains pattern not on a line by itself.
@@ -104,6 +104,7 @@ pcre2grep: Error in command-line regex at offset 4: quantifier does not follow a
 RC=2
 ---------------------------- Test 16 -----------------------------
 pcre2grep: Failed to open ./testdata/nonexistfile: No such file or directory
+./testdata/grepinput:abc
 RC=2
 ---------------------------- Test 17 -----------------------------
 features should be added at the end, because some of the tests involve the
@@ -324,10 +325,10 @@ RC=0
 ./testdata/grepinput-9-
 ./testdata/grepinput:10:This pattern is in lower case.
 --
-./testdata/grepinput-620-PUT NEW DATA ABOVE THIS LINE.
-./testdata/grepinput-621-=============================
-./testdata/grepinput-622-
-./testdata/grepinput:623:Check up on PATTERN near the end.
+./testdata/grepinput-639-PUT NEW DATA ABOVE THIS LINE.
+./testdata/grepinput-640-=============================
+./testdata/grepinput-641-
+./testdata/grepinput:642:Check up on PATTERN near the end.
 --
 ./testdata/grepinputx-1-This is a second file of input for the pcregrep tests.
 ./testdata/grepinputx-2-
@@ -349,8 +350,8 @@ RC=0
 ./testdata/grepinput-12-Here follows a whole lot of stuff that makes the file over 24KiB long.
 ./testdata/grepinput-13-
 --
-./testdata/grepinput:623:Check up on PATTERN near the end.
-./testdata/grepinput-624-This is the last line of this file.
+./testdata/grepinput:642:Check up on PATTERN near the end.
+./testdata/grepinput-643-This is the last line of this file.
 --
 ./testdata/grepinputx:3:Here is the pattern again.
 ./testdata/grepinputx-4-
@@ -991,3 +992,32 @@ RC=0
 ---------------------------- Test 134 -----------------------------
 =AB3CD5=
 RC=0
+---------------------------- Test 160 -----------------------------
+622-bnm
+623-asd
+624-qwe
+625:ert
+626-tyu
+627-uio
+628-ggg
+629-asd
+630-dfg
+631-ghj
+632:jkl
+633-abc
+634-def
+635-ghi
+RC=0
+621-cvb
+622-bnm
+623-asd
+624-qwe
+625:ert
+626-tyu
+627-uio
+628-ggg
+629-asd
+630:dfg
+631-ghj
+632-jkl
+RC=0
-- 
2.23.0
