[PATCH] ash: fix parsing of alias expansion + bash features
Denys Vlasenko
vda.linux at googlemail.com
Wed Jul 10 05:14:45 UTC 2024
Applied, thank you!
On Thu, May 2, 2024 at 2:14 PM Ron Yorston <rmy at pobox.com> wrote:
>
> An alias expansion immediately followed by '<' and a newline is
> parsed incorrectly:
>
> ~ $ alias x='echo yo'
> ~ $ x<
> yo
> ~ $
> sh: syntax error: unexpected newline
>
> The echo is executed and an error is printed on the next command
> submission. In dash the echo isn't executed and the error is
> reported immediately:
>
> $ alias x='echo yo'
> $ x<
> dash: 3: Syntax error: newline unexpected
> $
>
> The difference between BusyBox and dash is that BusyBox supports
> bash-style process substitution and output redirection. These
> require checking for '<(', '>(' and '&>' in readtoken1().
>
> In the case above, when the end of the alias is found, the '<' and
> the following newline are both read to check for '<('. Since
> there's no match both characters are pushed back.
>
> The next input is obtained by reading the expansion of the alias.
> Once this string is exhausted the next call to __pgetc() calls
> preadbuffer() which pops the string, reverts to the previous input
> and recursively calls __pgetc(). This request is satisified from
> the pungetc buffer. But the first __pgetc() doesn't know this:
> it sees the character has come from preadbuffer() so it (incorrectly)
> updates the pungetc buffer.
>
> Resolve the issue by moving the code to pop the string and fetch
> the next character up from preadbuffer() into __pgetc().
>
> function old new delta
> pgetc 28 589 +561
> __pgetc 607 - -607
> ------------------------------------------------------------------------------
> (add/remove: 0/1 grow/shrink: 1/0 up/down: 561/-607) Total: -46 bytes
>
> Signed-off-by: Ron Yorston <rmy at pobox.com>
> ---
> shell/ash.c | 12 ++++++------
> 1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/shell/ash.c b/shell/ash.c
> index 4ca4c6c56..5df0ba625 100644
> --- a/shell/ash.c
> +++ b/shell/ash.c
> @@ -10934,11 +10934,6 @@ preadbuffer(void)
> char *q;
> int more;
>
> - if (unlikely(g_parsefile->strpush)) {
> - popstring();
> - return __pgetc();
> - }
> -
> if (g_parsefile->buf == NULL) {
> pgetc_debug("preadbuffer PEOF1");
> return PEOF;
> @@ -11053,8 +11048,13 @@ static int __pgetc(void)
>
> if (--g_parsefile->left_in_line >= 0)
> c = (unsigned char)*g_parsefile->next_to_pgetc++;
> - else
> + else {
> + if (unlikely(g_parsefile->strpush)) {
> + popstring();
> + return __pgetc();
> + }
> c = preadbuffer();
> + }
>
> g_parsefile->lastc[1] = g_parsefile->lastc[0];
> g_parsefile->lastc[0] = c;
> --
> 2.44.0
>
> _______________________________________________
> busybox mailing list
> busybox at busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox
More information about the busybox
mailing list