diff --git a/src/lib.rs b/src/lib.rs index 0f2b63a..af06840 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -255,6 +255,14 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { )); } + // GNU grep's PCRE backend (-P) supports only a single pattern. + if perl_regexp && patterns.len() > 1 { + return Err(USimpleError::new( + 2, + "the -P option only supports a single pattern".to_string(), + )); + } + // Decoded options into enums let regex_mode = if fixed_strings { RegexMode::Fixed diff --git a/tests/test_grep.rs b/tests/test_grep.rs index d061918..e9665ee 100644 --- a/tests/test_grep.rs +++ b/tests/test_grep.rs @@ -170,6 +170,34 @@ fn pcre_features() { .stdout_only("42\n7\n"); } +#[test] +fn perl_regexp_rejects_multiple_patterns() { + // GNU grep's PCRE backend (-P) only supports a single pattern. + // Multiple -e patterns must produce exit 2 and the canonical error message. + // See: https://github.com/uutils/grep/issues/34 + + // Two separate -e flags. + let (_s, mut c) = ucmd(); + c.args(&["-P", "-e", "foo", "-e", "bar"]) + .pipe_in("foo\nbar\n") + .fails_with_code(2) + .stderr_contains("the -P option only supports a single pattern"); + + // A newline inside the pattern string is split into multiple patterns. + let (_s, mut c) = ucmd(); + c.args(&["-P", "-e", "foo\nbar"]) + .pipe_in("foo\nbar\n") + .fails_with_code(2) + .stderr_contains("the -P option only supports a single pattern"); + + // A single pattern with -P must still work normally. + let (_s, mut c) = ucmd(); + c.args(&["-P", "-e", r"\d+"]) + .pipe_in("abc\n42\n") + .succeeds() + .stdout_only("42\n"); +} + #[test] fn posix_character_classes() { let (_s, mut c) = ucmd();