hush: fix globbing+backslashes in unquoted $var expansion

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
This commit is contained in:
Denys Vlasenko
2010-09-06 10:26:37 +02:00
parent d383b49aef
commit c49d2d9793
5 changed files with 172 additions and 88 deletions

View File

@ -0,0 +1,18 @@
Expected Actual
Z\* : Z\*
Z* : Z*
Z\f : Z\f
Z\* : Z\*
Z\z : Z\z
Zz : Zz
Z\z : Z\z
Z\z : Z\z
Z\ : Z\
Z\ : Z\
Z\f Zf : Z\f Zf
Z\f Zf : Z\f Zf
Done: 0

View File

@ -0,0 +1,27 @@
# This test demonstrates that in unquoted $v, backslashes expand by this rule:
# \z -> \\\z; \<eol> -> \\<eol> (for any z, special or not),
# and subsequently globbing converts \\ to \ and treats \z as literal z
# even if it is a special char.
>'Zf'
>'Z\f'
echo 'Expected' 'Actual'
v='\*'; echo 'Z\* :' Z$v
echo 'Z* :' Z\*
echo 'Z\f :' Z\\*
echo 'Z\* :' Z\\\* # NB! only this matches Z$v output
echo
v='\z'; echo 'Z\z :' Z$v
echo 'Zz :' Z\z
echo 'Z\z :' Z\\z
echo 'Z\z :' Z\\\z
echo
v='\'; echo 'Z\ :' Z$v
echo 'Z\ :' Z\\
echo
v='*'; echo 'Z\f Zf :' Z$v
echo 'Z\f Zf :' Z*
echo
rm 'Z\f' 'Zf'
echo Done: $?

View File

@ -1,23 +1,40 @@
Source: a*b\*c
Replace str: _\\_\z_
Pattern: single backslash and star: "replace literal star"
In assignment: a_\_z_b\*c
Unquoted: a_\_z_b\*c
Unquoted =: a_\_z_b\*c
Quoted: a_\_\z_b\*c
Quoted =: a_\_\z_b\*c
Pattern: double backslash and star: "replace backslash and everything after it"
In assignment: a*b_\_z_
Unquoted: a*b_\_z_
Unquoted =: a*b_\_z_
Quoted: a*b_\_\z_
Quoted =: a*b_\_\z_
Source: a\bc
Replace str: _\\_\z_
Pattern: single backslash and b: "replace b"
In assignment: a\_\_z_c
Unquoted: a\_\_z_c
Unquoted =: a\_\_z_c
Quoted: a\_\_\z_c
Quoted =: a\_\_\z_c
Pattern: double backslash and b: "replace backslash and b"
In assignment: a_\_z_c
Unquoted: a_\_z_c
Unquoted =: a_\_z_c
Quoted: a_\_\z_c
Quoted =: a_\_\z_c
Source: a\bc
Replace str: _\\_\z_ (as variable $s)
Pattern: single backslash and b: "replace b"
Unquoted: a\_\\_\z_c
Unquoted =: a\_\\_\z_c
Quoted: a\_\\_\z_c
Quoted =: a\_\\_\z_c
Pattern: double backslash and b: "replace backslash and b"
Unquoted: a_\\_\z_c
Unquoted =: a_\\_\z_c
Quoted: a_\\_\z_c
Quoted =: a_\\_\z_c
Done: 0

View File

@ -6,23 +6,30 @@
# even in quotes.
#
# bash4 (and probably bash3 too): "Quoted:" results are different from
# unquoted and assignment expansions - they have a backslash before z.
# unquoted expansions - they have a backslash before z.
#
# The difference only exists if repl is a literal. If it is a variable:
# ${v/.../$s}, then all backslashes are preserved in both cases.
v='a*b\*c'
echo 'Source: ' "$v"
echo 'Replace str: ' '_\\_\z_'
echo 'Pattern: ' 'single backslash and star: "replace literal star"'
r=${v/\*/_\\_\z_}
echo 'In assignment:' "$r"
echo 'Unquoted: ' ${v/\*/_\\_\z_}
r=${v/\*/_\\_\z_}
echo 'Unquoted =: ' "$r"
echo 'Quoted: ' "${v/\*/_\\_\z_}"
r="${v/\*/_\\_\z_}"
echo 'Quoted =: ' "$r"
echo 'Pattern: ' 'double backslash and star: "replace backslash and everything after it"'
r=${v/\\*/_\\_\z_}
echo 'In assignment:' "$r"
echo 'Unquoted: ' ${v/\\*/_\\_\z_}
r=${v/\\*/_\\_\z_}
echo 'Unquoted =: ' "$r"
echo 'Quoted: ' "${v/\\*/_\\_\z_}"
r="${v/\\*/_\\_\z_}"
echo 'Quoted =: ' "$r"
echo
@ -31,16 +38,43 @@ echo 'Source: ' "$v"
echo 'Replace str: ' '_\\_\z_'
echo 'Pattern: ' 'single backslash and b: "replace b"'
r=${v/\b/_\\_\z_}
echo 'In assignment:' "$r"
echo 'Unquoted: ' ${v/\b/_\\_\z_}
r=${v/\b/_\\_\z_}
echo 'Unquoted =: ' "$r"
echo 'Quoted: ' "${v/\b/_\\_\z_}"
r="${v/\b/_\\_\z_}"
echo 'Quoted =: ' "$r"
echo 'Pattern: ' 'double backslash and b: "replace backslash and b"'
r=${v/\\b/_\\_\z_}
echo 'In assignment:' "$r"
echo 'Unquoted: ' ${v/\\b/_\\_\z_}
r=${v/\\b/_\\_\z_}
echo 'Unquoted =: ' "$r"
echo 'Quoted: ' "${v/\\b/_\\_\z_}"
r="${v/\\b/_\\_\z_}"
echo 'Quoted =: ' "$r"
echo
v='a\bc'
s='_\\_\z_'
echo 'Source: ' "$v"
echo 'Replace str: ' "$s" '(as variable $s)'
echo 'Pattern: ' 'single backslash and b: "replace b"'
echo 'Unquoted: ' ${v/\b/$s}
r=${v/\b/$s}
echo 'Unquoted =: ' "$r"
echo 'Quoted: ' "${v/\b/$s}"
r="${v/\b/$s}"
echo 'Quoted =: ' "$r"
echo 'Pattern: ' 'double backslash and b: "replace backslash and b"'
echo 'Unquoted: ' ${v/\\b/$s}
r=${v/\\b/$s}
echo 'Unquoted =: ' "$r"
echo 'Quoted: ' "${v/\\b/$s}"
r="${v/\\b/$s}"
echo 'Quoted =: ' "$r"
echo