hush: fix globbing+backslashes in unquoted $var expansion
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
This commit is contained in:
18
shell/hush_test/hush-glob/glob2.right
Normal file
18
shell/hush_test/hush-glob/glob2.right
Normal 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
|
27
shell/hush_test/hush-glob/glob2.tests
Executable file
27
shell/hush_test/hush-glob/glob2.tests
Executable 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: $?
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user