parent
ac3f0b3360
commit
505ff7832f
|
@ -1521,6 +1521,7 @@ prop_subshellAssignmentCheck15 = verifyNotTree subshellAssignmentCheck "#!/bin/k
|
|||
prop_subshellAssignmentCheck16 = verifyNotTree subshellAssignmentCheck "(set -e); echo $@"
|
||||
prop_subshellAssignmentCheck17 = verifyNotTree subshellAssignmentCheck "foo=${ { bar=$(baz); } 2>&1; }; echo $foo $bar"
|
||||
prop_subshellAssignmentCheck18 = verifyTree subshellAssignmentCheck "( exec {n}>&2; ); echo $n"
|
||||
prop_subshellAssignmentCheck19 = verifyNotTree subshellAssignmentCheck "#!/bin/bash\nshopt -s lastpipe; echo a | read -r b; echo \"$b\""
|
||||
subshellAssignmentCheck params t =
|
||||
let flow = variableFlow params
|
||||
check = findSubshelled flow [("oops",[])] Map.empty
|
||||
|
@ -2105,7 +2106,7 @@ checkLoopKeywordScope params t |
|
|||
where
|
||||
name = getCommandName t
|
||||
path = let p = getPath (parentMap params) t in filter relevant p
|
||||
subshellType t = case leadType (shellType params) (parentMap params) t of
|
||||
subshellType t' = case leadType (shellType params) (parentMap params) t' t of
|
||||
NoneScope -> Nothing
|
||||
SubshellScope str -> return str
|
||||
relevant t = isLoop t || isFunction t || isJust (subshellType t)
|
||||
|
@ -2167,7 +2168,7 @@ checkUnpassedInFunctions params root =
|
|||
functions = execWriter $ doAnalysis (tell . maybeToList . findFunction) root
|
||||
|
||||
findFunction t@(T_Function id _ _ name body) =
|
||||
let flow = getVariableFlow (shellType params) (parentMap params) body
|
||||
let flow = getVariableFlow (shellType params) (parentMap params) body root
|
||||
in
|
||||
if any (isPositionalReference t) flow && not (any isPositionalAssignment flow)
|
||||
then return t
|
||||
|
|
|
@ -145,7 +145,7 @@ makeParameters spec =
|
|||
shellTypeSpecified = isJust $ asShellType spec,
|
||||
parentMap = getParentTree root,
|
||||
variableFlow =
|
||||
getVariableFlow (shellType params) (parentMap params) root
|
||||
getVariableFlow (shellType params) (parentMap params) root root
|
||||
} in params
|
||||
where root = asScript spec
|
||||
|
||||
|
@ -337,18 +337,18 @@ tokenIsJustCommandOutput t = case t of
|
|||
check _ = False
|
||||
|
||||
-- TODO: Replace this with a proper Control Flow Graph
|
||||
getVariableFlow shell parents t =
|
||||
getVariableFlow shell parents t root =
|
||||
let (_, stack) = runState (doStackAnalysis startScope endScope t) []
|
||||
in reverse stack
|
||||
where
|
||||
startScope t =
|
||||
let scopeType = leadType shell parents t
|
||||
let scopeType = leadType shell parents t root
|
||||
in do
|
||||
when (scopeType /= NoneScope) $ modify (StackScope scopeType:)
|
||||
when (assignFirst t) $ setWritten t
|
||||
|
||||
endScope t =
|
||||
let scopeType = leadType shell parents t
|
||||
let scopeType = leadType shell parents t root
|
||||
in do
|
||||
setRead t
|
||||
unless (assignFirst t) $ setWritten t
|
||||
|
@ -367,7 +367,7 @@ getVariableFlow shell parents t =
|
|||
in mapM_ (\v -> modify (Assignment v:)) written
|
||||
|
||||
|
||||
leadType shell parents t =
|
||||
leadType shell parents t root =
|
||||
case t of
|
||||
T_DollarExpansion _ _ -> SubshellScope "$(..) expansion"
|
||||
T_Backticked _ _ -> SubshellScope "`..` expansion"
|
||||
|
@ -396,11 +396,19 @@ leadType shell parents t =
|
|||
|
||||
lastCreatesSubshell =
|
||||
case shell of
|
||||
Bash -> True
|
||||
Bash -> not hasShoptLastPipe
|
||||
Dash -> True
|
||||
Sh -> True
|
||||
Ksh -> False
|
||||
|
||||
hasShoptLastPipe = isNothing $ doAnalysis (guard . not . isShoptLastPipe) root
|
||||
isShoptLastPipe t =
|
||||
case t of
|
||||
T_SimpleCommand {} ->
|
||||
t `isUnqualifiedCommand` "shopt" &&
|
||||
("lastpipe" `elem` oversimplify t)
|
||||
_ -> False
|
||||
|
||||
getModifiedVariables t =
|
||||
case t of
|
||||
T_SimpleCommand _ vars [] ->
|
||||
|
|
Loading…
Reference in New Issue