grep: fix -o match with empty string (suggested by Colin Watson <cjwatson@ubuntu...
authorDenys Vlasenko <vda.linux@googlemail.com>
Mon, 23 Aug 2010 00:39:47 +0000 (02:39 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Mon, 23 Aug 2010 00:39:47 +0000 (02:39 +0200)
function                                             old     new   delta
grep_file                                           1216    1251     +35

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
findutils/grep.c
testsuite/grep.tests

index 688ea6ab24a858cef2b9053762b3a0149cd07b11..024f2760985cdb6165ab312db93486ffed20ef46 100644 (file)
@@ -461,15 +461,19 @@ static int grep_file(FILE *file)
                                                if (found)
                                                        print_line(gl->pattern, strlen(gl->pattern), linenum, ':');
                                        } else while (1) {
+                                               unsigned start = gl->matched_range.rm_so;
                                                unsigned end = gl->matched_range.rm_eo;
+                                               unsigned len = end - start;
                                                char old = line[end];
                                                line[end] = '\0';
-                                               print_line(line + gl->matched_range.rm_so,
-                                                               end - gl->matched_range.rm_so,
-                                                               linenum, ':');
+                                               /* Empty match is not printed: try "echo test | grep -o ''" */
+                                               if (len != 0)
+                                                       print_line(line + start, len, linenum, ':');
                                                if (old == '\0')
                                                        break;
                                                line[end] = old;
+                                               if (len == 0)
+                                                       end++;
 #if !ENABLE_EXTRA_COMPAT
                                                if (regexec(&gl->compiled_regex, line + end,
                                                                1, &gl->matched_range, REG_NOTBOL) != 0)
index 520a1840f9e77df938cedbceba2607da23c3287f..ffce033e6e65a8f053297ebbc6f2e0f942104689 100755 (executable)
@@ -98,5 +98,9 @@ testing "grep -o does not loop forever" \
        'grep -o "[^/]*$"' \
        "test\n" \
        "" "/var/test\n"
+testing "grep -o does not loop forever on zero-length match" \
+       'grep -o "" | head -n1' \
+       "" \
+       "" "test\n"
 
 exit $FAILCOUNT