grep: fix -w match if first match isn't a word, but second is. Closes 4520
authorDenys Vlasenko <vda.linux@googlemail.com>
Thu, 27 Feb 2014 13:56:12 +0000 (14:56 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Thu, 27 Feb 2014 13:56:12 +0000 (14:56 +0100)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
findutils/grep.c
testsuite/grep.tests

index 76859464fbaf7e47ae44cb887d26403467c2faf5..f1b6dc694f41d983e6601c7c5bdd0829ec0ed479 100644 (file)
@@ -418,13 +418,15 @@ static int grep_file(FILE *file)
                                                found = 1;
                                        } else {
                                                char c = ' ';
-                                               if (match_at > line || gl->matched_range.rm_so != 0)
+                                               if (match_at > line || gl->matched_range.rm_so != 0) {
                                                        c = match_at[gl->matched_range.rm_so - 1];
+                                               }
                                                if (!isalnum(c) && c != '_') {
                                                        c = match_at[gl->matched_range.rm_eo];
-                                                       if (!c || (!isalnum(c) && c != '_')) {
-                                                               found = 1;
-                                                       } else {
+                                               }
+                                               if (!isalnum(c) && c != '_') {
+                                                       found = 1;
+                                               } else {
                        /*
                         * Why check gl->matched_range.rm_eo?
                         * Zero-length match makes -w skip the line:
@@ -433,18 +435,17 @@ static int grep_file(FILE *file)
                         * Without such check, we can loop forever.
                         */
 #if !ENABLE_EXTRA_COMPAT
-                                                               if (gl->matched_range.rm_eo != 0) {
-                                                                       match_at += gl->matched_range.rm_eo;
-                                                                       match_flg |= REG_NOTBOL;
-                                                                       goto opt_w_again;
-                                                               }
+                                                       if (gl->matched_range.rm_eo != 0) {
+                                                               match_at += gl->matched_range.rm_eo;
+                                                               match_flg |= REG_NOTBOL;
+                                                               goto opt_w_again;
+                                                       }
 #else
-                                                               if (gl->matched_range.rm_eo > start_pos) {
-                                                                       start_pos = gl->matched_range.rm_eo;
-                                                                       goto opt_w_again;
-                                                               }
-#endif
+                                                       if (gl->matched_range.rm_eo > start_pos) {
+                                                               start_pos = gl->matched_range.rm_eo;
+                                                               goto opt_w_again;
                                                        }
+#endif
                                                }
                                        }
                                }
index 74b0eb63f39317796dddc9419cf40af880f7a49c..323b3849dea4982fad70f5de458a7daf57fc676a 100755 (executable)
@@ -165,6 +165,12 @@ testing "grep -w word doesn't match wordword" \
        "wordword\n" \
        ""
 
+testing "grep -w word match second word" \
+       "grep -w word input" \
+       "bword,word\n""wordb,word\n""bwordb,word\n" \
+       "bword,word\n""wordb,word\n""bwordb,word\n" \
+       ""
+
 # testing "test name" "commands" "expected result" "file input" "stdin"
 #   file input will be file called "input"
 #   test can create a file "actual" instead of writing to stdout