bug-bash
[Top][All Lists]
Advanced

[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

Attachment: pgpz119mIu23V.pgp
Description: PGP signature


reply via email to

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