parsing an escape sequence. (This mitigates but doesn't fully fix the
the "cursoring around the file deletes data under qemu" bug, presumably due
to "\033[D" being treated as three separate characters.)
This time it resulted in small code changes:
function old new delta
nexpr 820 828 +8
tail_main 1200 1202 +2
wrapf 166 167 +1
parse_mount_options 227 209 -18
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/1 up/down: 11/-18) Total: -7 bytes
watchdog function, presumably to catch infinite loop bugs.
(control-C can do the same thing, and the alarms were too short in
any case.) also, switch to sigsetjmp/siglongjmp in order to allow
repeated use of control-C -- otherwise it works once, then not again.
buffer between commands, not recalculate its length all the time,
and to not reallocate its fixed-length buffer frequently.
fixed the 'c', 'd', and 'y' commands to properly handle both motions
that are just part of a line, and those that are multiline. for
instance, now "c%" and "2cw" work correctly, whether the motions span
lines or not.
added some permissble motions for 'c', 'd', and 'y': namely 'h',
'l', SPACE, BS, and DEL
inetd,syslogd: use safe_read instead of open-coded EINTR handling
syslogd: bail out if you see null read from Unix socket
(should never happen, but if it does, spinning forever
and eating 100% CPU is not a good idea)
trylink: explain how to modify link and drastically decrease amount
of padding (unfortunately, needs hand editing ATM).
*: add ALIGN1 / ALIGN2 to global strings and arrays of bytes and shorts
size saving: 0.5k
* the puzzling message on error is replaced with strerror(errno)
so it should be even more detailed and smaller at the same time.
* merged code in edit_file() and code for ':edit <file>' in colon() into
new func init_text_buffer(). Was horribly duplicate. Moved most of
error/sanity checking to file_insert(). Result is that you get a proper
validation (prevent reading /dev/*) and error messages for ':r <file>'
* renamed 'cfn' to 'current_filename' for improved readability
* merged smallint vi_readonly and readonly into bitfields into
readonly_mode to save space.
* added text_size variable to keep track how big the text buffer is.
This is used to fix a buffer overflow. To reproduce bug:
./busybox vi TODO
:r Makefile
vi segfaults due to no buffer checking is done at all. som redesign is
needed here but i added a check in text_hole_make() to aviod the
segfault at least.
* removed isblnk() and use isblank(3) instead.
* fixed compiler warning by displaying the return code for :!<command>
This makes things bigger than needed but since the patch reduces the
overall size... (see below)
* new func next_tabstop(int) merges some duplicate code. There are more
cuplicode here but i couldnt find a good way to merge them.
* Fix *ANNOYING* placement of cursor on '\t' characters. To reproduce:
echo -e "\thello" > file1
./busybox vi file1
Try to insert some text at the beginning of line. Text will be inserted
but cursor is blinking somewhere else. The patch should make busybox vi
behave more like original vi(m). Costs a few bytes but its worth it
imho.
* new_text() is moved into init_text_buffer()
* the previously added update_ro_status() was moved info file_insert due
to duplication removal mentioned above.
function old new delta
init_text_buffer - 245 +245
file_insert 312 420 +108
next_tabstop - 82 +82
text_hole_make 154 171 +17
do_cmd 5093 5100 +7
static.cmd_mode_indicator - 5 +5
refresh 1248 1253 +5
current_filename - 4 +4
yank_delete 161 164 +3
what_reg 96 99 +3
end_cmd_q 78 81 +3
char_insert 440 442 +2
readonly_mode - 1 +1
vi_readonly 1 - -1
setops 154 153 -1
readonly 1 - -1
vi_setops 4 1 -3
string_insert 161 158 -3
cfn 4 - -4
show_status_line 532 514 -18
readit 519 500 -19
move_to_col 161 138 -23
vi_main 495 433 -62
isblnk 75 - -75
.rodata 4751 4655 -96
edit_file 892 787 -105
new_text 125 - -125
update_ro_status 131 - -131
colon 3848 3667 -181
------------------------------------------------------------------------------
(add/remove: 5/6 grow/shrink: 8/10 up/down: 485/-848) Total: -363
bytes
text data bss dec hex filename
34751 873 4260 39884 9bcc busybox_old
34439 877 4260 39576 9a98 busybox_unstripped
awk: some 'lineno' vars were shorts, made them ints (code got smaller)
awk: rename global t to global ttt. still an awful name, but at least
you can grep for it now.
function old new delta
ttt - 28 +28
mysleep 104 120 +16
readit 408 418 +10
lineno 2 4 +2
parse_program 338 339 +1
evaluate 6446 6445 -1
syntax_error 25 23 -2
next_token 917 915 -2
new_node 26 24 -2
tv 16 8 -8
skip_spaces 68 53 -15
t 28 - -28
rfds 128 - -128
------------------------------------------------------------------------------
(add/remove: 1/2 grow/shrink: 4/6 up/down: 57/-186) Total: -129 bytes
('size' happily displays 0 bytes in data and bss,
but in reality sed.o used 180 bytes of it). Oh well.
function old new delta
pipe_putc 67 76 +9
sed_main 627 633 +6
get_next_line 161 166 +5
bbg 180 - -180
(add/remove: 0/1 grow/shrink: 3/0 up/down: 20/-180) Total: -160 bytes
sed: also make sed -i failure message less cryptic
* do not make backup copy by copying (just retain old file)
* correctly fall back to /etc/passwd if user is not in shadow
* fix bug with overlong passwd entries
* be permissive on some kinds of failures
* reduce stack usage
* code size: -500 bytes
It is impossible to formulate sane ABI based on
size of ulong because it can be 32-bit or 64-bit.
Basically it means that you cannot portably use
more that 32 option chars in one call anyway...
Make it explicit.
things like xasprintf() into xfuncs.c, remove xprint_file_by_name() (it only
had one user), clean up lots of #includes... General cleanup pass. What I've
been doing for the last couple days.
And it conflicts! I've removed httpd.c from this checkin due to somebody else
touching that file. It builds for me. I have to catch a bus. (Now you know
why I'm looking forward to Mercurial.)
fix than his, and shrank the code a bit on top of that so the net size is
smaller, and added a test to the test suite for this case. Plus I cleaned up
the #includes and removed unnecessary "const"s while I was there.
an xterm it's running in. The vi signal behavior would catch and restarts lots
of signals, like SIGHUP, that should just kill the thing. (Leftover behavior
from when it would segfault all the time.) Filtered out the more obviously
bad ones. If it segfaults, we should find and fix the problem.
SIGIOT is not defined in any standard i can find and it seems to be
useless (alias for SIGABRT) on linux. i put it in #ifdef but it's
probably best just to remove it and cut down the size a bit.
A tab is now taken as the end of filename if it's there, but if it isn't
(because the timestamp isn't there) we continue with the existing untruncated
line as the filename.
error: static declaration of 'free_and_close_stuff' follows non-static declaration
Tiny whitespace cleanup while at it,
also make sure that we don't use CONFIG_ anymore.
Rob, hope this is ok w/ you..
be using WEXITSTATUS(), but until I can figure out why the heck that would
want to do (*(int *) &(status)) on the value, I'm happy just fixing the bug we
actually see.
0000474: vi crashes often
problem was that the buffer used for "." command ("last_modifying_cmd")
wasn't being maintined correctly -- the recording code was walking back
over the front of that buffer when a repeatable insert command
included backspacing (e.g. "i\b\b\bfoo"). the fix is to simply
record the backspaces along with the rest of the command.
also, cleaned up start_new_cmd_q() slightly.
correct screen, and bug 215 reports trouble with the status line
on small screens.
with this change a) the status line should always be refreshed
properly, b) the status line is a little shorter than it used to
be ("I" instead of "--INSERT--"), c) the status line will be
truncated if it doesn't fit on the screen, and d) if the screen
is too narrow for an error or transient status message (from
psb() or psbs()), then that message will be followed by a "Hit
Return" prompt. (it wasn't until i did this last bit that the
size grew. with this, these changes add about 150 bytes.)
- pgf
Charlie Brady wrote:
> Here's another awk parsing problem - unary post increment - pre is fine:
>
>bash-2.05a$ echo 2,3 | gawk -F , '{ $2++ }'
>bash-2.05a$ echo 2,3 | /tmp/busybox/busybox awk -F , '{ $2++ }'
>awk: cmd. line:1: Unexpected token
>
Here's a fix for this. There is another problem with constructions like
"print (A+B) ++C", I don't
know whether somebody uses such constructions (fixing both these
problems would require very
serious change in awk code).
This patch implements the 'T' command in sed. This is a GNU extension,
but one of the udev hotplug scripts uses it, so I need it in busybox
anyway.
Includes a test; 'svn add testsuite/sed/sed-branch-conditional-inverted'
after applying.
While the permissions on the temp file are correct to prevent it from being
maliciously mangled by passing strangers, (created with 600, opened O_EXCL,
etc), the permissions on the _directory_ might not be, and we re-open the
file to convert the filehandle to a FILE * (and automatically get an error
message and exit if the directory's read-only or out of space or some such).
This opens a potential race condition if somebody's using dnotify on the
directory, deletes/renames the tempfile, and drops a symlink or something
there. Somebody running sed -i as root in a world writeable directory could
do damage.
I dug up notes on an earlier discussion where we looked at the security
implications of this (unfortunately on the #uclibc channel rather than email;
I don't have a transcript, just notes-to-self) which pointed out that if the
permissions on the directory allow other people's files to be deleted/renamed
then the original file is vulnerable to sabotage anyway. However, there are
two cases that discussion apparently didn't take into account:
1) Using another user's permissions to damage files in other directories you
can't access (standard symlink attack).
2) Reading data another user couldn't otherwise access by having the new file
belong to that other user.
This patch uses fdopen to convert the filehandle into a FILE *, rather than
reopening the file.
and with multiple files SuSv3 says it should only trigger at the end of the
LAST file.
The trivial fix I tried first broke if the last file is empty. Fixing this
properly required restructuring things to create a file list (actually a
FILE * list), and then processing it all in one go. (There's probably a
smaller way to do this, merging with append_list perhaps. But let's get
the behavior correct first.)
Note that editing files in place (-i) needs the _old_ behavior, with $
triggering at the end of each file.
Here's a test of all the things this patch fixed. gnu and busybox seds produce
the same results with this patch, and different without it.
echo -n -e "1one\n1two\n1three" > ../test1
echo -n > ../test2
echo -e "3one\n3two\n3three" > ../test3
sed -n "$ p" ../test1 ../test2 ../test3
sed -n "$ p" ../test1 ../test2
sed -i -n "$ p" ../test1 ../test2 ../test3
to not put a newline at the end (which was backwards, it should have been
hardwired _to_ put a newline at the end, whether or not the input line
ended with a newline). Test case for that:
echo | sed -e '$ctest'
And then this would segfault:
echo | sed -e 'g'
Because pattern_space got freed but the dead pointer was only overwritten
in an if statement that didn't trigger if the hold space was empty. Oops.
While debugging it, I found out that the hold space is persistent between
multiple input files, so I promoted it to a global and added it to the
memory cleanup. The relevant test case (to compare with That Other Sed) is:
echo -n woo > woo
sed -e h -e g woo
echo "fish" | sed -e '/woo/h' -e "izap" -e 's/woo/thingy/' -e '/fish/g' woo -
And somebody gratuitously stuck in a c99 int8_t type for something that's just
a flag, so I grouped the darn ints.
Hi!
I've created a patch to busybox' build system to allow building it in
separate tree in a manner similar to kbuild from kernel version 2.6.
That is, one runs command like
'make O=/build/some/where/for/specific/target/and/options'
and everything is built in this exact directory, provided that it exists.
I understand that applyingc such invasive changes during 'release
candidates' stage of development is at best unwise. So, i'm currently
asking for comments about this patch, starting from whether such thing
is needed at all to whether it coded properly.
'make check' should work now, and one make creates Makefile in build
directory, so one can run 'make' in build directory after that.
One possible caveat is that if we build in some directory other than
source one, the source directory should be 'distclean'ed first.
egor
add sed -r support.
I bumped into a couple of things that want to use extended regular expressions
in sed, and it really isn't that hard to add. Can't say I've extensively
tested it, but it's small and isn't going to break anything that doesn't use
it, so...
Rob
the _destination_ file. (Ah hah! That works _much_ better...) I
implemented the behavior, I just forgot to test this corner of it. My fault,
sorry...
No, gnu sed -i doesn't preverve ownership information. I checked.
Permissions, yes, ownership info, no.
Rob
that the _only_ change to is that gnu sed has been replaced with busybox sed.
And ncurses' install phase hangs. I trace it down, and it's trying to run
gawk. (Insert obligatory doubletake, but this is FSF code we're talking
about, so...)
It turns out gawk shells out to sed, ala "sed -f /tmp/blah file.h". The
/tmp/blah file is basically empty (it contains one character, a newline). So
basically, gawk is using sed as "cat". With gnu sed, it works like cat,
anyway.
With busybox sed, it tests if its command list is empty after parsing the
command line, and if the list is empty it takes the first file argument as a
sed command string, and if that leaves the file list empty it tries to read
the data to operate on from stdin. (Hence the hang, since nothing's coming
in on stdin...)
It _should_ be testing whether there were any instances of -f or -e, not
whether it actually got any commands. Using sed as cat may be kind of
stupid, but it's valid and gawk relies on this behavior.
Here's a patch to fix it, turning a couple of ints into chars in hopes of
saving a bit of the space this adds. Comments?
Rob
This is a bulk spelling fix patch against busybox-1.00-pre10.
If anyone gets a corrupted copy (and cares), let me know and
I will make alternate arrangements.
Erik - please apply.
Authors - please check that I didn't corrupt any meaning.
Package importers - see if any of these changes should be
passed to the upstream authors.
I glossed over lots of sloppy capitalizations, missing apostrophes,
mixed American/British spellings, and German-style compound words.
What is "pretect redefined for test" in cmdedit.c?
Good luck on the 1.00 release!
- Larry
sed -i "/^boo/a fred" ipsec.conf
Which works in gnu sed. (And is _supposed_ to strip all the whitespace before
"fred".)
It also broke:
sed -i -e "/^boo/a \\" -e " fred" ipsec.conf
I.E. there can legally be spaces between the a and the backslash at the end of
the line.
And strangely enough, gnu sed accepts the following syntax as well:
sed -i "/^boo/a \\ fred" ipsec.conf
Which is a way of having the significant whitespace at the start of the line,
all on one line. (But notice that the whitespace BEFORE the slash is still
stripped, as is the slash itself. And notice that the naieve placement of
"\n" there doesn't work, it puts an n at the start of the appended line. The
double slashing is for shell escapes because you could escape the quote, you
see. It's turned into a single backslash. But \n there is _not_ turned into
a newline by the shell. So there.)
This makes all three syntaxes work in my tests. I should probably start
writing better documentation at some point. I posted my current sedtests.py
file to the list, which needs a lot more tests added as well...
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.
Hi All,
I aplogoize for the mistake, but i have just recognized that somehow the
last patch I sent in was wrong, and a '0' was instead of a '-1'. Because
of this, vi does behave the wrong way. So again, it should be the last
patch for vi. This is for pre7.
Hi,
I've noticed the bug also, and here is another patch for it. I hope it'll
not introduce more bugs. Not too nice, but works for me.
Here it is for busybox-1.00-pre6
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...)
Fixes two bugs:
- END block didn't execute after an exit() call
- huge memory consumption and performance degradation on large input
(now performance is comparable to gawk)
the busybox menuconfig triggered my "inacceptable number of spelling mistakes"
upper level, so I decided to make a patch ;-)
I also improved some wording to describe some things in a better way.
Many thanks for an incredible piece of software!
Andreas Mohr, random OSS developer
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