Commit graph

427 commits

Author SHA1 Message Date
Denys Vlasenko
b4cedd4c9a hush: fix several syntax corner cases with function definitions
function                                             old     new   delta
parse_stream                                        3063    3075     +12
done_word                                            777     784      +7
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 19/0)               Total: 19 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-18 14:52:46 +02:00
Denys Vlasenko
3e766dce5f hush: implement <<<here_string syntax
function                                             old     new   delta
setup_heredoc                                        299     351     +52
parse_stream                                        2514    2540     +26
parse_redirect                                       335     351     +16
redir_table                                           40      48      +8
static.setup_redirects                               394     400      +6
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 5/0 up/down: 108/0)             Total: 108 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-15 00:08:11 +02:00
Denys Vlasenko
6cc3380105 hush: undo incorrect change which allows a'b'=c to be assignment
While at it, remove now-unused WORD_IS_KEYWORD

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-14 16:19:58 +02:00
Denys Vlasenko
279371471e hush: move tickquote1.tests to hush-bugs/ - it's a known bug
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-14 05:02:07 +02:00
Denys Vlasenko
d029e80187 hush: remove the is_blank dance
function                                             old     new   delta
parse_stream                                        2566    2524     -42

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-14 04:04:57 +02:00
Denys Vlasenko
1847fee2d4 hush: fix a corner case in "case" stmt, ctx_dsemicolon is in fact unused
function                                             old     new   delta
parse_stream                                        2446    2476     +30
done_word                                            797     800      +3
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 33/0)               Total: 33 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-13 00:51:44 +02:00
Denys Vlasenko
f161bc628f hush: allow nested negation "! ! ! CMD" - bash 5.2.15 allows it
Also, deindent "ch == EOF" code branch in parse_stream()

function                                             old     new   delta
done_word                                            799     797      -2
parse_stream                                        2453    2446      -7
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-9)               Total: -9 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-12 20:29:26 +02:00
Denys Vlasenko
2b0b74e8b4 hush: drop ctx_inverted, use pipe->pi_inverted
function                                             old     new   delta
done_word                                            776     799     +23
parse_stream                                        2456    2453      -3
done_pipe                                            252     242     -10
.rodata                                           105837  105825     -12
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/3 up/down: 23/-25)             Total: -2 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-12 20:29:26 +02:00
Denys Vlasenko
5ecbed0e26 hush: do not segfault on "for </dev/null v in..."
This is not accepted by bash, we may also disallow this,
but for now, at least do not crash

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-12 17:56:58 +02:00
Denys Vlasenko
ab1de7df99 hush: test for, and disallow several invalid syntaxes
function                                             old     new   delta
parse_stream                                        2292    2456    +164
done_pipe                                            231     252     +21
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 185/0)             Total: 185 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-11 23:18:01 +02:00
Denys Vlasenko
0da6c813e1 hush: fix var_backslash1.tests
function                                             old     new   delta
o_addqblock                                            -     131    +131
append_str_maybe_ifs_split                            53     100     +47
expand_one_var                                      1872    1897     +25
encode_then_expand_vararg                            380     399     +19
sig_unblock                                           41      43      +2
sig_block                                             41      40      -1
sigprocmask_allsigs                                   33      31      -2
expand_vars_to_list                                 1080    1077      -3
wait_for_child_or_signal                             202     193      -9
o_addQstr                                            175      42    -133
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 4/5 up/down: 224/-148)           Total: 76 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-11 17:36:02 +02:00
Denys Vlasenko
d18c9eadf0 shells: testcase: add another test for EINTR on fifo open
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-11 14:10:17 +02:00
Denys Vlasenko
9b67dde8cd ash: redir: Retry open on EINTR
Upstream commit:

    Date: Thu, 28 May 2020 21:31:45 +1000
    redir: Retry open64 on EINTR

    It is possible for open64 to block on named pipes, and therefore
    it can be interrupted by signals and return EINTR.  We should only
    let it fail with EINTR if real signals are pending (i.e., it should
    not fail on SIGCHLD if SIGCHLD has not been trapped).

    This patch adds a new helper sh_open to retry the open64 call if
    necessary.  It also calls sh_error when appropriate.

    Fixes: 3800d4934391 ("[JOBS] Fix dowait signal race")

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-09 20:17:31 +02:00
Denys Vlasenko
c92755133b shells: fix a typo in var_backslash1.tests, expand it while at it
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-09 13:00:55 +02:00
Denys Vlasenko
fa82ef1a2e shells: add testsuite item
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-09 01:48:12 +02:00
Denys Vlasenko
7648dc721e ash,hush: fix corner cases with backslash-newlines in heredocs
function                                             old     new   delta
fetch_heredocs                                       477     485      +8

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-07 01:30:57 +02:00
Denys Vlasenko
c2ef7c6dad hush: if !JOBS, skip tests which wouldn't work
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-08-03 09:32:36 +02:00
Denys Vlasenko
e9c21c5c3a hush: fix SEGV on "echo << >" and such
function                                             old     new   delta
.rodata                                           105787  105823     +36
fetch_heredocs                                       461     477     +16
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 52/0)               Total: 52 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-07-08 10:36:12 +02:00
Ron Yorston
dcd8df258a shell: improve bash compatibility of read built-in
Make the read built-in more compatible with bash:

