grep - empty pattern with -v plus -w/-x wrongly selects nothing
Found by the differential fuzzer with args
grep ["-e", "", "-v", "-x", "-i", "--null-data", "-E"].
uu_grep short-circuits any -v run with an empty pattern to "no lines selected, exit 1",
on the assumption that an empty pattern matches every line. That assumption holds for plain
matching, but not under -x (whole-line) or -w (word): there the empty pattern matches
only an empty line (-x) or an empty match at a word boundary (-w), so its inversion should
select the non-empty / non-boundary lines. GNU selects them; uu_grep selects nothing.
Reproduction
Rust (incorrect)
$ printf 'abc\ndef\n' | ./target/release/grep -e '' -x -v
# Output: (none)
# Exit code: 1
GNU (correct)
$ printf 'abc\ndef\n' | LC_ALL=C /usr/bin/grep -e '' -x -v
# Output:
# abc
# def
# Exit code: 0
The same happens with -w in place of -x:
$ printf 'abc\n' | ./target/release/grep -e '' -w -v # Rust: nothing, exit 1
$ printf 'abc\n' | LC_ALL=C /usr/bin/grep -e '' -w -v # GNU: "abc", exit 0
Controls that already agree:
- plain
printf 'abc\n' | grep -e '' -v → both select nothing, exit 1 (the short-circuit is
correct here).
- plain
grep -e '' -x (no -v) → both select only the empty line.
So the bug is specific to combining the empty-pattern -v short-circuit with -w/-x. It is
distinct from the existing empty-match word/line report (that one is about the matcher dropping
zero-length matches; the non-inverted -x case now works).
grep - empty pattern with
-vplus-w/-xwrongly selects nothingFound by the differential fuzzer with args
grep ["-e", "", "-v", "-x", "-i", "--null-data", "-E"].uu_grepshort-circuits any-vrun with an empty pattern to "no lines selected, exit 1",on the assumption that an empty pattern matches every line. That assumption holds for plain
matching, but not under
-x(whole-line) or-w(word): there the empty pattern matchesonly an empty line (
-x) or an empty match at a word boundary (-w), so its inversion shouldselect the non-empty / non-boundary lines. GNU selects them;
uu_grepselects nothing.Reproduction
Rust (incorrect)
GNU (correct)
The same happens with
-win place of-x:Controls that already agree:
printf 'abc\n' | grep -e '' -v→ both select nothing, exit 1 (the short-circuit iscorrect here).
grep -e '' -x(no-v) → both select only the empty line.So the bug is specific to combining the empty-pattern
-vshort-circuit with-w/-x. It isdistinct from the existing empty-match word/line report (that one is about the matcher dropping
zero-length matches; the non-inverted
-xcase now works).