sed: yet another fix on top of zero length match code
authorDenys Vlasenko <vda.linux@googlemail.com>
Fri, 8 Jun 2012 08:25:31 +0000 (10:25 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Fri, 8 Jun 2012 08:25:31 +0000 (10:25 +0200)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
editors/sed.c
testsuite/sed.tests

index 0fe82f3376e642d21a47ed779b979abe925a3b0a..652aaf5735bac83ec676295aa626c6b0622a2747 100644 (file)
@@ -768,8 +768,11 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line_p)
                 * Second match is NOT replaced!
                 */
                if (prev_match_empty || start != 0 || start != end) {
+                       //dbg("%d %d %d", prev_match_empty, start, end);
                        dbg("inserting replacement at %d in '%s'", start, line);
                        do_subst_w_backrefs(line, sed_cmd->string);
+                       /* Flag that something has changed */
+                       altered = 1;
                } else {
                        dbg("NOT inserting replacement at %d in '%s'", start, line);
                }
@@ -778,16 +781,18 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line_p)
                 * copy verbatim one char after it before attempting more matches
                 */
                prev_match_empty = (start == end);
-               if (prev_match_empty && line[end]) {
-                       pipe_putc(line[end]);
-                       end++;
+               if (prev_match_empty) {
+                       if (!line[end]) {
+                               tried_at_eol = 1;
+                       } else {
+                               pipe_putc(line[end]);
+                               end++;
+                       }
                }
 
                /* Advance past the match */
                dbg("line += %d", end);
                line += end;
-               /* Flag that something has changed */
-               altered = 1;
 
                /* if we're not doing this globally, get out now */
                if (sed_cmd->which_match != 0)
index 12b36ae185cd12bcb1bf88cc775a886ed4e139cb..468565f47081280e9007d6ee80cc5687547900d1 100755 (executable)
@@ -302,10 +302,14 @@ testing "sed zero chars match/replace advances correctly 2" \
        "sed 's [^ .]* x g'" \
        "x x.x\n" "" " a.b\n"
 
-testing "sed zero chars match/replace logic must not falsely trigger here" \
+testing "sed zero chars match/replace logic must not falsely trigger here 1" \
        "sed 's/a/A/g'" \
        "_AAA1AA\n" "" "_aaa1aa\n"
 
+testing "sed zero chars match/replace logic must not falsely trigger here 2" \
+       "sed 's/ *$/_/g'" \
+       "qwerty_\n" "" "qwerty\n"
+
 # testing "description" "commands" "result" "infile" "stdin"
 
 exit $FAILCOUNT