bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Option '-c' has bug when compile-time config 'ONESHOT' is enabled


From: Yu Kou
Subject: Option '-c' has bug when compile-time config 'ONESHOT' is enabled
Date: Tue, 14 May 2019 14:57:44 -0700

Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -O2 -g -pipe -Wall -Werror=format-security
-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions
-fstack-protector-strong -grecord-gcc-switches
-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1
-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic
-fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection
-Wno-parentheses -Wno-format-security
uname output: Linux yudev144 5.0.11-300.fc30.x86_64 #1 SMP Thu May 2
14:11:38 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
Machine Type: x86_64-redhat-linux-gnu

Bash Version: 5.0
Patch Level: 2
Release Status: release

Description:
        This bug was found in bash 4.4.12 (GNU bash, version
4.4.12(1)-release (x86_64-pc-linux-gnu))
        It is still here in bash 5.0.2.

        I pubilshed it first in this page,

https://unix.stackexchange.com/questions/406674/bash-why-is-alias-after-newline-ignored-when-run-remotely#407064

        This is a bug of option '-c'.

        It can be reproduced with the command below,

                bash -c "shopt -s expand_aliases &>/dev/null;
                alias myalias='echo foo
                echo bar
echo baz'
myalias

I expect it to output such three lines as follows,
foo
bar
baz

But only 'foo' will be output.

To get the right/expected output, at least one more line has to be added
after 'myalias', like below,

bash -c "shopt -s expand_aliases &>/dev/null;
alias myalias='echo foo
echo bar
echo baz'
myalias
:"

After read the code, I found a solution to fix it without changing any
code, that is to compile bash with 'ONESHOT' undefined.

Whether define 'ONESHOT' or not leads to two completely different route in
Bash code for '-c "command"'. If undefine 'ONESHOT', '-c "command"' will
run the normal code route, which is the code route for almost all bash
executions, such as interactive command and bash script. But if define
'ONESHOT', '-c "command"' will run another particular route which is
specially designed for '-c' only, to improve its performance by avoiding
fork.

The bug is right in the particular route.

--------

Some details about this bug

The following piece of code is where the bug is. It is from function
parse_and_execute() in file builtins/evalstring.c, which is the one enabled
by 'ONESHOT'.

while (*(bash_input.location.string))
  {
    ...
  }

This while loop will run by lines, handling one line in one loop. After
read 'myalias', the last line in the problematic command (see above), the
condition in while will become false. 'myalias' is expanded to three lines
of echo, but only one echo is handled in this loop; the two other echos are
intended to be handled in next loops, but... there is no more loops.

If you add one more line after 'myalias', after read 'myalias', the
condition in while will remain true, so the two other echos will get chance
to run in next loops. The last line after 'myalias' will be handled after
all echos expanded from 'myalias' are handled.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]