summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2016-11-19 03:12:56 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2016-11-19 03:14:18 -0800
commit6a3f4e447af3698b1e26337211a587ff54aab99d (patch)
treed18ad8f097ca67a99c5c954f592e975e782fca69
parent575bdb1bc65d0aa73df127ec1bf70ab6ec3db174 (diff)
downloadgrep-6a3f4e447af3698b1e26337211a587ff54aab99d.tar.gz
grep: fix -zxP bug
* NEWS: Document this. * src/pcresearch.c (Pcompile): Search a line at a time if -x is used, since -x uses ^ and $. * tests/pcre: Test this.
-rw-r--r--NEWS6
-rw-r--r--src/pcresearch.c34
-rwxr-xr-xtests/pcre1
3 files changed, 24 insertions, 17 deletions
diff --git a/NEWS b/NEWS
index 978ec555..4972c018 100644
--- a/NEWS
+++ b/NEWS
@@ -10,9 +10,9 @@ GNU grep NEWS -*- outline -*-
>/dev/null" where PROGRAM dies when writing into a broken pipe.
[bug introduced in grep-2.26]
- grep -Pz no longer rejects patterns containing ^ and $, and is
- more cautious about special patterns like (?-m) and (*FAIL).
- [bug introduced in grep-2.23]
+ grep -Pz no longer rejects patterns containing ^ and $, is more
+ cautious about special patterns like (?-m) and (*FAIL), and works
+ when combined with -x. [bug introduced in grep-2.23]
grep -m0 -L PAT FILE now outputs "FILE". [bug introduced in grep-2.5]
diff --git a/src/pcresearch.c b/src/pcresearch.c
index 439945aa..01616c2c 100644
--- a/src/pcresearch.c
+++ b/src/pcresearch.c
@@ -128,22 +128,28 @@ Pcompile (char const *pattern, size_t size)
if (! eolbyte)
{
- bool escaped = false;
- bool after_unescaped_left_bracket = false;
- for (p = pattern; *p; p++)
- if (escaped)
- escaped = after_unescaped_left_bracket = false;
- else
- {
- if (*p == '$' || (*p == '^' && !after_unescaped_left_bracket)
- || (*p == '(' && (p[1] == '?' || p[1] == '*')))
+ bool line_at_a_time = match_lines;
+ if (! line_at_a_time)
+ {
+ bool escaped = false;
+ bool after_unescaped_left_bracket = false;
+ for (p = pattern; *p; p++)
+ if (escaped)
+ escaped = after_unescaped_left_bracket = false;
+ else
{
- flags = (flags & ~ PCRE_MULTILINE) | PCRE_DOLLAR_ENDONLY;
- break;
+ if (*p == '$' || (*p == '^' && !after_unescaped_left_bracket)
+ || (*p == '(' && (p[1] == '?' || p[1] == '*')))
+ {
+ line_at_a_time = true;
+ break;
+ }
+ escaped = *p == '\\';
+ after_unescaped_left_bracket = *p == '[';
}
- escaped = *p == '\\';
- after_unescaped_left_bracket = *p == '[';
- }
+ }
+ if (line_at_a_time)
+ flags = (flags & ~ PCRE_MULTILINE) | PCRE_DOLLAR_ENDONLY;
}
*n = '\0';
diff --git a/tests/pcre b/tests/pcre
index 653ef221..a290099a 100755
--- a/tests/pcre
+++ b/tests/pcre
@@ -17,5 +17,6 @@ echo | grep -zP '\s$' || fail=1
echo '.ab' | returns_ 1 grep -Pwx ab || fail=1
echo x | grep -Pz '[^a]' || fail=1
printf 'x\n\0' | returns_ 1 grep -zP 'x$' || fail=1
+printf 'a\nb\0' | grep -zxP a && fail=1
Exit $fail