Warn about strings for numerical operators in [[ ]] (fixes #2312)
This commit is contained in:
parent
f5fd9c2fed
commit
747bd8fd6a
|
@ -1109,6 +1109,12 @@ prop_checkNumberComparisons13 = verify checkNumberComparisons "[ $foo > $bar ]"
|
||||||
prop_checkNumberComparisons14 = verifyNot checkNumberComparisons "[[ foo < bar ]]"
|
prop_checkNumberComparisons14 = verifyNot checkNumberComparisons "[[ foo < bar ]]"
|
||||||
prop_checkNumberComparisons15 = verifyNot checkNumberComparisons "[ $foo '>' $bar ]"
|
prop_checkNumberComparisons15 = verifyNot checkNumberComparisons "[ $foo '>' $bar ]"
|
||||||
prop_checkNumberComparisons16 = verify checkNumberComparisons "[ foo -eq 'y' ]"
|
prop_checkNumberComparisons16 = verify checkNumberComparisons "[ foo -eq 'y' ]"
|
||||||
|
prop_checkNumberComparisons17 = verify checkNumberComparisons "[[ 'foo' -eq 2 ]]"
|
||||||
|
prop_checkNumberComparisons18 = verify checkNumberComparisons "[[ foo -eq 2 ]]"
|
||||||
|
prop_checkNumberComparisons19 = verifyNot checkNumberComparisons "foo=1; [[ foo -eq 2 ]]"
|
||||||
|
prop_checkNumberComparisons20 = verify checkNumberComparisons "[[ 2 -eq / ]]"
|
||||||
|
prop_checkNumberComparisons21 = verify checkNumberComparisons "[[ foo -eq foo ]]"
|
||||||
|
|
||||||
checkNumberComparisons params (TC_Binary id typ op lhs rhs) = do
|
checkNumberComparisons params (TC_Binary id typ op lhs rhs) = do
|
||||||
if isNum lhs || isNum rhs
|
if isNum lhs || isNum rhs
|
||||||
then do
|
then do
|
||||||
|
@ -1134,8 +1140,8 @@ checkNumberComparisons params (TC_Binary id typ op lhs rhs) = do
|
||||||
|
|
||||||
when (op `elem` arithmeticBinaryTestOps) $ do
|
when (op `elem` arithmeticBinaryTestOps) $ do
|
||||||
mapM_ checkDecimals [lhs, rhs]
|
mapM_ checkDecimals [lhs, rhs]
|
||||||
when (typ == SingleBracket) $
|
mapM_ checkString [lhs, rhs]
|
||||||
checkStrings [lhs, rhs]
|
|
||||||
|
|
||||||
where
|
where
|
||||||
hasStringComparison = shellType params /= Sh
|
hasStringComparison = shellType params /= Sh
|
||||||
|
@ -1148,19 +1154,45 @@ checkNumberComparisons params (TC_Binary id typ op lhs rhs) = do
|
||||||
decimalError = "Decimals are not supported. " ++
|
decimalError = "Decimals are not supported. " ++
|
||||||
"Either use integers only, or use bc or awk to compare."
|
"Either use integers only, or use bc or awk to compare."
|
||||||
|
|
||||||
checkStrings =
|
checkString t =
|
||||||
mapM_ stringError . find isNonNum
|
let
|
||||||
|
asString = getLiteralStringDef "\0" t
|
||||||
|
isVar = isVariableName asString
|
||||||
|
kind = if isVar then "a variable" else "an arithmetic expression"
|
||||||
|
fix = if isVar then "$var" else "$((expr))"
|
||||||
|
in
|
||||||
|
when (isNonNum t) $
|
||||||
|
if typ == SingleBracket
|
||||||
|
then
|
||||||
|
err (getId t) 2170 $
|
||||||
|
"Invalid number for " ++ op ++ ". Use " ++ seqv op ++
|
||||||
|
" to compare as string (or use " ++ fix ++
|
||||||
|
" to expand as " ++ kind ++ ")."
|
||||||
|
else
|
||||||
|
-- We should warn if any of the following holds:
|
||||||
|
-- The string is not a variable name
|
||||||
|
-- Any part of it is quoted
|
||||||
|
-- It's not a recognized variable name
|
||||||
|
when (not isVar || any isQuotes (getWordParts t) || asString `notElem` assignedVariables) $
|
||||||
|
warn (getId t) 2309 $
|
||||||
|
op ++ " treats this as " ++ kind ++ ". " ++
|
||||||
|
"Use " ++ seqv op ++ " to compare as string (or expand explicitly with " ++ fix ++ ")."
|
||||||
|
|
||||||
|
assignedVariables :: [String]
|
||||||
|
assignedVariables = mapMaybe f (variableFlow params)
|
||||||
|
where
|
||||||
|
f t = do
|
||||||
|
Assignment (_, _, name, _) <- return t
|
||||||
|
return name
|
||||||
|
|
||||||
isNonNum t = not . all numChar $ onlyLiteralString t
|
isNonNum t = not . all numChar $ onlyLiteralString t
|
||||||
numChar x = isDigit x || x `elem` "+-. "
|
numChar x = isDigit x || x `elem` "+-. "
|
||||||
|
|
||||||
stringError t = err (getId t) 2170 $
|
|
||||||
"Numerical " ++ op ++ " does not dereference in [..]. Expand or use string operator."
|
|
||||||
|
|
||||||
isNum t =
|
isNum t =
|
||||||
case oversimplify t of
|
case oversimplify t of
|
||||||
[v] -> all isDigit v
|
[v] -> all isDigit v
|
||||||
_ -> False
|
_ -> False
|
||||||
|
|
||||||
isFraction t =
|
isFraction t =
|
||||||
case oversimplify t of
|
case oversimplify t of
|
||||||
[v] -> isJust $ matchRegex floatRegex v
|
[v] -> isJust $ matchRegex floatRegex v
|
||||||
|
|
Loading…
Reference in New Issue