Warn about suspicious IFS, such as IFS="\n"

This commit is contained in:
Vidar Holen 2014-05-10 15:37:02 -07:00
parent 680f838c63
commit c4181d45d2
2 changed files with 23 additions and 1 deletions

View File

@ -197,6 +197,7 @@ nodeChecks = [
,checkUnsupported ,checkUnsupported
,checkMultipleAppends ,checkMultipleAppends
,checkAliasesExpandEarly ,checkAliasesExpandEarly
,checkSuspiciousIFS
] ]
@ -2723,3 +2724,22 @@ checkAliasesExpandEarly params =
flip mapM_ (take 1 $ filter (not . isLiteral) $ getWordParts arg) $ flip mapM_ (take 1 $ filter (not . isLiteral) $ getWordParts arg) $
\x -> warn (getId x) 2139 "This expands when defined, not when used. Consider escaping." \x -> warn (getId x) 2139 "This expands when defined, not when used. Consider escaping."
checkArg _ = return () checkArg _ = return ()
prop_checkSuspiciousIFS1 = verify checkSuspiciousIFS "IFS=\"\\n\""
prop_checkSuspiciousIFS2 = verifyNot checkSuspiciousIFS "IFS=$'\\t'"
checkSuspiciousIFS params (T_Assignment id Assign "IFS" Nothing value) =
potentially $ do
str <- getLiteralString value
return $ check str
where
n = if (shellType params == Sh) then "'<literal linefeed here>'" else "$'\\n'"
t = if (shellType params == Sh) then "\"$(printf '\\t')\"" else "$'\\t'"
check value =
case value of
"\\n" -> suggest n
"/n" -> suggest n
"\\t" -> suggest t
"/t" -> suggest t
_ -> return ()
suggest r = warn id 2141 $ "Did you mean IFS=" ++ r ++ " ?"
checkSuspiciousIFS _ _ = return ()

View File

@ -965,10 +965,12 @@ readNormalEscaped = called "escaped char" $ do
do do
next <- anyChar next <- anyChar
case escapedChar next of case escapedChar next of
Just name -> parseNoteAt pos WarningC 1012 $ "\\" ++ [next] ++ " is just literal '" ++ [next] ++ "' here. For " ++ name ++ ", use \"$(printf \"\\" ++ [next] ++ "\")\"." Just name -> parseNoteAt pos WarningC 1012 $ "\\" ++ [next] ++ " is just literal '" ++ [next] ++ "' here. For " ++ name ++ ", use " ++ (alternative next) ++ " instead."
Nothing -> parseNoteAt pos InfoC 1001 $ "This \\" ++ [next] ++ " will be a regular '" ++ [next] ++ "' in this context." Nothing -> parseNoteAt pos InfoC 1001 $ "This \\" ++ [next] ++ " will be a regular '" ++ [next] ++ "' in this context."
return [next] return [next]
where where
alternative 'n' = "a quoted, literal line feed"
alternative t = "\"$(printf \"\\" ++ [t] ++ "\")\""
escapedChar 'n' = Just "line feed" escapedChar 'n' = Just "line feed"
escapedChar 't' = Just "tab" escapedChar 't' = Just "tab"
escapedChar 'r' = Just "carriage return" escapedChar 'r' = Just "carriage return"