The sed command in busybox 1.0.0-pre8 loses leading whitespace
in 'a' command ('i' and 'c' commands are also affected). A
patch to fix this is attached at the end of this message.
The following is a transcript that reproduces the problem. The
first run uses busybox 1.0.0-pre3 as "/bin/sed" command, which
gets the expected result. Later in the test, /bin/sed symlink
is changed to point at busybox 1.0.0-pre8 and the test script is
run again, which shows the failure.
=== reproduction recipe ===
* Part 1. Use busybox 1.0.0-pre3 as sed; this works.
root# cd /tmp
root# cat 1.sh
#!/bin/sh
cd /tmp
rm -f ipsec.conf ipsec.conf+
cat >ipsec.conf <<\EOF
version 2.0
config setup
klipsdebug=none
plutodebug=none
plutostderrlog=/dev/null
conn %default
keyingtries=1
...
EOF
sed -e '/^config setup/a\
nat_traversal=yes' ipsec.conf >ipsec.conf+
mv -f ipsec.conf+ ipsec.conf
root# sh -x 1.sh
+ cd /tmp
+ rm -f ipsec.conf ipsec.conf+
+ cat
+ sed -e /^config setup/a\
nat_traversal=yes ipsec.conf
+ mv -f ipsec.conf+ ipsec.conf
root# cat ipsec.conf
version 2.0
config setup
nat_traversal=yes
klipsdebug=none
plutodebug=none
plutostderrlog=/dev/null
conn %default
keyingtries=1
...
root# sed --version
sed: invalid option -- -
BusyBox v1.00-pre3 (2004.02.26-18:47+0000) multi-call binary
Usage: sed [-nef] pattern [files...]
* Part 2. Continuing from the above, use busybox 1.0.0-pre8
as sed; this fails.
root# ln -s busybox-pre8 /bin/sed-8
root# mv /bin/sed-8 /bin/sed
root# sed --version
This is not GNU sed version 4.0
root# sed --
BusyBox v1.00-pre8 (2004.03.30-02:44+0000) multi-call binary
Usage: sed [-nef] pattern [files...]
root# sh -x 1.sh
+ cd /tmp
+ rm -f ipsec.conf ipsec.conf+
+ cat
+ sed -e /^config setup/a\
nat_traversal=yes ipsec.conf
+ mv -f ipsec.conf+ ipsec.conf
root# cat ipsec.conf
version 2.0
config setup
nat_traversal=yes
klipsdebug=none
plutodebug=none
plutostderrlog=/dev/null
conn %default
keyingtries=1
...
root#
=== reproduction recipe ends here ===
This problem was introduced in 1.0.0-pre4. The problem is that
the command argument parsing code strips leading whitespaces too
aggressively. When running the above example, the piece of code
in question gets "\n\tnat_traversal=yes" as its argument in
cmdstr variable (shown part in the following patch). What it
needs to do at this point is to strip the first newline and
nothing else, but it instead strips all the leading whitespaces
at the beginning of the string, thus losing the tab character.
The following patch fixes this.
While building glibc with busybox as part of the development environment, I
found a bug in glibc's regexec can throw sed into an endless loop. This
fixes it. Should I put an #ifdef around it or something? (Note, this patch
also contains the "this is not gnu sed 4.0" hack I posted earlier, which is
also needed to build glibc...)
Moving on to building diffutils, busybox sed needs this patch to get
past the first problem. (Passing it a multi-line command line argument
with -e works, but if you don't use -e it doesn't break up the multiple
lines...)
echo fooba | ./busybox sed -n 's/foo//;s/bar/found/p'
I really need to start adding these tests to the testsuite.
keep the substituted and altered flags seperate
If a label isnt specified, jump to end of script, not the last command
in the script.
Print an error and exit if you try and jump to a non-existant label
Works for the following testcase
# cat strings
a
b
c
d
e
f
g
# cat strings | ./busybox sed -n '/d/b;p'
a
b
c
e
f
g
Fixed a memory leak in add_cmd/add_cmd_str by moving the allocation
of sed_cmd down to where it's actually first needed.
In get_address, if index_of_next_unescaped_regexp_delim ever failed, we
wouldn't notice because the return value was added to idx, which was
already guaranteed to be > 0. (This is buried in the changes made when
I redid get_address to be based on pointer arithmetic, because all the tests
were gratuitously dereferencing with a constant zero, which wasn't obvious.)
Comment in parse_regex_delim was wrong: 's' and 'y' both call it.
The reason "sed_cmd->num_backrefs = 0;" isn't needed is that sed_cmd was
allocated with cmalloc, which zeroes memory.
Different handling of space after \ in i...
Different handling of pattern "s/a/b s/c/d"
Cool, resursive reads don't cause a crash. :)
Fixed "sed -f blah filename - < filename" since GNU sed was handling
both - and filenames on the same line. (You can even list - more than
once, although it's immediate EOF...)
the command.
# cat strings
a
b
c
d
e
f
g
# ./busybox sed '1,2d;4,$d' <strings
c
# ./busybox sed '4,$d;1,2d' <strings
# sed '4,$d;1,2d' <strings
c
# sed '1,2d;4,$d' <strings
c
- Fixed bug where you couldn't use two addresses for a 'c' cmd
- Moved the do_sed_cmd function into process_file to simplify some things
- Reduced a buncha lines of code in the process