From 8132ad2f4ec9b463ed954a302e9e490b549b106a Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Thu, 29 Oct 2015 01:30:58 -0500 Subject: Fix sed bug reported by Isabella Parakiss, where sed -e "/x/c\" -e "y" added an extra newline because the test for whether we have an existing string to append a newline to was checking if struct step had data appended to it, and the /x/ regex is data appended to it. Change test to check for null terminator at ->arg1 offset. --- tests/sed.test | 3 +++ toys/posix/sed.c | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/sed.test b/tests/sed.test index 9f2956f8..56d68fdb 100755 --- a/tests/sed.test +++ b/tests/sed.test @@ -127,6 +127,9 @@ testing "" "sed -e '1a\' -e 'huh'" "meep\nhuh\n" "" "meep" testing "" "sed -f input" "blah\nboom\n" '1a\\\nboom' 'blah' testing "" "sed '1a\ hello'" "merp\nhello\n" "" "merp" + +testing "" "sed -e '/x/c\' -e 'y'" 'y\n' '' 'x\n' + #echo meep | sed/sed -e '1a\' -e 'huh' #echo blah | sed/sed -f <(echo -e "1a\\\\\nboom") #echo merp | sed/sed "1a\\ diff --git a/toys/posix/sed.c b/toys/posix/sed.c index 20975320..9d377cdb 100644 --- a/toys/posix/sed.c +++ b/toys/posix/sed.c @@ -260,7 +260,7 @@ static char *extend_string(char **old, char *new, int oldlen, int newlen) } // An empty regex repeats the previous one -void *get_regex(void *trump, int offset) +static void *get_regex(void *trump, int offset) { if (!offset) { if (!TT.lastregex) error_exit("no previous regex"); @@ -669,6 +669,7 @@ static void do_lines(int fd, char *name, void (*call)(char **pline, long len)) if (fd) fclose(fp); } +// Callback called on each input file static void do_sed(int fd, char *name) { int i = toys.optflags & FLAG_i; @@ -677,7 +678,7 @@ static void do_sed(int fd, char *name) if (i) { struct step *primal; - if (!fd && *name=='-') { + if (!fd && !strcmp(name, "-")) { error_msg("-i on stdin"); return; } @@ -970,7 +971,7 @@ resume_a: // pointers so realloc() moving stuff doesn't break things. Ok to write // \n over NUL terminator because call to extend_string() adds it back. if (!corwin->arg1) corwin->arg1 = reg - (char*)corwin; - else if ((corwin+1) != (void *)reg) *(reg++) = '\n'; + else if (*(corwin->arg1+(char *)corwin)) *(reg++) = '\n'; reg = extend_string((void *)&corwin, line, reg - (char *)corwin, end); // Recopy data to remove escape sequences and handle line continuation. -- cgit v1.2.3