- Return an exit code of 142 on timeout.

- When the timeout expires before a newline is detected in the
  input bash captures the partial input.  This behaviour is new
  since bash version 4.4.  BusyBox shells had the pre-4.4 behaviour
  where the input was lost.

Update the tests to suit and fix a couple of compiler errors in
the testsuite.

function                                             old     new   delta
builtin_read                                         154     174     +20
readcmd                                              213     228     +15
shell_builtin_read                                  1364    1370      +6
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 41/0)               Total: 41 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2025-07-01 20:21:37 +02:00
Denys Vlasenko
23da5c4b71 hush: do not exit interactive shell on some redirection errors
$ echo >&99
hush: dup2(99,1): Bad file descriptor
$ echo >&9999
hush: fcntl(1,F_DUPFD,10000): Invalid argument
$ echo 2>/dev/tty 10>&9999
hush: fcntl(10,F_DUPFD,10000): Invalid argument
$ still alive!_

function                                             old     new   delta
static.setup_redirects                               334     394     +60
.rodata                                           105661  105712     +51
dup_CLOEXEC                                           49      79     +30
save_fd_on_redirect                                  263     277     +14
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/0 up/down: 155/0)             Total: 155 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2024-07-13 02:13:28 +02:00
Denys Vlasenko
14e28c18ca hush: fix "exec 3>FILE" aborting if 3 is exactly the next free fd
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2024-07-13 00:59:02 +02:00
Denys Vlasenko
c5a1be25ba ash: fix handling of single-quoted strings in pattern substitution
function                                             old     new   delta
subevalvar                                          1576    1588     +12

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2024-02-26 16:27:53 +01:00
Denys Vlasenko
758b21402a hush: detect when terminating "done"/"fi" is missing
function                                             old     new   delta
parse_stream                                        2271    2292     +21
.rodata                                           105408  105427     +19
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 40/0)               Total: 40 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2024-02-25 17:53:25 +01:00
Denys Vlasenko
07a95cfcab ash: disable check for "good" function name, bash does not check this
function                                             old     new   delta
.rodata                                           105304  105261     -43
parse_command                                       1696    1633     -63
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-106)           Total: -106 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2023-07-04 14:38:25 +02:00
Denys Vlasenko
c1c267fd36 shell/math: bash-compatible handling of too large numbers
function                                             old     new   delta
parse_with_base                                        -     170    +170
evaluate_string                                     1477    1309    -168
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 0/1 up/down: 170/-168)            Total: 2 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2023-06-25 17:42:05 +02:00
Denys Vlasenko
b61fd8ec5a shell: typo fix in tests
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2023-06-18 18:49:00 +02:00
Denys Vlasenko
e127985839 shell/math: fix ?: to not evaluate not-taken branches
This fixes ash-arith-arith-ternary1/2.tests

