Skip to content

Empty pattern with -v plus -w/-x selects nothing instead of the non-matching lines #65

Description

@sylvestre

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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions