When text is inserted by insertLine() the lines following the
insertion are moved down and the insertion point is made the new
current line. To avoid too much scanning of the linked list of
lines setCurNum() may use the position of the old current line to
determine the location of the new current line.
If the insertion point is before the old current line in the file
the latter will have been moved down, so its line pointer needs to
be adjusted.
function old new delta
insertLine 162 180 +18
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 18/0) Total: 18 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Currently vi assumes that the edit buffer ends in a newline. This may
not be the case. For example:
$ printf test > test
$ vi test
<press 'o'>
We fix this by inserting a newline to the end during initialization.
Signed-off-by: Petja Patjas <pp01415943@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Something is fishy with constrcts like "3==v=3" in gawk,
they should not work, but do. Ignore those for now.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
function old new delta
evaluate 3377 3385 +8
Fixes https://bugs.busybox.net/show_bug.cgi?id=15865
Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
A 32-bit build of BusyBox using clang segfaulted in the test
"awk assign while assign". Specifically, on line 7 of the test
input where the adjustment of the L.v pointer when the Fields
array was reallocated
L.v += Fields - old_Fields_ptr;
was out by 4 bytes.
Rearrange to code so both gcc and clang generate code that works.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
sed would currently not error if write failed when modifying a file.
This can be reproduced with the following 'script':
$ sudo mount -t tmpfs tmpfs -o size=1M /tmp/m
$ sudo chmod 777 /tmp/m
$ echo foo > /tmp/m/foo
$ dd if=/dev/zero of=/tmp/m/fill bs=4k
dd: error writing '/tmp/m/fill': No space left on device
256+0 records in
255+0 records out
1044480 bytes (1.0 MB, 1020 KiB) copied, 0.00234567 s, 445 MB/s
$ busybox sed -i -e 's/.*/bar/' /tmp/m/foo
$ echo $?
0
$ cat /tmp/m/foo
<empty>
new behaviour:
$ echo foo > /tmp/m/foo
$ ./busybox sed -i -e 's/.*/bar/' /tmp/m/foo
sed: write error
$ echo $?
4
$ cat /tmp/m/foo
foo
function old new delta
sed_main 754 801 +47
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 47/0) Total: 47 bytes
text data bss dec hex filename
75727 2510 1552 79789 137ad busybox_old
75774 2510 1552 79836 137dc busybox_unstripped
Signed-off-by: Dominique Martinet <dominique.martinet@atmark-techno.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Patch by M Rubon <rubonmtz@gmail.com>:
Busybox awk handles references to empty (not provided in the input)
fields differently during the first line of input, as compared to
subsequent lines.
$ (echo a ; echo b) | awk '$2 != 0' #wrong
b
No field $2 value is provided in the input. When awk references field
$2 for the "a" line, it is seen to have a different behaviour than
when it is referenced for the "b" line.
Problem in BusyBox v1.36.1 embedded in OpenWrt 23.05.0
Same problem also in 21.02 versions of OpenWrt
Same problem in BusyBox v1.37.0.git
I get the correct expected output from Ubuntu gawk and Debian mawk,
and from my fix.
will@dev:~$ (echo a ; echo b) | awk '$2 != 0' #correct
a
b
will@dev:~/busybox$ (echo a ; echo b ) | ./busybox awk '$2 != 0' #fixed
a
b
I built and poked into the source code at editors/awk.c The function
fsrealloc(int size) is core to allocating, initializing, reallocating,
and reinitializing fields, both real input line fields and imaginary
fields that the script references but do not exist in the input.
When fsrealloc() needs more field space than it has previously
allocated, it initializes those new fields differently than how they
are later reinitialized for the next input line. This works fine for
fields defined in the input, like $1, but does not work the first time
when there is no input for that field (e.g. field $99)
My one-line fix simply makes the initialization and clrvar()
reinitialization use the same value for .type. I am not sure if there
are regression tests to run, but I have not done those.
I'm not sure if I understand why clrvar() is not setting .type to a
default constant value, but in any case I have left that untouched.
function old new delta
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/0 up/down: 0/0) Total: 0 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Since we take its address, the variable lives on stack (not a GPR).
Thus, nothing is improved by caching it.
function old new delta
awk_getline 642 639 -3
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The memcpy invocations in the subCommand function, modified by this
commit, previously used memcpy with overlapping memory regions. This is
undefined behavior. On Alpine Linux, it causes BusyBox ed to crash since
we compile BusyBox with -D_FORTIFY_SOURCE=2 and our fortify-headers
implementation catches this source of undefined behavior [0]. The issue
can only be triggered if the replacement string is the same size or
shorter than the old string.
Looking at the code, it seems to me that a memmove(3) is what was
actually intended here, this commit modifies the code accordingly.
[0]: https://gitlab.alpinelinux.org/alpine/aports/-/issues/13504
Signed-off-by: Sören Tempel <soeren+git@soeren-tempel.net>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Busybox vi provides the 'ZZ' command to save and close
the similar 'ZQ' command just exits without saving.
function old new delta
do_cmd 4222 4244 +22
Signed-off-by: Grob Grobmann <grobgrobmann@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
fixes https://bugs.busybox.net/show_bug.cgi?id=14781
function old new delta
evaluate 3343 3357 +14
Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
When the 'cc' command is invoked with autoindent enabled it
should use the indent of the first line being changed.
The size of the indent has to be established before char_insert()
is called as the lines being changed are deleted. Introduce a
new global variable, newindent, to handle this. The indentcol
global is now effectively a static variable in char_insert().
function old new delta
do_cmd 4247 4308 +61
vi_main 416 422 +6
char_insert 891 875 -16
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 67/-16) Total: 51 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Suppose autoindent is enabled and we have a line with an initial
tab where we want to split the words onto separate lines:
split the words
One way to do this is with the sequence 'f r<CR>;r<CR>', but in
BusyBox vi the result is:
split
he
words
This is a regression introduced by commit 9659a8db1 (vi: remove
autoindent from otherwise empty lines). The amount of indentation
is being recorded when the 'r' command inserts a newline but
isn't subsequently reset. A fix is to only record the indent
when in insert or replace mode. Proper handling of the 'o' and
'O' commands then requires them to switch to insert mode before
calling char_insert() to insert a newline.
function old new delta
char_insert 884 891 +7
do_cmd 4243 4247 +4
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 11/0) Total: 11 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Colon and search commands are entered on the status line. Since
the cursor position wasn't being tracked backspacing over a tab
resulted in a mismatch between the actual and apparent content
of the command.
function old new delta
get_input_line 178 180 +2
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 2/0) Total: 2 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
In replace mode ('R' command) the backspace character should get
special treatment:
- backspace only goes back to the start of the replacement;
- backspacing over replaced characters restores the original text.
Prior to this commit BusyBox vi deleted the characters both before
and after the cursor in replace mode.
function old new delta
undo_pop - 235 +235
char_insert 858 884 +26
indicate_error 81 84 +3
find_range 654 657 +3
static.text_yank 77 79 +2
do_cmd 4486 4243 -243
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 4/1 up/down: 269/-243) Total: 26 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
In order to improve compatibility with GNU cmp add support for long
options to busybox cmp.
function old new delta
static.cmp_longopts - 36 +36
cmp_main 589 594 +5
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/0 up/down: 41/0) Total: 41 bytes
Signed-off-by: Walter Lozano <walter.lozano@collabora.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Apart from the -p option, POSIX also mandates an -s option which
suppresses the output of byte counts for the e, E, r, and w command.
From these commands, Busybox ed presently only implements the r and w
commands. This commit ensures that these two command do not output any
bytes counts when the -s option is passed. The shell escape command,
also effected by the -s option, is not implemented by Busybox at the
moment.
function old new delta
packed_usage 34096 34115 +19
doCommands 1887 1900 +13
readLines 388 397 +9
.rodata 104196 104200 +4
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/0 up/down: 45/0) Total: 45 bytes
Signed-off-by: Sören Tempel <soeren+git@soeren-tempel.net>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
It is perfectly valid to start a regex with ^ and have other patterns
with \| that can match more than once, e.g. the following example
should print ca, as illustrated with gnu sed:
$ echo 'abca' | sed -e 's/^a\|b//g'
ca
busybox before patch:
$ echo 'abca' | busybox sed -e 's/^a\|b//g'
bca
busybox after patch:
$ echo 'abca' | ./busybox sed -e 's/^a\|b//g'
ca
regcomp handles ^ perfectly well as illustrated with the second 'a' that
did not match in the example, we ca leave the non-repeating to it if
appropriate.
The check had been added before using regcomp and was required at the
time (f36635cec6) but no longer makes sense now.
(tested with glibc and musl libc)
function old new delta
add_cmd 1189 1176 -13
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
POSIX.1-2008 mandates the following regarding the read command:
If the read is successful, and -s was not specified, the number
of bytes read shall be written to standard output in the
following format:
"%d\n", <number of bytes read>
This commit aligns the output of busybox ed with POSIX.1-2008 by
removing the file name from the output for the read command.
This slipped through in 4836a0708fd0aaeb82871a3762b40fcf4b61e812.
function old new delta
.rodata 104203 104196 -7
readLines 409 388 -21
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-28) Total: -28 bytes
Signed-off-by: Sören Tempel <soeren+git@soeren-tempel.net>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
POSIX.1-2008 mandates the following regarding the file command-line
argument:
If the file argument is given, ed shall simulate an e command
on the file named by the pathname […]
The specification for the e command mandates the following behaviour
regarding the current line number in POSIX.1-2008:
The current line number shall be set to the address of the last
line of the buffer.
However, without this commit, busybox ed will set the current line
number to 1 if a file is given on the command-line and this file is not
empty (lastNum != 0). This is incorrect and fixed in this commit by not
modifying the current line number in ed_main(). As such, the current
line number will be zero for empty files and otherwise be set to the
address of the last line of the buffer.
function old new delta
ed_main 144 128 -16
Signed-off-by: Sören Tempel <soeren+git@soeren-tempel.net>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The POSIX.1-2008 specification of ed(1) mandates two command-line
options: -p (for specifying a prompt string) and -s (to suppress writing
of byte counts). This commit adds support for the former. Furthermore,
it also changes the default prompt string to an empty string (instead
of ": ") since this is also mandated by POSIX:
-p string Use string as the prompt string when in command mode.
By default, there shall be no prompt string.
function old new delta
ed_main 112 144 +32
packed_usage 34074 34097 +23
doCommands 1889 1887 -2
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 55/-2) Total: 53 bytes
Signed-off-by: Sören Tempel <soeren+git@soeren-tempel.net>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Add support to for "-n" to cmp in order to compare at most n bytes.
function old new delta
cmp_main 552 589 +37
.rodata 104198 104203 +5
packed_usage 34102 34074 -28
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 42/-28) Total: 14 bytes
Signed-off-by: Walter Lozano <walter.lozano@collabora.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>