summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2017-02-08 13:00:11 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2017-02-08 13:01:34 -0800
commit6e4c8728f0e75af57f839625d0bd51b0a02d091e (patch)
treea7591bb81d9f178164879bdd3a3f7bde2278a710
parent6e9836442e63dbbc710d3bfe5e48103aeded4605 (diff)
downloadgrep-6e4c8728f0e75af57f839625d0bd51b0a02d091e.tar.gz
grep: do not mishandle \. in multiple patterns
Problem reported by Lars Wendler (Bug#25655). * NEWS: Document this. * src/grep.c (try_fgrep_pattern): Fix typo that prevented keys from being properly updated. * tests/foad1: Test for the bug.
-rw-r--r--NEWS5
-rw-r--r--src/grep.c15
-rwxr-xr-xtests/foad17
3 files changed, 20 insertions, 7 deletions
diff --git a/NEWS b/NEWS
index 072b1e97..a3248e44 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,11 @@ GNU grep NEWS -*- outline -*-
** Bug fixes
+ grep without -F no longer goes awry when given two or more patterns
+ that contain no special characters other than '\' and also contain a
+ subpattern like '\.' that escapes a character to make it ordinary.
+ [bug introduced in grep 2.28]
+
grep no longer fails to build on PCRE versions before 8.20.
[bug introduced in grep 2.28]
diff --git a/src/grep.c b/src/grep.c
index 81654c3a..74acb0b2 100644
--- a/src/grep.c
+++ b/src/grep.c
@@ -2361,11 +2361,12 @@ try_fgrep_pattern (int matcher, char *keys, size_t *len_p)
size_t len = *len_p;
char *new_keys = xmalloc (len + 1);
char *p = new_keys;
+ char const *q = keys;
mbstate_t mb_state = { 0 };
while (len != 0)
{
- switch (*keys)
+ switch (*q)
{
case '$': case '*': case '.': case '[': case '^':
goto fail;
@@ -2377,7 +2378,7 @@ try_fgrep_pattern (int matcher, char *keys, size_t *len_p)
case '\\':
if (1 < len)
- switch (keys[1])
+ switch (q[1])
{
case '\n':
case 'B': case 'S': case 'W': case'\'': case '<':
@@ -2391,7 +2392,7 @@ try_fgrep_pattern (int matcher, char *keys, size_t *len_p)
goto fail;
/* Fall through. */
default:
- keys++, len--;
+ q++, len--;
break;
}
break;
@@ -2401,20 +2402,20 @@ try_fgrep_pattern (int matcher, char *keys, size_t *len_p)
size_t n;
if (match_icase)
{
- int ni = fgrep_icase_charlen (keys, len, &mb_state);
+ int ni = fgrep_icase_charlen (q, len, &mb_state);
if (ni < 0)
goto fail;
n = ni;
}
else
{
- n = mb_clen (keys, len, &mb_state);
+ n = mb_clen (q, len, &mb_state);
if (MB_LEN_MAX < n)
goto fail;
}
- p = mempcpy (p, keys, n);
- keys += n;
+ p = mempcpy (p, q, n);
+ q += n;
len -= n;
}
}
diff --git a/tests/foad1 b/tests/foad1
index 286c4491..0163f1a1 100755
--- a/tests/foad1
+++ b/tests/foad1
@@ -137,6 +137,13 @@ grep_test "$x2" "$y2" -F -w --color=always bc
grep_test "$x3" "$y3" -E -w --color=always bc
grep_test "$x3" "$y3" -F -w --color=always bc
+# Bug#25655
+grep_test .tar/ .tar/ -e '\.tar' -e '\.tbz'
+grep_test .tar/ .tar/ -o -e '\.tar' -e 'tar'
+grep_test '$*.[^\/' '$*.[^\/' -o -e '\$\*\.\[\^\\' -e abc
+grep_test '$*.[^\/(+?{|/' '$*.[^\/(+?{|/' -o -E \
+ -e '\$\*\.\[\^\\' -e '\(\+\?\{\|'
+
# Skip the rest of the tests - known to fail. TAA.
Exit $failures