[Top][All Lists]

[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



Commit a0c0a00fc419b7bc08202a79134fcd5bc0427071 (bash-4.4) introduced a change 
in parse.y with following documentation in the change logs:

        - 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] = '\\';
            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 

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 

 $ hexdump -C  echo-with-newline.sh 
 00000000  65 63 68 6f 20 5c 0a                              |echo \.|
 $ hexdump -C  echo-without-newline.sh 
 00000000  65 63 68 6f 20 5c                                 |echo \|
 $ bash echo-with-newline.sh 
 $ bash echo-without-newline.sh 
 $ # no output in both cases

See commands in the description.

reply via email to

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