"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/ShellCheck/Checks/ShellSupport.hs" between
shellcheck-0.8.0.tar.gz and shellcheck-0.9.0.tar.gz

About: ShellCheck is a static analysis and linting tool for sh/bash scripts (written in Haskell).

ShellSupport.hs  (shellcheck-0.8.0):ShellSupport.hs  (shellcheck-0.9.0)
skipping to change at line 28 skipping to change at line 28
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
-} -}
{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleContexts #-}
module ShellCheck.Checks.ShellSupport (checker , ShellCheck.Checks.ShellSupport. runTests) where module ShellCheck.Checks.ShellSupport (checker , ShellCheck.Checks.ShellSupport. runTests) where
import ShellCheck.AST import ShellCheck.AST
import ShellCheck.ASTLib import ShellCheck.ASTLib
import ShellCheck.AnalyzerLib import ShellCheck.AnalyzerLib
import ShellCheck.Interface import ShellCheck.Interface
import ShellCheck.Prelude
import ShellCheck.Regex import ShellCheck.Regex
import Control.Monad import Control.Monad
import Control.Monad.RWS import Control.Monad.RWS
import Data.Char import Data.Char
import Data.Functor.Identity import Data.Functor.Identity
import Data.List import Data.List
import Data.Maybe import Data.Maybe
import qualified Data.Map as Map import qualified Data.Map as Map
import qualified Data.Set as Set import qualified Data.Set as Set
skipping to change at line 93 skipping to change at line 94
prop_checkBashisms = verify checkBashisms "while read a; do :; done < <(a)" prop_checkBashisms = verify checkBashisms "while read a; do :; done < <(a)"
prop_checkBashisms2 = verify checkBashisms "[ foo -nt bar ]" prop_checkBashisms2 = verify checkBashisms "[ foo -nt bar ]"
prop_checkBashisms3 = verify checkBashisms "echo $((i++))" prop_checkBashisms3 = verify checkBashisms "echo $((i++))"
prop_checkBashisms4 = verify checkBashisms "rm !(*.hs)" prop_checkBashisms4 = verify checkBashisms "rm !(*.hs)"
prop_checkBashisms5 = verify checkBashisms "source file" prop_checkBashisms5 = verify checkBashisms "source file"
prop_checkBashisms6 = verify checkBashisms "[ \"$a\" == 42 ]" prop_checkBashisms6 = verify checkBashisms "[ \"$a\" == 42 ]"
prop_checkBashisms7 = verify checkBashisms "echo ${var[1]}" prop_checkBashisms7 = verify checkBashisms "echo ${var[1]}"
prop_checkBashisms8 = verify checkBashisms "echo ${!var[@]}" prop_checkBashisms8 = verify checkBashisms "echo ${!var[@]}"
prop_checkBashisms9 = verify checkBashisms "echo ${!var*}" prop_checkBashisms9 = verify checkBashisms "echo ${!var*}"
prop_checkBashisms10= verify checkBashisms "echo ${var:4:12}" prop_checkBashisms10 = verify checkBashisms "echo ${var:4:12}"
prop_checkBashisms11= verifyNot checkBashisms "echo ${var:-4}" prop_checkBashisms11 = verifyNot checkBashisms "echo ${var:-4}"
prop_checkBashisms12= verify checkBashisms "echo ${var//foo/bar}" prop_checkBashisms12 = verify checkBashisms "echo ${var//foo/bar}"
prop_checkBashisms13= verify checkBashisms "exec -c env" prop_checkBashisms13 = verify checkBashisms "exec -c env"
prop_checkBashisms14= verify checkBashisms "echo -n \"Foo: \"" prop_checkBashisms14 = verify checkBashisms "echo -n \"Foo: \""
prop_checkBashisms15= verify checkBashisms "let n++" prop_checkBashisms15 = verify checkBashisms "let n++"
prop_checkBashisms16= verify checkBashisms "echo $RANDOM" prop_checkBashisms16 = verify checkBashisms "echo $RANDOM"
prop_checkBashisms17= verify checkBashisms "echo $((RANDOM%6+1))" prop_checkBashisms17 = verify checkBashisms "echo $((RANDOM%6+1))"
prop_checkBashisms18= verify checkBashisms "foo &> /dev/null" prop_checkBashisms18 = verify checkBashisms "foo &> /dev/null"
prop_checkBashisms19= verify checkBashisms "foo > file*.txt" prop_checkBashisms19 = verify checkBashisms "foo > file*.txt"
prop_checkBashisms20= verify checkBashisms "read -ra foo" prop_checkBashisms20 = verify checkBashisms "read -ra foo"
prop_checkBashisms21= verify checkBashisms "[ -a foo ]" prop_checkBashisms21 = verify checkBashisms "[ -a foo ]"
prop_checkBashisms22= verifyNot checkBashisms "[ foo -a bar ]" prop_checkBashisms22 = verifyNot checkBashisms "[ foo -a bar ]"
prop_checkBashisms23= verify checkBashisms "trap mything ERR INT" prop_checkBashisms23 = verify checkBashisms "trap mything ERR INT"
prop_checkBashisms24= verifyNot checkBashisms "trap mything INT TERM" prop_checkBashisms24 = verifyNot checkBashisms "trap mything INT TERM"
prop_checkBashisms25= verify checkBashisms "cat < /dev/tcp/host/123" prop_checkBashisms25 = verify checkBashisms "cat < /dev/tcp/host/123"
prop_checkBashisms26= verify checkBashisms "trap mything ERR SIGTERM" prop_checkBashisms26 = verify checkBashisms "trap mything ERR SIGTERM"
prop_checkBashisms27= verify checkBashisms "echo *[^0-9]*" prop_checkBashisms27 = verify checkBashisms "echo *[^0-9]*"
prop_checkBashisms28= verify checkBashisms "exec {n}>&2" prop_checkBashisms28 = verify checkBashisms "exec {n}>&2"
prop_checkBashisms29= verify checkBashisms "echo ${!var}" prop_checkBashisms29 = verify checkBashisms "echo ${!var}"
prop_checkBashisms30= verify checkBashisms "printf -v '%s' \"$1\"" prop_checkBashisms30 = verify checkBashisms "printf -v '%s' \"$1\""
prop_checkBashisms31= verify checkBashisms "printf '%q' \"$1\"" prop_checkBashisms31 = verify checkBashisms "printf '%q' \"$1\""
prop_checkBashisms32= verifyNot checkBashisms "#!/bin/dash\n[ foo -nt bar ]" prop_checkBashisms32 = verifyNot checkBashisms "#!/bin/dash\n[ foo -nt bar ]"
prop_checkBashisms33= verify checkBashisms "#!/bin/sh\necho -n foo" prop_checkBashisms33 = verify checkBashisms "#!/bin/sh\necho -n foo"
prop_checkBashisms34= verifyNot checkBashisms "#!/bin/dash\necho -n foo" prop_checkBashisms34 = verifyNot checkBashisms "#!/bin/dash\necho -n foo"
prop_checkBashisms35= verifyNot checkBashisms "#!/bin/dash\nlocal foo" prop_checkBashisms35 = verifyNot checkBashisms "#!/bin/dash\nlocal foo"
prop_checkBashisms36= verifyNot checkBashisms "#!/bin/dash\nread -p foo -r bar" prop_checkBashisms36 = verifyNot checkBashisms "#!/bin/dash\nread -p foo -r bar"
prop_checkBashisms37= verifyNot checkBashisms "HOSTNAME=foo; echo $HOSTNAME" prop_checkBashisms37 = verifyNot checkBashisms "HOSTNAME=foo; echo $HOSTNAME"
prop_checkBashisms38= verify checkBashisms "RANDOM=9; echo $RANDOM" prop_checkBashisms38 = verify checkBashisms "RANDOM=9; echo $RANDOM"
prop_checkBashisms39= verify checkBashisms "foo-bar() { true; }" prop_checkBashisms39 = verify checkBashisms "foo-bar() { true; }"
prop_checkBashisms40= verify checkBashisms "echo $(<file)" prop_checkBashisms40 = verify checkBashisms "echo $(<file)"
prop_checkBashisms41= verify checkBashisms "echo `<file`" prop_checkBashisms41 = verify checkBashisms "echo `<file`"
prop_checkBashisms42= verify checkBashisms "trap foo int" prop_checkBashisms42 = verify checkBashisms "trap foo int"
prop_checkBashisms43= verify checkBashisms "trap foo sigint" prop_checkBashisms43 = verify checkBashisms "trap foo sigint"
prop_checkBashisms44= verifyNot checkBashisms "#!/bin/dash\ntrap foo int" prop_checkBashisms44 = verifyNot checkBashisms "#!/bin/dash\ntrap foo int"
prop_checkBashisms45= verifyNot checkBashisms "#!/bin/dash\ntrap foo INT" prop_checkBashisms45 = verifyNot checkBashisms "#!/bin/dash\ntrap foo INT"
prop_checkBashisms46= verify checkBashisms "#!/bin/dash\ntrap foo SIGINT" prop_checkBashisms46 = verify checkBashisms "#!/bin/dash\ntrap foo SIGINT"
prop_checkBashisms47= verify checkBashisms "#!/bin/dash\necho foo 42>/dev/null" prop_checkBashisms47 = verify checkBashisms "#!/bin/dash\necho foo 42>/dev/null"
prop_checkBashisms48= verifyNot checkBashisms "#!/bin/sh\necho $LINENO" prop_checkBashisms48 = verifyNot checkBashisms "#!/bin/sh\necho $LINENO"
prop_checkBashisms49= verify checkBashisms "#!/bin/dash\necho $MACHTYPE" prop_checkBashisms49 = verify checkBashisms "#!/bin/dash\necho $MACHTYPE"
prop_checkBashisms50= verify checkBashisms "#!/bin/sh\ncmd >& file" prop_checkBashisms50 = verify checkBashisms "#!/bin/sh\ncmd >& file"
prop_checkBashisms51= verifyNot checkBashisms "#!/bin/sh\ncmd 2>&1" prop_checkBashisms51 = verifyNot checkBashisms "#!/bin/sh\ncmd 2>&1"
prop_checkBashisms52= verifyNot checkBashisms "#!/bin/sh\ncmd >&2" prop_checkBashisms52 = verifyNot checkBashisms "#!/bin/sh\ncmd >&2"
prop_checkBashisms53= verifyNot checkBashisms "#!/bin/sh\nprintf -- -f\n" prop_checkBashisms52b = verifyNot checkBashisms "#!/bin/sh\ncmd >& $var"
prop_checkBashisms54= verify checkBashisms "#!/bin/sh\nfoo+=bar" prop_checkBashisms52c = verify checkBashisms "#!/bin/sh\ncmd >& $dir/$var"
prop_checkBashisms55= verify checkBashisms "#!/bin/sh\necho ${@%foo}" prop_checkBashisms53 = verifyNot checkBashisms "#!/bin/sh\nprintf -- -f\n"
prop_checkBashisms56= verifyNot checkBashisms "#!/bin/sh\necho ${##}" prop_checkBashisms54 = verify checkBashisms "#!/bin/sh\nfoo+=bar"
prop_checkBashisms57= verifyNot checkBashisms "#!/bin/dash\nulimit -c 0" prop_checkBashisms55 = verify checkBashisms "#!/bin/sh\necho ${@%foo}"
prop_checkBashisms58= verify checkBashisms "#!/bin/sh\nulimit -c 0" prop_checkBashisms56 = verifyNot checkBashisms "#!/bin/sh\necho ${##}"
prop_checkBashisms57 = verifyNot checkBashisms "#!/bin/dash\nulimit -c 0"
prop_checkBashisms58 = verify checkBashisms "#!/bin/sh\nulimit -c 0"
prop_checkBashisms59 = verify checkBashisms "#!/bin/sh\njobs -s" prop_checkBashisms59 = verify checkBashisms "#!/bin/sh\njobs -s"
prop_checkBashisms60 = verifyNot checkBashisms "#!/bin/sh\njobs -p" prop_checkBashisms60 = verifyNot checkBashisms "#!/bin/sh\njobs -p"
prop_checkBashisms61 = verifyNot checkBashisms "#!/bin/sh\njobs -lp" prop_checkBashisms61 = verifyNot checkBashisms "#!/bin/sh\njobs -lp"
prop_checkBashisms62 = verify checkBashisms "#!/bin/sh\nexport -f foo" prop_checkBashisms62 = verify checkBashisms "#!/bin/sh\nexport -f foo"
prop_checkBashisms63 = verifyNot checkBashisms "#!/bin/sh\nexport -p" prop_checkBashisms63 = verifyNot checkBashisms "#!/bin/sh\nexport -p"
prop_checkBashisms64 = verify checkBashisms "#!/bin/sh\nreadonly -a" prop_checkBashisms64 = verify checkBashisms "#!/bin/sh\nreadonly -a"
prop_checkBashisms65 = verifyNot checkBashisms "#!/bin/sh\nreadonly -p" prop_checkBashisms65 = verifyNot checkBashisms "#!/bin/sh\nreadonly -p"
prop_checkBashisms66 = verifyNot checkBashisms "#!/bin/sh\ncd -P ." prop_checkBashisms66 = verifyNot checkBashisms "#!/bin/sh\ncd -P ."
prop_checkBashisms67 = verify checkBashisms "#!/bin/sh\ncd -P -e ." prop_checkBashisms67 = verify checkBashisms "#!/bin/sh\ncd -P -e ."
prop_checkBashisms68 = verify checkBashisms "#!/bin/sh\numask -p" prop_checkBashisms68 = verify checkBashisms "#!/bin/sh\numask -p"
skipping to change at line 226 skipping to change at line 229
warnMsg id 3015 "=~ regex matching is" warnMsg id 3015 "=~ regex matching is"
bashism (TC_Unary id SingleBracket "-v" _) = bashism (TC_Unary id SingleBracket "-v" _) =
warnMsg id 3016 "unary -v (in place of [ -n \"${var+x}\" ]) is" warnMsg id 3016 "unary -v (in place of [ -n \"${var+x}\" ]) is"
bashism (TC_Unary id _ "-a" _) = bashism (TC_Unary id _ "-a" _) =
warnMsg id 3017 "unary -a in place of -e is" warnMsg id 3017 "unary -a in place of -e is"
bashism (TA_Unary id op _) bashism (TA_Unary id op _)
| op `elem` [ "|++", "|--", "++|", "--|"] = | op `elem` [ "|++", "|--", "++|", "--|"] =
warnMsg id 3018 $ filter (/= '|') op ++ " is" warnMsg id 3018 $ filter (/= '|') op ++ " is"
bashism (TA_Binary id "**" _ _) = warnMsg id 3019 "exponentials are" bashism (TA_Binary id "**" _ _) = warnMsg id 3019 "exponentials are"
bashism (T_FdRedirect id "&" (T_IoFile _ (T_Greater _) _)) = warnMsg id 3020 "&> is" bashism (T_FdRedirect id "&" (T_IoFile _ (T_Greater _) _)) = warnMsg id 3020 "&> is"
bashism (T_FdRedirect id "" (T_IoFile _ (T_GREATAND _) _)) = warnMsg id 3021 bashism (T_FdRedirect id "" (T_IoFile _ (T_GREATAND _) file)) =
">& is" unless (all isDigit $ onlyLiteralString file) $ warnMsg id 3021 ">& file
name (as opposed to >& fd) is"
bashism (T_FdRedirect id ('{':_) _) = warnMsg id 3022 "named file descriptor s are" bashism (T_FdRedirect id ('{':_) _) = warnMsg id 3022 "named file descriptor s are"
bashism (T_FdRedirect id num _) bashism (T_FdRedirect id num _)
| all isDigit num && length num > 1 = warnMsg id 3023 "FDs outside 0-9 a re" | all isDigit num && length num > 1 = warnMsg id 3023 "FDs outside 0-9 a re"
bashism (T_Assignment id Append _ _ _) = bashism (T_Assignment id Append _ _ _) =
warnMsg id 3024 "+= is" warnMsg id 3024 "+= is"
bashism (T_IoFile id _ word) | isNetworked = bashism (T_IoFile id _ word) | isNetworked =
warnMsg id 3025 "/dev/{tcp,udp} is" warnMsg id 3025 "/dev/{tcp,udp} is"
where where
file = onlyLiteralString word file = onlyLiteralString word
isNetworked = any (`isPrefixOf` file) ["/dev/tcp", "/dev/udp"] isNetworked = any (`isPrefixOf` file) ["/dev/tcp", "/dev/udp"]
skipping to change at line 442 skipping to change at line 446
(var `elem` bashDynamicVars (var `elem` bashDynamicVars
|| var `elem` bashVars && not (isAssigned var)) || var `elem` bashVars && not (isAssigned var))
&& not (isDash && var `elem` dashVars) && not (isDash && var `elem` dashVars)
isAssigned var = any f (variableFlow params) isAssigned var = any f (variableFlow params)
where where
f x = case x of f x = case x of
Assignment (_, _, name, _) -> name == var Assignment (_, _, name, _) -> name == var
_ -> False _ -> False
prop_checkEchoSed1 = verify checkEchoSed "FOO=$(echo \"$cow\" | sed 's/foo/bar/g ')" prop_checkEchoSed1 = verify checkEchoSed "FOO=$(echo \"$cow\" | sed 's/foo/bar/g ')"
prop_checkEchoSed1b= verify checkEchoSed "FOO=$(sed 's/foo/bar/g' <<< \"$cow\")" prop_checkEchoSed1b = verify checkEchoSed "FOO=$(sed 's/foo/bar/g' <<< \"$cow\") "
prop_checkEchoSed2 = verify checkEchoSed "rm $(echo $cow | sed -e 's,foo,bar,')" prop_checkEchoSed2 = verify checkEchoSed "rm $(echo $cow | sed -e 's,foo,bar,')"
prop_checkEchoSed2b= verify checkEchoSed "rm $(sed -e 's,foo,bar,' <<< $cow)" prop_checkEchoSed2b = verify checkEchoSed "rm $(sed -e 's,foo,bar,' <<< $cow)"
checkEchoSed = ForShell [Bash, Ksh] f checkEchoSed = ForShell [Bash, Ksh] f
where where
f (T_Redirecting id lefts r) = f (T_Redirecting id lefts r) =
when (any redirectHereString lefts) $ when (any redirectHereString lefts) $
checkSed id rcmd checkSed id rcmd
where where
redirectHereString :: Token -> Bool redirectHereString :: Token -> Bool
redirectHereString t = case t of redirectHereString t = case t of
(T_FdRedirect _ _ T_HereString{}) -> True (T_FdRedirect _ _ T_HereString{}) -> True
_ -> False _ -> False
skipping to change at line 528 skipping to change at line 532
T_IndexedElement _ (first:second:_) _ -> about second T_IndexedElement _ (first:second:_) _ -> about second
T_DollarBraced _ _ l -> T_DollarBraced _ _ l ->
when (isMultiDim l) $ about token when (isMultiDim l) $ about token
_ -> return () _ -> return ()
about t = warn (getId t) 2180 "Bash does not support multidimensional arrays . Use 1D or associative arrays." about t = warn (getId t) 2180 "Bash does not support multidimensional arrays . Use 1D or associative arrays."
re = mkRegex "^\\[.*\\]\\[.*\\]" -- Fixme, this matches ${foo:- [][]} and s uch as well re = mkRegex "^\\[.*\\]\\[.*\\]" -- Fixme, this matches ${foo:- [][]} and s uch as well
isMultiDim l = getBracedModifier (concat $ oversimplify l) `matches` re isMultiDim l = getBracedModifier (concat $ oversimplify l) `matches` re
prop_checkPS11 = verify checkPS1Assignments "PS1='\\033[1;35m\\$ '" prop_checkPS11 = verify checkPS1Assignments "PS1='\\033[1;35m\\$ '"
prop_checkPS11a= verify checkPS1Assignments "export PS1='\\033[1;35m\\$ '" prop_checkPS11a = verify checkPS1Assignments "export PS1='\\033[1;35m\\$ '"
prop_checkPSf2 = verify checkPS1Assignments "PS1='\\h \\e[0m\\$ '" prop_checkPSf2 = verify checkPS1Assignments "PS1='\\h \\e[0m\\$ '"
prop_checkPS13 = verify checkPS1Assignments "PS1=$'\\x1b[c '" prop_checkPS13 = verify checkPS1Assignments "PS1=$'\\x1b[c '"
prop_checkPS14 = verify checkPS1Assignments "PS1=$'\\e[3m; '" prop_checkPS14 = verify checkPS1Assignments "PS1=$'\\e[3m; '"
prop_checkPS14a= verify checkPS1Assignments "export PS1=$'\\e[3m; '" prop_checkPS14a = verify checkPS1Assignments "export PS1=$'\\e[3m; '"
prop_checkPS15 = verifyNot checkPS1Assignments "PS1='\\[\\033[1;35m\\]\\$ '" prop_checkPS15 = verifyNot checkPS1Assignments "PS1='\\[\\033[1;35m\\]\\$ '"
prop_checkPS16 = verifyNot checkPS1Assignments "PS1='\\[\\e1m\\e[1m\\]\\$ '" prop_checkPS16 = verifyNot checkPS1Assignments "PS1='\\[\\e1m\\e[1m\\]\\$ '"
prop_checkPS17 = verifyNot checkPS1Assignments "PS1='e033x1B'" prop_checkPS17 = verifyNot checkPS1Assignments "PS1='e033x1B'"
prop_checkPS18 = verifyNot checkPS1Assignments "PS1='\\[\\e\\]'" prop_checkPS18 = verifyNot checkPS1Assignments "PS1='\\[\\e\\]'"
checkPS1Assignments = ForShell [Bash] f checkPS1Assignments = ForShell [Bash] f
where where
f token = case token of f token = case token of
(T_Assignment _ _ "PS1" _ word) -> warnFor word (T_Assignment _ _ "PS1" _ word) -> warnFor word
_ -> return () _ -> return ()
 End of changes. 7 change blocks. 
55 lines changed or deleted 59 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)