Subject: bug#29613: Debian Bug#883733: grep returns 0 even if there is no match

From: Jim Meyering <[email-masked]>
Date: Fri, 8 Dec 2017 10:38:45 -0800

On Fri, Dec 8, 2017 at 3:11 AM, Santiago R.R. <[email-masked]> wrote:
> Dear grep developers,
>
> I would like to forward the report below, filed by Mathias Pietsch to
> Debian. I don't want to introduce other noise than this:
>
> $ echo 1111111111111 | grep -E '^1?$' ; echo $?
> 1
> $ echo 1111111111111 | grep -E '^(11+)\1+$' ; echo $?
> 1
> $ echo 1111111111111 | grep -E '^(11+)\1+$|^1?$' ; echo $?
> 1111111111111
> 0
>
> Shouldn't the last grep command exit 1 too?
>
> Cheers,
>
>  -- Santiago
>
> ----- Forwarded message from Mathias Pietsch <[email-masked]> -----
>
> Date: Wed, 6 Dec 2017 23:51:52 +0100
> From: Mathias Pietsch <[email-masked]>
> To: Debian Bug Tracking System <[email-masked]>
> Subject: Bug#883733: grep returns 0 even if there is no match
> X-Mailer: reportbug 7.1.7
>
> Package: grep
> Version: 2.27-2
> Severity: normal
> Tags: upstream
>
> when trying to test this famous regexp for matching non-prime numbers
> (^1?$|^(11+?)\1+$) which works fine with 'grep -P', i wondered if it
> also would work without the non-greedy quantifier so egrep or even
> plain grep could use it, and found the following problem e.g., with the
> prime number 13:
>
> $ echo "1111111111111" | grep -E '^(11+)\1+$|^1?$' || echo prime
> 1111111111111
>
> the expected output would have been 'prime' because '1111111111111'
> doesn't match '^1?$' and is also no concatanation of two or more
> '11', two or more '111', ... opposite to the orignal perl-style
> non-greedy version, here the substrings should be tested for a match
> beginning with the longest (13 x '1') down to the shortest ('11').
>
> next i removed the empty line term from the regexp (i.e., the '?' from
> the '^1?$' term):
>
> $ echo "1111111111111" | grep -E '^(11+)\1+$|^1$' || echo prime
> prime
>
> now the result is correct. but since the input in not an empty line,
> using '^(11+)\1+$|^1?$' or '^(11+)\1+$|^1$' should not make any
> difference.
>
> (making the empty line term a separate term '^(11+)\1+$|^1$|^$' doesn't
> change anything. the same is true with using plain grep and
> '^\(11\+\)\1\+$\|^1\?$' or '^\(11\+\)\1\+$\|^1$\|^$'.)
>
> this bug also appears in the original upstream version 3.1
> (http://ftp.gnu.org/gnu/grep/grep-3.1.tar.xz)

Yikes! Thanks for forwarding that.
That is indeed a bug. I think it must be due to a bug in glibc's
regexp code, since that's the matcher that grep uses when there is any
back-reference.