Skip to content

wrong exit code for -o -v with a zero-width match on an empty line (related to #18) #28

@sylvestre

Description

@sylvestre

When -o (only-matching) and -v (invert) are combined with a pattern whose only match on some line is zero-width (e.g. $, x*), and that line is empty, uu_grep treats the empty line as not matching. -v then selects it, so uu_grep reports a selection and exits 0. GNU matches the zero-width pattern on the empty line (so -v does not select it) and exits 1.

Found by the differential fuzzer (fuzz_grep). This shares its root with #18 (zero-length matches are dropped before they can mark a line as matched), but manifests through the -o/-v path and the exit code rather than -w/-x.

Input is a, an empty line, b — the pattern $ matches the end of all three lines.

Rust (incorrect)

$ printf 'a\n\nb\n' | ./target/release/grep -e '$' -v -o
# Output: (none)
# Exit code: 0

GNU (correct)

$ printf 'a\n\nb\n' | LC_ALL=C /usr/bin/grep -e '$' -v -o
# Output: (none)
# Exit code: 1

Same with x* instead of $. Controls that agree: without -o (grep '$' -v) both exit 1; without the empty line (printf 'a\nb\n') both exit 1; a plain count grep '$' -c is 3 in both (so the empty line does match in plain mode — only the -o path mishandles it).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    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