[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Sus behaviour when cmd string ends with single backslash
From: |
vzvzvz2 |
Subject: |
Sus behaviour when cmd string ends with single backslash |
Date: |
Sun, 13 Feb 2022 20:15:47 +0000 |
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -g -O2 -fdebug-prefix-map=/build/bash-a6qmCk/bash-5.0=.
-fstack-protector-strong -Wformat -Werror=format-security -Wall
-Wno-parentheses -Wno-format-security
uname output: Linux zoli-linux 5.13.0-28-generic #31~20.04.1-Ubuntu SMP Wed Jan
19 14:08:10 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu
Bash Version: 5.0
Patch Level: 17
Release Status: release
Description:
Background
----------
Commit a0c0a00fc419b7bc08202a79134fcd5bc0427071 (bash-4.4) introduced a change
in parse.y with following documentation in the change logs:
parse.y
- shell_getc: if bash is reading input from a string that ends with an
unquoted backslash, add another backslash instead of a newline, since
the backslash and newline will disappear in normal processing. Fixes
bug with `bash -c 'eval \\; echo y' ' skipping the eval command and
setting incorrect exit status, and `bash -ic 'eval \\; echo y' '
seeing EOF on empty line and exiting before the echo. Keep track of
backslash state with last_was_backslash; set in char reading loop.
Fixes bug reported by Eduardo A. Bustamante López <dualbus@gmail.com>
The new code in parse.y
/* Don't add a newline to a string that ends with a backslash if we're
going to be removing quoted newlines, since that will eat the
backslash. Add another backslash instead (will be removed by
word expansion). */
if (bash_input.type == st_string && expanding_alias() == 0 &&
last_was_backslash && c == EOF && remove_quoted_newline)
shell_input_line[shell_input_line_len] = '\\';
else
shell_input_line[shell_input_line_len] = '\n';
shell_input_line[shell_input_line_len + 1] = '\0';
This specific change is also there in commit
0385211bb5cb01e0259c64ec2c5cc6337d4e215c on a development branch.
Observed vs. expected behaviour
-------------------------------
The mentioned bug is indeed fixed by this change. However, in case of another
edge case following new behaviour is observable:
$ bash -c 'echo \'
\
$ # backslash appears on output
The behaviour before the change was following:
$ bash -c 'echo \'
$ # no output
This behaviour is observable since 4.4 up to the most current released version
(5.1).
I am not sure what is the correct behaviour here. My best guess is, that the
single backslash at the end of the string should not be printed, because (bash
man page):
Quote Removal
After the preceding expansions, all unquoted occurrences of the
characters \, ', and " that did not result
from one of the above expansions are removed.
This behaviour would be consistent with the very same command took from a
script:
$ hexdump -C echo-with-newline.sh
00000000 65 63 68 6f 20 5c 0a |echo \.|
00000007
$ hexdump -C echo-without-newline.sh
00000000 65 63 68 6f 20 5c |echo \|
00000006
$ bash echo-with-newline.sh
$ bash echo-without-newline.sh
$ # no output in both cases
Repeat-By:
See commands in the description.
- Sus behaviour when cmd string ends with single backslash,
vzvzvz2 <=