function                                             old     new   delta
evaluate_string                                     1271    1432    +161
arith_apply                                          968    1000     +32
arith                                                 22      36     +14
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 207/0)             Total: 207 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2023-06-16 19:51:01 +02:00
Denys Vlasenko
ea6dcbe283 shell/math: fix order of expansion of variables to numbers
This fixes arith-assign-in-varexp1.tests

function                                             old     new   delta
evaluate_string                                     1132    1258    +126
arith_lookup_val                                     143       -    -143
arith_apply                                         1132     977    -155
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 1/1 up/down: 126/-298)         Total: -172 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2023-06-15 13:56:12 +02:00
Denys Vlasenko
61a4959251 shell/math: remove special code to handle a?b?c:d:e, it works without it now
The "hack" to virtually parenthesize ? EXPR : made this unnecessary.
The expression is effectively a?(b?(c):d):e and thus b?c:d is evaluated
before continuing with the second :

function                                             old     new   delta
evaluate_string                                     1148    1132     -16

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2023-06-15 11:22:13 +02:00
Denys Vlasenko
5f56a03882 shell/math: fix parsing of ?: and explain why it's parsed that way
This fixes arith-precedence1.tests.

This breaks arith-ternary2.tests again (we now evaluate variables
on not-taken branches). We need a better logic here anyway:
not only bare variables should not evaluate when not-taken:
	1 ? eval_me : do_not_eval
but any (arbitrarily complex) expressions shouldn't
evaluate as well!
	1 ? var_is_set=1 : ((var_is_not_set=2,var2*=4))

function                                             old     new   delta
evaluate_string                                     1097    1148     +51

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2023-06-15 10:14:43 +02:00
Denys Vlasenko
2ff01bb699 shell: sync ash/hush test scripts
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2023-06-14 15:19:02 +02:00
Denys Vlasenko
3df885abe3 shell/math: fix the order of variable resolution in binops
function                                             old     new   delta
arith_apply                                         1134    1143      +9

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2023-06-14 11:33:59 +02:00
Denys Vlasenko
bab8828b0d hush: fix expansion of space in "a=${a:+$a }c" construct
function                                             old     new   delta
encode_then_append_var_plusminus                     554     552      -2

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2023-06-12 16:39:32 +02:00
Denys Vlasenko
6824298ab4 hush: fix ELIF cmd1;cmd2 THEN ... not executing cmd2, closes 15571
function                                             old     new   delta
run_list                                            1012    1024     +12

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2023-05-25 14:22:10 +02:00
Denys Vlasenko
90b607d79a hush: quote variable values printed by "set" (match ash behavior)
function                                             old     new   delta
builtin_set                                          258     301     +43

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2023-04-13 09:20:24 +02:00
Denys Vlasenko
1c54552842 ash: fix ifs cleanup on error paths
Patch by Alex Gorinson <algore3698@gmail.com>

function                                             old     new   delta
evalvar                                              477     495     +18
varvalue                                             603     618     +15
subevalvar                                          1557    1572     +15
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 48/0)               Total: 48 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2022-08-02 11:18:11 +02:00
Sören Tempel
fa52ac9781 ash: don't read past end of var in subvareval for bash substitutions
Without this patch, BusyBox handles bash pattern substitutions without
a terminating '/' character incorrectly.

Consider the following shell script:

	_bootstrapver=5.0.211-r0
	_referencesdir="/usr/${_bootstrapver/-*}/Sources"
	echo $_referencesdir

