[PATCH] use-after-free in expand_string_dollar_quote
A use-after-free happens in expand_string_dollar_quote if noexpand_translation is enabled and a string's translation is the same length as the string itself. --- diff --git a/subst.c b/subst.c index 08d9285e..a7a386d4 100644 --- a/subst.c +++ b/subst.c @@ -4231,12 +4231,17 @@ expand_string_dollar_quote (const char *string, int flags) continue; } trans = locale_expand (t, 0, news-sindex, 0, &translen); - free (t); if (singlequote_translations && ((news-sindex-1) != translen || STREQN (t, trans, translen) == 0)) - t = sh_single_quote (trans); + { + free (t); + t = sh_single_quote (trans); + } else - t = sh_mkdoublequoted (trans, translen, 0); + { + free (t); + t = sh_mkdoublequoted (trans, translen, 0); + } sindex = news; } #endif /* TRANSLATABLE_STRINGS */
set -e not working as expected with conditional operators
Consider the following script: #!/bin/bash f() { ls missing-file 2> /dev/null echo "test" } # 1 (set -e; f); ret=$? if (( ret )); then echo "failed" exit 1 fi # 2 (set -e; f) || { echo "failed" exit 1 } Running the block labelled '1' prints "failed" and returns 1 as the exit code, while running the other block prints "test" and returns 0. However, the result should be the same. If f() is modified like so, however: f() { ls missing-file 2> /dev/null || return 1 echo "test" } then it "works", but this also works without using set -e. I thought this was an issue with subshells, but apparently the following script also doesn't work as expected: #!/bin/bash f() { ls missing-file 2> /dev/null echo "test" } set -e f && : Since f() is not ran in a subshell, the script should quit after the 'ls' command because of set -e, but "test" is still printed and the script exits with 0. To make this script work you can either remove the "&& :" part or the 'echo' command from f(), but again, it doesn't seem like it's supposed to work this way. # This works f() { ls missing-file 2> /dev/null } set -e f && : # This also works f() { ls missing-file 2> /dev/null echo "test" } set -e f What's going on here? I'm using the latest release, Bash 5.2.15.