[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Unexpected behavior of single quotes when used in the patsub PE.
From: |
Eduardo A . Bustamante López |
Subject: |
Unexpected behavior of single quotes when used in the patsub PE. |
Date: |
Wed, 20 Mar 2013 14:56:18 -0700 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
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
pgpymDT3Wo_7s.pgp
Description: PGP signature
- Unexpected behavior of single quotes when used in the patsub PE.,
Eduardo A . Bustamante López <=