Allow directive/-s to override shebang blacklist (fixes #974)

This commit is contained in:
Vidar Holen 2018-07-22 12:43:51 -07:00
parent b8ee7436e5
commit 5005dc0fa1
4 changed files with 54 additions and 22 deletions

View File

@ -118,10 +118,9 @@ defaultSpec root = AnalysisSpec {
pScript s =
let
pSpec = ParseSpec {
pSpec = newParseSpec {
psFilename = "script",
psScript = s,
psCheckSourced = False
psScript = s
}
in prRoot . runIdentity $ parseScript (mockedSystemInterface []) pSpec

View File

@ -52,10 +52,11 @@ checkScript sys spec = do
}
where
checkScript contents = do
result <- parseScript sys ParseSpec {
result <- parseScript sys newParseSpec {
psFilename = csFilename spec,
psScript = contents,
psCheckSourced = csCheckSourced spec
psCheckSourced = csCheckSourced spec,
psShellTypeOverride = csShellTypeOverride spec
}
let parseMessages = prComments result
let analysisMessages =
@ -136,6 +137,21 @@ prop_optionDisablesIssue2 =
csExcludedWarnings = [2148, 1037]
}
prop_wontParseBadShell =
[1071] == check "#!/usr/bin/python\ntrue $1\n"
prop_optionDisablesBadShebang =
null $ getErrors
(mockedSystemInterface [])
emptyCheckSpec {
csScript = "#!/usr/bin/python\ntrue\n",
csShellTypeOverride = Just Sh
}
prop_annotationDisablesBadShebang =
[] == check "#!/usr/bin/python\n# shellcheck shell=sh\ntrue\n"
prop_canParseDevNull =
[] == check "source /dev/null"
@ -180,7 +196,7 @@ prop_filewideAnnotation1 = null $
prop_filewideAnnotation2 = null $
check "#!/bin/sh\n# shellcheck disable=2086\ntrue\necho $1"
prop_filewideAnnotation3 = null $
check "#!/bin/sh\n#unerlated\n# shellcheck disable=2086\ntrue\necho $1"
check "#!/bin/sh\n#unrelated\n# shellcheck disable=2086\ntrue\necho $1"
prop_filewideAnnotation4 = null $
check "#!/bin/sh\n# shellcheck disable=2086\n#unrelated\ntrue\necho $1"
prop_filewideAnnotation5 = null $
@ -197,6 +213,5 @@ prop_filewideAnnotation8 = null $
prop_sourcePartOfOriginalScript = -- #1181: -x disabled posix warning for 'source'
2039 `elem` checkWithIncludes [("./saywhat.sh", "echo foo")] "#!/bin/sh\nsource ./saywhat.sh"
return []
runTests = $quickCheckAll

View File

@ -52,11 +52,20 @@ emptyCheckSpec = CheckSpec {
csShellTypeOverride = Nothing
}
newParseSpec :: ParseSpec
newParseSpec = ParseSpec {
psFilename = "",
psScript = "",
psCheckSourced = False,
psShellTypeOverride = Nothing
}
-- Parser input and output
data ParseSpec = ParseSpec {
psFilename :: String,
psScript :: String,
psCheckSourced :: Bool
psCheckSourced :: Bool,
psShellTypeOverride :: Maybe Shell
} deriving (Show, Eq)
data ParseResult = ParseResult {

View File

@ -305,7 +305,8 @@ initialSystemState = SystemState {
data Environment m = Environment {
systemInterface :: SystemInterface m,
checkSourced :: Bool
checkSourced :: Bool,
shellTypeOverride :: Maybe Shell
}
parseProblem level code msg = do
@ -2965,17 +2966,24 @@ readScriptFile = do
parseProblem ErrorC 1082
"This file has a UTF-8 BOM. Remove it with: LC_CTYPE=C sed '1s/^...//' < yourscript ."
sb <- option "" readShebang
verifyShell pos (getShell sb)
if isValidShell (getShell sb) /= Just False
allspacing
annotationStart <- startSpan
annotations <- readAnnotations
annotationId <- endSpan annotationStart
let shellAnnotationSpecified =
any (\x -> case x of ShellOverride {} -> True; _ -> False) annotations
shellFlagSpecified <- isJust <$> Mr.asks shellTypeOverride
let ignoreShebang = shellAnnotationSpecified || shellFlagSpecified
unless ignoreShebang $
verifyShebang pos (getShell sb)
if ignoreShebang || isValidShell (getShell sb) /= Just False
then do
allspacing
annotationStart <- startSpan
annotations <- readAnnotations
annotationId <- endSpan annotationStart
commands <- withAnnotations annotations readCompoundListOrEmpty
id <- endSpan start
verifyEof
let script = T_Annotation annotationId annotations $ T_Script id sb commands
let script = T_Annotation annotationId annotations $
T_Script id sb commands
reparseIndices script
else do
many anyChar
@ -2993,7 +3001,7 @@ readScriptFile = do
then second
else basename first
verifyShell pos s =
verifyShebang pos s = do
case isValidShell s of
Just True -> return ()
Just False -> parseProblemAt pos ErrorC 1071 "ShellCheck only supports sh/bash/dash/ksh scripts. Sorry!"
@ -3055,16 +3063,16 @@ debugParseScript string =
}
where
result = runIdentity $
parseScript (mockedSystemInterface []) $ ParseSpec {
parseScript (mockedSystemInterface []) $ newParseSpec {
psFilename = "debug",
psScript = string,
psCheckSourced = False
psScript = string
}
testEnvironment =
Environment {
systemInterface = (mockedSystemInterface []),
checkSourced = False
checkSourced = False,
shellTypeOverride = Nothing
}
@ -3230,7 +3238,8 @@ parseScript sys spec =
where
env = Environment {
systemInterface = sys,
checkSourced = psCheckSourced spec
checkSourced = psCheckSourced spec,
shellTypeOverride = psShellTypeOverride spec
}
-- Same as 'try' but emit syntax errors if the parse fails.