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: ""