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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions