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 |
|
31 |
#### strict-arith option |
32 |
shopt -s strict-arith |
33 |
## status: 0 |
34 |
## N-I bash status: 1 |
35 |
## N-I dash/mksh status: 127 |
36 |
|
37 |
#### Sourcing a script that returns at the top level |
38 |
echo one |
39 |
. spec/testdata/return-helper.sh |
40 |
echo $? |
41 |
echo two |
42 |
## STDOUT: |
43 |
one |
44 |
return-helper.sh |
45 |
42 |
46 |
two |
47 |
## END |
48 |
|
49 |
#### top level control flow |
50 |
$SH spec/testdata/top-level-control-flow.sh |
51 |
## status: 0 |
52 |
## STDOUT: |
53 |
SUBSHELL |
54 |
BREAK |
55 |
CONTINUE |
56 |
RETURN |
57 |
## OK bash STDOUT: |
58 |
SUBSHELL |
59 |
BREAK |
60 |
CONTINUE |
61 |
RETURN |
62 |
DONE |
63 |
## END |
64 |
|
65 |
#### errexit and top-level control flow |
66 |
$SH -o errexit spec/testdata/top-level-control-flow.sh |
67 |
## status: 2 |
68 |
## OK bash status: 1 |
69 |
## STDOUT: |
70 |
SUBSHELL |
71 |
## END |
72 |
|
73 |
#### shopt -s strict-control-flow |
74 |
shopt -s strict-control-flow || true |
75 |
echo break |
76 |
break |
77 |
echo hi |
78 |
## STDOUT: |
79 |
break |
80 |
## END |
81 |
## status: 1 |
82 |
## N-I dash/bash/mksh STDOUT: |
83 |
break |
84 |
hi |
85 |
# END |
86 |
## N-I dash/bash/mksh status: 0 |
87 |
|
88 |
#### return at top level is an error |
89 |
return |
90 |
echo "status=$?" |
91 |
## stdout-json: "" |
92 |
## OK bash STDOUT: |
93 |
status=1 |
94 |
## END |
95 |
|
96 |
#### continue at top level is NOT an error |
97 |
# NOTE: bash and mksh both print warnings, but don't exit with an error. |
98 |
continue |
99 |
echo status=$? |
100 |
## stdout: status=0 |
101 |
|
102 |
#### break at top level is NOT an error |
103 |
break |
104 |
echo status=$? |
105 |
## stdout: status=0 |
106 |
|
107 |
#### empty argv WITHOUT strict-argv |
108 |
x='' |
109 |
$x |
110 |
echo status=$? |
111 |
|
112 |
if $x; then |
113 |
echo VarSub |
114 |
fi |
115 |
|
116 |
if $(echo foo >/dev/null); then |
117 |
echo CommandSub |
118 |
fi |
119 |
|
120 |
if "$x"; then |
121 |
echo VarSub |
122 |
else |
123 |
echo VarSub FAILED |
124 |
fi |
125 |
|
126 |
if "$(echo foo >/dev/null)"; then |
127 |
echo CommandSub |
128 |
else |
129 |
echo CommandSub FAILED |
130 |
fi |
131 |
|
132 |
## STDOUT: |
133 |
status=0 |
134 |
VarSub |
135 |
CommandSub |
136 |
VarSub FAILED |
137 |
CommandSub FAILED |
138 |
## END |
139 |
|
140 |
#### empty argv WITH strict-argv |
141 |
shopt -s strict-argv || true |
142 |
echo empty |
143 |
x='' |
144 |
$x |
145 |
echo status=$? |
146 |
## status: 1 |
147 |
## STDOUT: |
148 |
empty |
149 |
## END |
150 |
## N-I dash/bash/mksh status: 0 |
151 |
## N-I dash/bash/mksh STDOUT: |
152 |
empty |
153 |
status=0 |
154 |
## END |
155 |
|
156 |
#### Arrays are incorrectly compared, but strict-array prevents it |
157 |
|
158 |
# NOTE: from spec/dbracket has a test case like this |
159 |
# sane-array should turn this ON. |
160 |
# bash and mksh allow this because of decay |
161 |
|
162 |
a=('a b' 'c d') |
163 |
b=('a' 'b' 'c' 'd') |
164 |
echo ${#a[@]} |
165 |
echo ${#b[@]} |
166 |
[[ "${a[@]}" == "${b[@]}" ]] && echo EQUAL |
167 |
|
168 |
shopt -s strict-array || true |
169 |
[[ "${a[@]}" == "${b[@]}" ]] && echo EQUAL |
170 |
|
171 |
## status: 1 |
172 |
## STDOUT: |
173 |
2 |
174 |
4 |
175 |
EQUAL |
176 |
## END |
177 |
## OK bash/mksh status: 0 |
178 |
## OK bash/mksh STDOUT: |
179 |
2 |
180 |
4 |
181 |
EQUAL |
182 |
EQUAL |
183 |
## END |
184 |
## N-I dash status: 2 |
185 |
## N-I dash stdout-json: "" |
186 |
|
187 |
#### automatically creating arrays WITHOUT strict-array |
188 |
undef[2]=x |
189 |
undef[3]=y |
190 |
argv "${undef[@]}" |
191 |
## STDOUT: |
192 |
['x', 'y'] |
193 |
## END |
194 |
## N-I dash status: 2 |
195 |
## N-I dash stdout-json: "" |
196 |
|
197 |
#### automatically creating arrays are INDEXED, not associative |
198 |
shopt -u strict-arith || true |
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: "" |