summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xcontrib/netbsd-tests/usr.bin/grep/t_grep.sh24
-rw-r--r--usr.bin/grep/util.c27
2 files changed, 48 insertions, 3 deletions
diff --git a/contrib/netbsd-tests/usr.bin/grep/t_grep.sh b/contrib/netbsd-tests/usr.bin/grep/t_grep.sh
index 76058f4..d265e5d 100755
--- a/contrib/netbsd-tests/usr.bin/grep/t_grep.sh
+++ b/contrib/netbsd-tests/usr.bin/grep/t_grep.sh
@@ -93,6 +93,12 @@ word_regexps_body()
{
atf_check -o file:"$(atf_get_srcdir)/d_word_regexps.out" \
grep -w separated $(atf_get_srcdir)/d_input
+
+ # Begin FreeBSD
+ printf "xmatch pmatch\n" > test1
+
+ atf_check -o inline:"pmatch\n" grep -Eow "(match )?pmatch" test1
+ # End FreeBSD
}
atf_test_case begin_end
@@ -439,6 +445,23 @@ grep_sanity_body()
atf_check -o inline:"M\n" grep -o -e "M\{1\}" test2
}
+
+atf_test_case wv_combo_break
+wv_combo_break_head()
+{
+ atf_set "descr" "Check for incorrectly matching lines with both -w and -v flags (PR 218467)"
+}
+wv_combo_break_body()
+{
+ printf "x xx\n" > test1
+ printf "xx x\n" > test2
+
+ atf_check -o file:test1 grep -w "x" test1
+ atf_check -o file:test2 grep -w "x" test2
+
+ atf_check -s exit:1 grep -v -w "x" test1
+ atf_check -s exit:1 grep -v -w "x" test2
+}
# End FreeBSD
atf_init_test_cases()
@@ -467,6 +490,7 @@ atf_init_test_cases()
atf_add_test_case escmap
atf_add_test_case egrep_empty_invalid
atf_add_test_case zerolen
+ atf_add_test_case wv_combo_break
atf_add_test_case fgrep_sanity
atf_add_test_case egrep_sanity
atf_add_test_case grep_sanity
diff --git a/usr.bin/grep/util.c b/usr.bin/grep/util.c
index 8815d4f..dd9a753 100644
--- a/usr.bin/grep/util.c
+++ b/usr.bin/grep/util.c
@@ -305,6 +305,7 @@ procline(struct str *l, int nottext)
unsigned int i;
int c = 0, m = 0, r = 0, lastmatches = 0, leflags = eflags;
int startm = 0;
+ int retry;
/* Initialize to avoid a false positive warning from GCC. */
lastmatch.rm_so = lastmatch.rm_eo = 0;
@@ -313,6 +314,7 @@ procline(struct str *l, int nottext)
while (st <= l->len) {
lastmatches = 0;
startm = m;
+ retry = 0;
if (st > 0)
leflags |= REG_NOTBOL;
/* Loop to compare with all the patterns */
@@ -356,6 +358,17 @@ procline(struct str *l, int nottext)
else if (iswword(wbegin) ||
iswword(wend))
r = REG_NOMATCH;
+ /*
+ * If we're doing whole word matching and we
+ * matched once, then we should try the pattern
+ * again after advancing just past the start of
+ * the earliest match. This allows the pattern
+ * to match later on in the line and possibly
+ * still match a whole word.
+ */
+ if (r == REG_NOMATCH &&
+ (retry == 0 || pmatch.rm_so + 1 < retry))
+ retry = pmatch.rm_so + 1;
}
if (r == 0) {
lastmatches++;
@@ -385,9 +398,14 @@ procline(struct str *l, int nottext)
}
}
- if (vflag) {
- c = !c;
- break;
+ /*
+ * Advance to just past the start of the earliest match, try
+ * again just in case we still have a chance to match later in
+ * the string.
+ */
+ if (lastmatches == 0 && retry > 0) {
+ st = retry;
+ continue;
}
/* One pass if we are not recording matches */
@@ -410,6 +428,9 @@ procline(struct str *l, int nottext)
}
+ if (vflag)
+ c = !c;
+
/* Count the matches if we have a match limit */
if (mflag)
mcount -= c;
OpenPOWER on IntegriCloud