This should output `/usr/5.0.211/Sources`. However, without this patch
it instead outputs `/usr/5.0.211Sources`. This is due to the fact that
BusyBox expects the bash pattern substitutions to always be terminated
with a '/' (at least in this part of subvareval) and thus reads passed
the substitution itself and consumes the '/' character which is part of
the literal string. If there is no '/' after the substitution then
BusyBox might perform an out-of-bounds read under certain circumstances.

When replacing the bash pattern substitution with `${_bootstrapver/-*/}`,
or with this patch applied, ash outputs the correct value.

Signed-off-by: Sören Tempel <soeren@soeren-tempel.net>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2022-03-01 08:47:43 +01:00
Denys Vlasenko
5acf5e1f87 shell: fix script's comm field if ENABLE_FEATURE_PREFER_APPLETS=y
function                                             old     new   delta
re_execed_comm                                         -      46     +46
main                                                  72      86     +14
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/0 up/down: 60/0)               Total: 60 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-10-11 18:44:00 +02:00
Denys Vlasenko
1be73dd9ad shell: fix parsing of $(( (v)++ + NUM ))
function                                             old     new   delta
evaluate_string                                      988    1011     +23

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-09-26 13:29:25 +02:00
Denys Vlasenko
62e433131b shell: enable more tests which are passing now
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-09-25 22:35:17 +02:00
Denys Vlasenko
d84a604830 shell: fix arithmentic evaluation of "++7" and such (it is + + 7, i.e. 7)
function                                             old     new   delta
evaluate_string                                      945     988     +43

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-09-25 22:04:45 +02:00
Denys Vlasenko
64aa86b720 ash: LINENO starts from 0 in -c SCRIPT mode
The var_LINENO3.tests fails for hush: it does start from 0, but does not increment.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-09-07 18:16:45 +02:00
Denys Vlasenko
d6c9cbc072 ash: fix LINENO in functions
From larger patch by Roberto A. Foglietta <roberto.foglietta@gmail.com>

function                                             old     new   delta
evalfun                                              348     369     +21
ash_main                                            1202    1218     +16
setinputstring                                        65      73      +8
lookupvar                                            116     106     -10
evaltree                                             772     753     -19
evalsubshell                                         192     173     -19
evalfor                                              175     156     -19
evalcase                                             273     254     -19
evalcommand                                         1560    1536     -24
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/6 up/down: 45/-110)           Total: -65 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-09-07 18:01:49 +02:00
Denys Vlasenko
e53c7dbafc hush: fix set -n to act immediately, not just after run_list()
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-09-07 02:25:52 +02:00
Denys Vlasenko
c450437a4e shell: update psubst testcases
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-07-27 04:20:32 +02:00
Denys Vlasenko
b278d82c61 hush: implement $'str' bashism
function                                             old     new   delta
parse_dollar_squote                                    -     441    +441
encode_then_expand_vararg                            359     380     +21
parse_stream                                        2252    2271     +19
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/0 up/down: 481/0)             Total: 481 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-07-26 15:32:46 +02:00
Denys Vlasenko
05c5d745f7 ahell: update testsuite
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-07-25 22:03:16 +02:00
Denys Vlasenko
97c3b5e3ff hush: fix bkslash+newline handling and number validation in ${NN} and ${#NN}
Entering "${1a}" into interactive shell was making it exit.

function                                             old     new   delta
parse_dollar                                         824     958    +134
i_getch_and_eat_bkslash_nl                             -      44     +44
parse_expr                                           917     938     +21
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/0 up/down: 199/0)             Total: 199 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-19 15:45:45 +02:00
Denys Vlasenko
1b7a9b68d0 hush: fix handling of \^C and "^C"
function                                             old     new   delta
parse_stream                                        2238    2252     +14
encode_string                                        243     256     +13
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 27/0)               Total: 27 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-15 16:46:30 +02:00
Denys Vlasenko
cad20ced86 typo fix
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2020-12-25 19:08:16 +01:00