Skip to content

Commit

Permalink
Reorganize tests for quotes in parameter expansion
Browse files Browse the repository at this point in the history
In POSIX.1-2024, it is clarified that the word in ${param=word} is
subject to quote removal, so the relevant behavior now can be tests in
quote-p.tst instead of quote-y.tst. It is also clarified that } can be
escaped with a backslash in parameter expansions, which allows moving
the relevant tests as well.
  • Loading branch information
magicant committed Dec 12, 2024
1 parent 9b2d911 commit b10320c
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 104 deletions.
1 change: 1 addition & 0 deletions tests/POSIX
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Volume 3: Shell & Utilities

2.6.2 Parameter Expansion
* param-p.tst
* quote-p.tst

2.6.3 Command Substitution
* cmdsub-p.tst
Expand Down
80 changes: 66 additions & 14 deletions tests/quote-p.tst
Original file line number Diff line number Diff line change
Expand Up @@ -487,18 +487,17 @@ __IN__
[abcdefghijklmnopqrstuvwxyz{|}~][``]
__OUT__

# \{ and \} are tested in quote-y.tst.
test_oE 'backslashes in substitution of expansion ${a+b} in double quotes'
a=a
bracket "${a+\ \!\$x\%\&\(\)\*\+\,\-\.\/ \# \"x\" \'x\'}"
bracket "${a+\0\1\2\3\4\5\6\7\8\9\:\;\<\=\>\? \\ \\\\}"
bracket "${a+\@\A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z\[\]\^\_}"
bracket "${a+\a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z\|\~ \`\`}"
bracket "${a+\a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z\{\|\}\~ \`\`}"
__IN__
[\ \!$x\%\&\(\)\*\+\,\-\.\/ \# "x" \'x\']
[\0\1\2\3\4\5\6\7\8\9\:\;\<\=\>\? \ \\]
[\@\A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z\[\]\^\_]
[\a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z\|\~ ``]
[\a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z\{\|}\~ ``]
__OUT__

test_oE 'backslashes in substitution of expansion ${a-b}'
Expand All @@ -513,23 +512,69 @@ __IN__
[abcdefghijklmnopqrstuvwxyz{|}~][``]
__OUT__

# \{ and \} are tested in quote-y.tst.
test_oE 'backslashes in substitution of expansion ${a-b} in double quotes'
bracket "${u-\ \!\$x\%\&\(\)\*\+\,\-\.\/ \# \"x\" \'x\'}"
bracket "${u-\0\1\2\3\4\5\6\7\8\9\:\;\<\=\>\? \\ \\\\}"
bracket "${u-\@\A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z\[\]\^\_}"
bracket "${u-\a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z\|\~ \`\`}"
bracket "${u-\a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z\{\|\}\~ \`\`}"
__IN__
[\ \!$x\%\&\(\)\*\+\,\-\.\/ \# "x" \'x\']
[\0\1\2\3\4\5\6\7\8\9\:\;\<\=\>\? \ \\]
[\@\A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z\[\]\^\_]
[\a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z\|\~ ``]
[\a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z\{\|}\~ ``]
__OUT__

# Quote removal is performed before assignment, so the resultant expansions are
# subject to field splitting.
test_oE 'quotes in substitution of expansion ${a=b}'
bracket ${a=\ \!\$x\%\&\(\)\*\+\,\-\.\/ \# \"x\" \'x\'}
bracket ${b=\0\1\2\3\4\5\6\7\8\9\:\;\<\=\>\? \\ \\\\}
bracket ${c=\@\A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z\[\]\^\_}
bracket ${d=\a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z\{\|\}\~ \`\`}
bracket $a
bracket $b
bracket $c
bracket $d
__IN__
[!$x%&()*+,-./][#]["x"]['x']
[0123456789:;<=>?][\][\\]
[@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_]
[abcdefghijklmnopqrstuvwxyz{|}~][``]
[!$x%&()*+,-./][#]["x"]['x']
[0123456789:;<=>?][\][\\]
[@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_]
[abcdefghijklmnopqrstuvwxyz{|}~][``]
__OUT__

# See quote-y.tst
#test_oE 'backslashes in substitution of expansion ${a=b}'
#__IN__
#__OUT__
# Quote removal is performed before assignment, but the resultant expansions
# are not subject to field splitting because they are double-quoted.
test_oE 'quotes in substitution of expansion ${a=b} in double quotes'
bracket "${a=\ \!\$x\%\&\(\)\*\+\,\-\.\/ \# \"x\" \'x\'}"
bracket "${b=\0\1\2\3\4\5\6\7\8\9\:\;\<\=\>\? \\ \\\\}"
bracket "${c=\@\A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z\[\]\^\_}"
bracket "${d=\a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z\{\|\}\~ \`\`}"
bracket "${e=a"b"c}" "${f=a"*"c}" "${g=a"\"\""c}" "${h=a"\\"c}" "${i=a"''"c}"
bracket "${j=a'b'c}" "${k=a'*'c}" "${l=a'""'c}" "${m=a'\'c}"
bracket "$a"
bracket "$b"
bracket "$c"
bracket "$d"
bracket "$e" "$f" "$g" "$h" "$i"
bracket "$j" "$k" "$l" "$m"
__IN__
[\ \!$x\%\&\(\)\*\+\,\-\.\/ \# "x" \'x\']
[\0\1\2\3\4\5\6\7\8\9\:\;\<\=\>\? \ \\]
[\@\A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z\[\]\^\_]
[\a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z\{\|}\~ ``]
[abc][a*c][a""c][a\c][a''c]
[a'b'c][a'*'c][a''c][a'\'c]
[\ \!$x\%\&\(\)\*\+\,\-\.\/ \# "x" \'x\']
[\0\1\2\3\4\5\6\7\8\9\:\;\<\=\>\? \ \\]
[\@\A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z\[\]\^\_]
[\a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z\{\|}\~ ``]
[abc][a*c][a""c][a\c][a''c]
[a'b'c][a'*'c][a''c][a'\'c]
__OUT__

# See quote-y.tst
#test_oE 'backslashes in substitution of expansion ${a?b}'
Expand All @@ -553,10 +598,17 @@ __IN__
[abc][a*c][a""c][a\c]
__OUT__

# See quote-y.tst
#test_oE 'single and double quotes in substitution of expansion ${a=b}'
#__IN__
#__OUT__
test_oE 'single and double quotes in substitution of expansion ${a=b}'
bracket ${a=a"b"c} ${b=a"*"c} ${c=a"\"\""c} ${d=a"\\"c} ${e=a"''"c}
bracket ${f=a'b'c} ${g=a'*'c} ${h=a'""'c} ${i=a'\'c}
bracket $a $b $c $d $e
bracket $f $g $h $i
__IN__
[abc][a*c][a""c][a\c][a''c]
[abc][a*c][a""c][a\c]
[abc][a*c][a""c][a\c][a''c]
[abc][a*c][a""c][a\c]
__OUT__

# See quote-y.tst
#test_oE 'single and double quotes in substitution of expansion ${a?b}'
Expand Down
96 changes: 6 additions & 90 deletions tests/quote-y.tst
Original file line number Diff line number Diff line change
@@ -1,104 +1,20 @@
# quote-y.tst: yash-specific test of quoting

(
setup -d

posix="true"

# POSIX does not imply that quote removal should be applied before the expanded
# word is assigned to the unset/empty variable. However, existing shells seem
# to perform quote removal, so yash follows them. Also note that the resultant
# value of the parameter expansion has quote removal already applied, so it is
# subject to field splitting.
test_oE 'quotes in substitution of expansion ${a=b}'
bracket ${a=\ \!\$x\%\&\(\)\*\+\,\-\.\/ \# \"x\" \'x\'}
bracket ${b=\0\1\2\3\4\5\6\7\8\9\:\;\<\=\>\? \\ \\\\}
bracket ${c=\@\A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z\[\]\^\_}
bracket ${d=\a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z\{\|\}\~ \`\`}
bracket ${e=a"b"c} ${f=a"*"c} ${g=a"\"\""c} ${h=a"\\"c} ${i=a"''"c}
bracket ${j=a'b'c} ${k=a'*'c} ${l=a'""'c} ${m=a'\'c}
bracket $a
bracket $b
bracket $c
bracket $d
bracket $e $f $g $h $i
bracket $j $k $l $m
__IN__
[!$x%&()*+,-./][#]["x"]['x']
[0123456789:;<=>?][\][\\]
[@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_]
[abcdefghijklmnopqrstuvwxyz{|}~][``]
[abc][a*c][a""c][a\c][a''c]
[abc][a*c][a""c][a\c]
[!$x%&()*+,-./][#]["x"]['x']
[0123456789:;<=>?][\][\\]
[@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_]
[abcdefghijklmnopqrstuvwxyz{|}~][``]
[abc][a*c][a""c][a\c][a''c]
[abc][a*c][a""c][a\c]
__OUT__

# \{ and \} are tested below
test_oE 'quotes in substitution of expansion ${a=b} in double quotes'
bracket "${a=\ \!\$x\%\&\(\)\*\+\,\-\.\/ \# \"x\" \'x\'}"
bracket "${b=\0\1\2\3\4\5\6\7\8\9\:\;\<\=\>\? \\ \\\\}"
bracket "${c=\@\A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z\[\]\^\_}"
bracket "${d=\a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z\|\~ \`\`}"
bracket "${e=a"b"c}" "${f=a"*"c}" "${g=a"\"\""c}" "${h=a"\\"c}" "${i=a"''"c}"
bracket "${j=a'b'c}" "${k=a'*'c}" "${l=a'""'c}" "${m=a'\'c}"
bracket "$a"
bracket "$b"
bracket "$c"
bracket "$d"
bracket "$e" "$f" "$g" "$h" "$i"
bracket "$j" "$k" "$l" "$m"
__IN__
[\ \!$x\%\&\(\)\*\+\,\-\.\/ \# "x" \'x\']
[\0\1\2\3\4\5\6\7\8\9\:\;\<\=\>\? \ \\]
[\@\A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z\[\]\^\_]
[\a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z\|\~ ``]
[abc][a*c][a""c][a\c][a''c]
[a'b'c][a'*'c][a''c][a'\'c]
[\ \!$x\%\&\(\)\*\+\,\-\.\/ \# "x" \'x\']
[\0\1\2\3\4\5\6\7\8\9\:\;\<\=\>\? \ \\]
[\@\A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z\[\]\^\_]
[\a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z\|\~ ``]
[abc][a*c][a""c][a\c][a''c]
[a'b'c][a'*'c][a''c][a'\'c]
__OUT__

# The same as above, POSIX does not imply quote removal but many existing
# shells perform quote removal.
# POSIX does not imply quote removal to be performed on the error message but
# many existing shells do it.
test_Oe -e 2 'quotes in substitution of expansion ${a?b}'
eval '${u?\ \!\$x\%\&\(\)\*\+\,\-\.\/ \# \"x\" \'\''x\'\''\?\\\`\`"x"'\''y'\''}'
eval '${u?\ \!\$x\%\&\(\)\*\+\,\-\.\/\{\|\} \# \"x\" \'\''x\'\''\?\\\`\`"x"'\''y'\''}'
__IN__
eval: u: !$x%&()*+,-./ # "x" 'x'?\``xy
eval: u: !$x%&()*+,-./{|} # "x" 'x'?\``xy
__ERR__

test_Oe -e 2 'quotes in substitution of expansion ${a?b} in double quotes'
eval '"${u?\ \!\$x\%\&\(\)\*\+\,\-\.\/ \# \"x\" \'\''x\'\''\?\\\\\`\`"x"'\''y'\''}"'
eval '"${u?\ \!\$x\%\&\(\)\*\+\,\-\.\/\{\|\} \# \"x\" \'\''x\'\''\?\\\\\`\`"x"'\''y'\''}"'
__IN__
eval: u: \ \!$x\%\&\(\)\*\+\,\-\.\/ \# "x" \'x\'\?\\``x'y'
__ERR__

# POSIX XCU 2.2.3 says, "A preceding <backslash> character shall be used to
# escape a literal '{' or '}'." On the other hand, it also says in the same
# section, "The <backslash> shall retain its special meaning as an escape
# character ... only when followed by one of the following characters when
# considered special: $ ` " \ <newline>"
# These specs look quite contradictory as to whether \{ and \} should be
# considered as escapes or not, but existing (other) shells seem to behave
# consistently, so yash follows those shells.
test_oe -e 2 '\{ and \} in substitution of expansions in double quotes'
a=a
bracket "${a+1\{2\}3}" "${u-1\{2\}3}" "${b=1\{2\}3}"
bracket "$b"
eval '"${u?1\{2\}3}"'
__IN__
[1\{2}3][1\{2}3][1\{2}3]
[1\{2}3]
__OUT__
eval: u: 1\{2}3
eval: u: \ \!$x\%\&\(\)\*\+\,\-\.\/\{\|} \# "x" \'x\'\?\\``x'y'
__ERR__

)
Expand Down

0 comments on commit b10320c

Please sign in to comment.