Warn about eval'ing arrays

This commit is contained in:
Vidar Holen 2021-07-30 18:46:19 -07:00
parent e33146d530
commit a44f3edb14
3 changed files with 24 additions and 0 deletions

View File

@ -4,6 +4,7 @@
- SC2289: Warn when command name contains tabs or linefeeds
- SC2291: Warn about repeated unquoted spaces between words in echo
- SC2292: Suggest [[ over [ in Bash/Ksh scripts (optional)
- SC2293/SC2294: Warn when calling `eval` with arrays
### Fixed
- SC2102 about repetitions in ranges no longer triggers on [[ -v arr[xx] ]]

View File

@ -872,6 +872,8 @@ getBracedReference s = fromMaybe s $
prop_getBracedModifier1 = getBracedModifier "foo:bar:baz" == ":bar:baz"
prop_getBracedModifier2 = getBracedModifier "!var:-foo" == ":-foo"
prop_getBracedModifier3 = getBracedModifier "foo[bar]" == "[bar]"
prop_getBracedModifier4 = getBracedModifier "foo[@]@Q" == "[@]@Q"
prop_getBracedModifier5 = getBracedModifier "@@Q" == "@Q"
getBracedModifier s = headOrDefault "" $ do
let var = getBracedReference s
a <- dropModifier s

View File

@ -96,6 +96,7 @@ commandChecks = [
,checkChmodDashr
,checkXargsDashi
,checkUnquotedEchoSpaces
,checkEvalArray
]
++ map checkArgComparison declaringCommands
++ map checkMaskedReturns declaringCommands
@ -1258,5 +1259,25 @@ checkUnquotedEchoSpaces = CommandCheck (Basename "echo") check
&& not (any (\x -> b < x && x < c) redirs)
prop_checkEvalArray1 = verify checkEvalArray "eval $@"
prop_checkEvalArray2 = verify checkEvalArray "eval \"${args[@]}\""
prop_checkEvalArray3 = verify checkEvalArray "eval \"${args[@]@Q}\""
prop_checkEvalArray4 = verifyNot checkEvalArray "eval \"${args[*]@Q}\""
prop_checkEvalArray5 = verifyNot checkEvalArray "eval \"$*\""
checkEvalArray = CommandCheck (Exactly "eval") (mapM_ check . concatMap getWordParts . arguments)
where
check t =
when (isArrayExpansion t) $
if isEscaped t
then style (getId t) 2293 "When eval'ing @Q-quoted words, use * rather than @ as the index."
else warn (getId t) 2294 "eval negates the benefit of arrays. Drop eval to preserve whitespace/symbols (or eval as string)."
isEscaped q =
case q of
-- Match ${arr[@]@Q} and ${@@Q} and such
T_DollarBraced _ _ l -> 'Q' `elem` getBracedModifier (concat $ oversimplify l)
_ -> False
return []
runTests = $( [| $(forAllProperties) (quickCheckWithResult (stdArgs { maxSuccess = 1 }) ) |])