A repetition operator (?, *, +) at the start of an expression has no preceding atom to repeat. GNU grep treats this leniently: it prints warning: <op> at start of expression to stderr, matches as if the operator were a no-op (so every line is selected), and exits 0. uu_grep rejects the pattern as a hard error and exits 2.
Found by the differential fuzzer (fuzz_grep).
Rust (incorrect)
$ printf 'abc\n' | ./target/release/grep -e '?' -E
# Output (stderr): grep: invalid pattern "?": Oniguruma error: target of repeat operator is not specified
# Exit code: 2
GNU (correct)
$ printf 'abc\n' | LC_ALL=C /usr/bin/grep -e '?' -E
# Output (stderr): grep: warning: ? at start of expression
# Output (stdout): abc
# Exit code: 0
The same divergence occurs for * and + as the leading character (grep -E '*', grep -E '+'): GNU warns and matches every line (exit 0); uu_grep errors (exit 2).
A repetition operator (
?,*,+) at the start of an expression has no preceding atom to repeat. GNU grep treats this leniently: it printswarning: <op> at start of expressionto stderr, matches as if the operator were a no-op (so every line is selected), and exits0.uu_greprejects the pattern as a hard error and exits2.Found by the differential fuzzer (
fuzz_grep).Rust (incorrect)
GNU (correct)
The same divergence occurs for
*and+as the leading character (grep -E '*',grep -E '+'): GNU warns and matches every line (exit 0);uu_greperrors (exit 2).