1 |
#!/usr/bin/env bash |
2 |
# |
3 |
# In this file: |
4 |
# |
5 |
# - strict-control-flow: break/continue at the top level should be fatal! |
6 |
# |
7 |
# Other tests: |
8 |
# - spec/errexit-strict: command subs inherit errexit |
9 |
# - TODO: does bash 4.4. use inherit_errexit? |
10 |
# |
11 |
# - spec/var-op-other tests strict-word-eval (negative indices and invalid |
12 |
# utf-8) |
13 |
# - hm I think these should be the default? compat-word-eval? |
14 |
# |
15 |
# - spec/arith tests strict-arith - invalid strings become 0 |
16 |
# - OSH has a warning that can turn into an error. I think the error could |
17 |
# be the default (since this was a side effect of "ShellMathShock") |
18 |
|
19 |
# - strict-array: unimplemented. |
20 |
# - WAS undef[2]=x, but bash-completion relied on the associative array |
21 |
# version of that. |
22 |
# - TODO: It should disable decay_array EVERYWHERE except a specific case like: |
23 |
# - s="${a[*]}" # quoted, the unquoted ones glob in a command context |
24 |
# - spec/dbracket has array comparison relevant to the case below |
25 |
# |
26 |
# Most of those options could be compat-*. |
27 |
# |
28 |
# One that can't: strict-scope disables dynamic scope. |
29 |
|
30 |
#### Sourcing a script that returns at the top level |
31 |
echo one |
32 |
. spec/testdata/return-helper.sh |
33 |
echo $? |
34 |
echo two |
35 |
## STDOUT: |
36 |
one |
37 |
return-helper.sh |
38 |
42 |
39 |
two |
40 |
## END |
41 |
|
42 |
#### top level control flow |
43 |
$SH spec/testdata/top-level-control-flow.sh |
44 |
## status: 0 |
45 |
## STDOUT: |
46 |
SUBSHELL |
47 |
BREAK |
48 |
CONTINUE |
49 |
RETURN |
50 |
## OK bash STDOUT: |
51 |
SUBSHELL |
52 |
BREAK |
53 |
CONTINUE |
54 |
RETURN |
55 |
DONE |
56 |
## END |
57 |
|
58 |
#### errexit and top-level control flow |
59 |
$SH -o errexit spec/testdata/top-level-control-flow.sh |
60 |
## status: 2 |
61 |
## OK bash status: 1 |
62 |
## STDOUT: |
63 |
SUBSHELL |
64 |
## END |
65 |
|
66 |
#### set -o strict-control-flow |
67 |
$SH -o strict-control-flow -c 'echo break; break; echo hi' |
68 |
## stdout: break |
69 |
## status: 1 |
70 |
## N-I dash/bash status: 2 |
71 |
## N-I dash/bash stdout-json: "" |
72 |
## N-I mksh status: 1 |
73 |
## N-I mksh stdout-json: "" |
74 |
|
75 |
#### return at top level is an error |
76 |
return |
77 |
echo "status=$?" |
78 |
## stdout-json: "" |
79 |
## OK bash STDOUT: |
80 |
status=1 |
81 |
## END |
82 |
|
83 |
#### continue at top level is NOT an error |
84 |
# NOTE: bash and mksh both print warnings, but don't exit with an error. |
85 |
continue |
86 |
echo status=$? |
87 |
## stdout: status=0 |
88 |
|
89 |
#### break at top level is NOT an error |
90 |
break |
91 |
echo status=$? |
92 |
## stdout: status=0 |
93 |
|
94 |
#### empty argv WITHOUT strict-argv |
95 |
x='' |
96 |
$x |
97 |
echo status=$? |
98 |
|
99 |
if $x; then |
100 |
echo VarSub |
101 |
fi |
102 |
|
103 |
if $(echo foo >/dev/null); then |
104 |
echo CommandSub |
105 |
fi |
106 |
|
107 |
if "$x"; then |
108 |
echo VarSub |
109 |
else |
110 |
echo VarSub FAILED |
111 |
fi |
112 |
|
113 |
if "$(echo foo >/dev/null)"; then |
114 |
echo CommandSub |
115 |
else |
116 |
echo CommandSub FAILED |
117 |
fi |
118 |
|
119 |
## STDOUT: |
120 |
status=0 |
121 |
VarSub |
122 |
CommandSub |
123 |
VarSub FAILED |
124 |
CommandSub FAILED |
125 |
## END |
126 |
|
127 |
#### strict-argv: no first word but exit code |
128 |
|
129 |
# POSIX has a special rule for this. In OSH strict-argv is preferred so it |
130 |
# becomes a moot point. I think this is an artifact of the |
131 |
# "stateful"/imperative nature of $? -- it can be "left over" from a prior |
132 |
# command, and sometimes the prior argv is []. OSH has a more "functional" |
133 |
# implementation so it doesn't have this weirdness. |
134 |
|
135 |
if $(false); then |
136 |
echo TRUE |
137 |
else |
138 |
echo FALSE |
139 |
fi |
140 |
## STDOUT: |
141 |
FALSE |
142 |
## END |
143 |
|
144 |
#### empty argv WITH strict-argv |
145 |
set -o strict-argv || true |
146 |
echo empty |
147 |
x='' |
148 |
$x |
149 |
echo status=$? |
150 |
## status: 1 |
151 |
## STDOUT: |
152 |
empty |
153 |
## END |
154 |
## N-I bash status: 0 |
155 |
## N-I bash STDOUT: |
156 |
empty |
157 |
status=0 |
158 |
## END |
159 |
## N-I dash status: 2 |
160 |
## N-I mksh status: 1 |
161 |
## N-I dash/mksh stdout-json: "" |
162 |
|
163 |
#### Arrays should not be incorrectly compared like bash/mksh |
164 |
|
165 |
# NOTE: from spec/dbracket has a test case like this |
166 |
# sane-array should turn this ON. |
167 |
# bash and mksh allow this because of decay |
168 |
|
169 |
a=('a b' 'c d') |
170 |
b=('a' 'b' 'c' 'd') |
171 |
echo ${#a[@]} |
172 |
echo ${#b[@]} |
173 |
[[ "${a[@]}" == "${b[@]}" ]] && echo EQUAL |
174 |
## status: 1 |
175 |
## STDOUT: |
176 |
2 |
177 |
4 |
178 |
## END |
179 |
## BUG bash/mksh status: 0 |
180 |
## BUG bash/mksh STDOUT: |
181 |
2 |
182 |
4 |
183 |
EQUAL |
184 |
## END |
185 |
## N-I dash status: 2 |
186 |
## N-I dash stdout-json: "" |
187 |
|
188 |
#### automatically creating arrays WITHOUT strict-array |
189 |
undef[2]=x |
190 |
undef[3]=y |
191 |
argv "${undef[@]}" |
192 |
## STDOUT: |
193 |
['x', 'y'] |
194 |
## END |
195 |
## N-I dash status: 2 |
196 |
## N-I dash stdout-json: "" |
197 |
|
198 |
#### automatically creating arrays are INDEXED, not associative |
199 |
|
200 |
undef[2]=x |
201 |
undef[3]=y |
202 |
x='bad' |
203 |
# bad gets coerced to zero, but this is part of the RECURSIVE arithmetic |
204 |
# behavior, which we want to disallow. Consider disallowing in OSH. |
205 |
|
206 |
undef[$x]=zzz |
207 |
argv "${undef[@]}" |
208 |
## STDOUT: |
209 |
['zzz', 'x', 'y'] |
210 |
## END |
211 |
## N-I dash status: 2 |
212 |
## N-I dash stdout-json: "" |