Subject: grep --ignore-case --color does not always color the matches

From: Tomasz Dziendzielski <[email-masked]>
Date: Mon, 18 Oct 2021 00:26:41 +0200

Hello,
I did some investigation and it seems the problem with '\a' is not that the output is not colored but that it's printed at all while it should not be. It's being printed even when re_search in EGexecute doesn't return a match. As a result the for loop in print_line_middle is not being run - this means the 'a' output that you see is not from the matched string but from the rest of the line. To fix this I suggest to return NULL from print_line_middle if 'b' variable equals NULL - which means the loop was not executed.

I'm sending the patch with the fix in the attachment.

Best regards,
Tomasz Dziendzielski

From 07805259b9bf3e167847a1cf5308b6c54018b709 Mon Sep 17 00:00:00 2001
From: Tomasz Dziendzielski <[email-masked]>
Date: Sun, 17 Oct 2021 21:47:28 +0200
Subject: [PATCH] grep: Don't print line if matcher returned nothing

It can happen that re_search in EGexecute fails and returns nothing so
for loop in print_line_middle runs zero times but still still returns
trash under `cur` variable, so grep thinks it matched something and then
returns whole line.

Fixes bug 39678. Issue was that second of below commands did not color
the "a" character:
| echo a | grep -i --color '\A'
| echo a | grep -i --color '\a'
but in fact it shouldn't even print it in the first place, since gnulib
regex doesn't match it.

* src/grep.c: print_line_middle: Return NULL if match not found and for
loop not executed

Signed-off-by: Tomasz Dziendzielski <[email-masked]>
---
 src/grep.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/grep.c b/src/grep.c
index a55194cf1aa9072ecc37a13574bc588167ee5d94..b372e3415ccbf6f896039a6d72bd6c3498d8c269 100644
--- a/src/grep.c
+++ b/src/grep.c
@@ -1213,7 +1213,7 @@ print_line_middle (char *beg, char *lim,
   ptrdiff_t match_offset;
   char *cur;
   char *mid = NULL;
-  char *b;
+  char *b = NULL;
 
   for (cur = beg;
        (cur < lim
@@ -1269,6 +1269,8 @@ print_line_middle (char *beg, char *lim,
     cur = lim;
   else if (mid)
     cur = mid;
+  else if (b == NULL)
+    return NULL;
 
   return cur;
 }
-- 
2.33.0