Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash=' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-unknown-linux-gnu' -DCONF_VENDOR='unknown' -DLOCALEDIR='/home/dualbus/local/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -DDEBUG -DMALLOC_DEBUG -I. -I. -I./include -I./lib -g -O2 uname output: Linux claret 3.7.9-1-ARCH #1 SMP PREEMPT Mon Feb 18 02:13:30 EET 2013 x86_64 GNU/Linux Machine Type: x86_64-unknown-linux-gnu
Bash Version: 4.3 Patch Level: 0 Release Status: alpha Description: The rules for escaping single quotes inside the pat and rep arguments are somehow fuzzy. There's a difference between what I expected to work, and how really bash treats strings there. I see that that specific PE has changed in every bash major version, and even within minor releases it has incompatible behavior. I include a script that -- I expect -- explains the issue better than my words. The left side of the `|' is what bash generates, the right side is what I expect. Repeat-By: ------------------------- #!/usr/bin/env bash for shell in bash{4,+,=} mksh ksh zsh; do "$shell" <<'EOF' t() { printf '%s | %s\n' "$1" "$2" } v="'" # v <- ' printf '===\n%s %s\n---\n' \ "$0" \ "$BASH_VERSION" #-- t "${v/$'\''/$'\''}" "'" t ${v/$'\''/$'\''} "'" t "${v/$'\''/x}" "x" t ${v/$'\''/x} "x" t "${v/x/$'\''}" "'" t ${v/x/$'\''} "'" t "${v/x/$'\x5c\''}" "'" #< I would actually expect these to t ${v/x/$'\x5c\''} "'" #< be \' t "${v/\'/\'}" "'" t ${v/\'/\'} "'" EOF done : <<'EOF' http://austingroupbugs.net/view.php?id=221 ansiexpand sh_single_quote expand_string_if_necessary EOF ------------------------- The output in my machine: ------------------------- === bash4 4.2.45(2)-release --- ' | ' ' | ' bash4: line 13: bad substitution: no closing `}' in "${v/'/x}" x | x bash4: line 15: bad substitution: no closing `}' in "${v/x/'}" ' | ' ' | ' ' | ' \' | ' ' | ' === bash+ 4.3.0(1)-alpha --- ' | ' ' | ' bash+: line 13: bad substitution: no closing `}' in "${v/'/x}" x | x bash+: line 15: bad substitution: no closing `}' in "${v/x/'}" ' | ' ' | ' ' | ' ' | ' ' | ' === bash= 4.3.0(2)-alpha --- ' | ' ' | ' x | x x | x ' | ' ' | ' ' | ' ' | ' ' | ' ' | ' === mksh --- ' | ' ' | ' x | x x | x ' | ' ' | ' ' | ' ' | ' ' | ' ' | ' === ksh --- ' | ' ' | ' x | x x | x ' | ' ' | ' ' | ' ' | ' ' | ' ' | ' === zsh --- $'\'' | ' ' | ' x | x x | x ' | ' ' | ' ' | ' ' | ' \' | ' ' | ' ------------------------- I add a fix for the `bad substitution' error. I'm not aware if it breaks anything. I ran the tests, and there was no evident breakage, but I didn't investigate the issue further. As for the "${v/x/$'\x5c\''}" expansion, I don't think that interpreting the expanded $'\x5c' is correct, but all the shells I tested do that, so I guess that's expected behavior. Fix: --- parse.y | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/parse.y b/parse.y index 61f0f7c..729cf3b 100644 --- a/parse.y +++ b/parse.y @@ -3352,17 +3352,9 @@ parse_matched_pair (qc, open, close, lenp, flags) ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen); xfree (nestret); - if ((rflags & P_DQUOTE) == 0) - { - nestret = sh_single_quote (ttrans); - free (ttrans); - nestlen = strlen (nestret); - } - else - { - nestret = ttrans; - nestlen = ttranslen; - } + nestret = sh_single_quote (ttrans); + free (ttrans); + nestlen = strlen (nestret); retind -= 2; /* back up before the $' */ } else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0)) @@ -3830,17 +3822,9 @@ eof_error: ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen); xfree (nestret); - if ((rflags & P_DQUOTE) == 0) - { - nestret = sh_single_quote (ttrans); - free (ttrans); - nestlen = strlen (nestret); - } - else - { - nestret = ttrans; - nestlen = ttranslen; - } + nestret = sh_single_quote (ttrans); + free (ttrans); + nestlen = strlen (nestret); retind -= 2; /* back up before the $' */ } else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0)) -- Eduardo A. Bustamante López
pgpcyGieD6Isz.pgp
Description: PGP signature