Allow quoting values in directives (fixes #2517)

This commit is contained in:
Vidar Holen 2022-07-28 08:56:44 -07:00
parent f440912279
commit d0dd81e1fa
4 changed files with 33 additions and 6 deletions

View File

@ -17,6 +17,7 @@
based on control flow rather than just syntax. Existing checks will based on control flow rather than just syntax. Existing checks will
gradually start using it, which may cause them to trigger differently gradually start using it, which may cause them to trigger differently
(but more accurately). (but more accurately).
- Values in directives/shellcheckrc can now be quoted with '' or ""
## v0.8.0 - 2021-11-06 ## v0.8.0 - 2021-11-06

View File

@ -282,6 +282,9 @@ Here is an example `.shellcheckrc`:
source-path=SCRIPTDIR source-path=SCRIPTDIR
source-path=/mnt/chroot source-path=/mnt/chroot
# Since 0.9.0, values can be quoted with '' or "" to allow spaces
source-path="My Documents/scripts"
# Allow opening any 'source'd file, even if not specified as input # Allow opening any 'source'd file, even if not specified as input
external-sources=true external-sources=true

View File

@ -244,6 +244,9 @@ prop_canStripPrefixAndSource2 =
prop_canSourceDynamicWhenRedirected = prop_canSourceDynamicWhenRedirected =
null $ checkWithIncludes [("lib", "")] "#shellcheck source=lib\n. \"$1\"" null $ checkWithIncludes [("lib", "")] "#shellcheck source=lib\n. \"$1\""
prop_canRedirectWithSpaces =
null $ checkWithIncludes [("my file", "")] "#shellcheck source=\"my file\"\n. \"$1\""
prop_recursiveAnalysis = prop_recursiveAnalysis =
[2086] == checkRecursive [("lib", "echo $1")] "source lib" [2086] == checkRecursive [("lib", "echo $1")] "source lib"
@ -413,6 +416,15 @@ prop_sourcePathAddsAnnotation = result == [2086]
csCheckSourced = True csCheckSourced = True
} }
prop_sourcePathWorksWithSpaces = result == [2086]
where
f "dir/myscript" _ ["my path"] "lib" = return "foo/lib"
result = checkWithIncludesAndSourcePath [("foo/lib", "echo $1")] f emptyCheckSpec {
csScript = "#!/bin/bash\n# shellcheck source-path='my path'\nsource lib",
csFilename = "dir/myscript",
csCheckSourced = True
}
prop_sourcePathRedirectsDirective = result == [2086] prop_sourcePathRedirectsDirective = result == [2086]
where where
f "dir/myscript" _ _ "lib" = return "foo/lib" f "dir/myscript" _ _ "lib" = return "foo/lib"

View File

@ -992,6 +992,10 @@ prop_readAnnotation5 = isOk readAnnotation "# shellcheck disable=SC2002 # All ca
prop_readAnnotation6 = isOk readAnnotation "# shellcheck disable=SC1234 # shellcheck foo=bar\n" prop_readAnnotation6 = isOk readAnnotation "# shellcheck disable=SC1234 # shellcheck foo=bar\n"
prop_readAnnotation7 = isOk readAnnotation "# shellcheck disable=SC1000,SC2000-SC3000,SC1001\n" prop_readAnnotation7 = isOk readAnnotation "# shellcheck disable=SC1000,SC2000-SC3000,SC1001\n"
prop_readAnnotation8 = isOk readAnnotation "# shellcheck disable=all\n" prop_readAnnotation8 = isOk readAnnotation "# shellcheck disable=all\n"
prop_readAnnotation9 = isOk readAnnotation "# shellcheck source='foo bar' source-path=\"baz etc\"\n"
prop_readAnnotation10 = isOk readAnnotation "# shellcheck disable='SC1234,SC2345' enable=\"foo\" shell='bash'\n"
prop_readAnnotation11 = isOk (readAnnotationWithoutPrefix False) "external-sources='true'"
readAnnotation = called "shellcheck directive" $ do readAnnotation = called "shellcheck directive" $ do
try readAnnotationPrefix try readAnnotationPrefix
many1 linewhitespace many1 linewhitespace
@ -1007,12 +1011,19 @@ readAnnotationWithoutPrefix sandboxed = do
many linewhitespace many linewhitespace
return $ concat values return $ concat values
where where
plainOrQuoted p = quoted p <|> p
quoted p = do
c <- oneOf "'\""
start <- getPosition
str <- many1 $ noneOf (c:"\n")
char c <|> fail "Missing terminating quote for directive."
subParse start p str
readKey = do readKey = do
keyPos <- getPosition keyPos <- getPosition
key <- many1 (letter <|> char '-') key <- many1 (letter <|> char '-')
char '=' <|> fail "Expected '=' after directive key" char '=' <|> fail "Expected '=' after directive key"
annotations <- case key of annotations <- case key of
"disable" -> readElement `sepBy` char ',' "disable" -> plainOrQuoted $ readElement `sepBy` char ','
where where
readElement = readRange <|> readAll readElement = readRange <|> readAll
readAll = do readAll = do
@ -1027,21 +1038,21 @@ readAnnotationWithoutPrefix sandboxed = do
int <- many1 digit int <- many1 digit
return $ read int return $ read int
"enable" -> readName `sepBy` char ',' "enable" -> plainOrQuoted $ readName `sepBy` char ','
where where
readName = EnableComment <$> many1 (letter <|> char '-') readName = EnableComment <$> many1 (letter <|> char '-')
"source" -> do "source" -> do
filename <- many1 $ noneOf " \n" filename <- quoted (many1 anyChar) <|> (many1 $ noneOf " \n")
return [SourceOverride filename] return [SourceOverride filename]
"source-path" -> do "source-path" -> do
dirname <- many1 $ noneOf " \n" dirname <- quoted (many1 anyChar) <|> (many1 $ noneOf " \n")
return [SourcePath dirname] return [SourcePath dirname]
"shell" -> do "shell" -> do
pos <- getPosition pos <- getPosition
shell <- many1 $ noneOf " \n" shell <- quoted (many1 anyChar) <|> (many1 $ noneOf " \n")
when (isNothing $ shellForExecutable shell) $ when (isNothing $ shellForExecutable shell) $
parseNoteAt pos ErrorC 1103 parseNoteAt pos ErrorC 1103
"This shell type is unknown. Use e.g. sh or bash." "This shell type is unknown. Use e.g. sh or bash."
@ -1049,7 +1060,7 @@ readAnnotationWithoutPrefix sandboxed = do
"external-sources" -> do "external-sources" -> do
pos <- getPosition pos <- getPosition
value <- many1 letter value <- plainOrQuoted $ many1 letter
case value of case value of
"true" -> "true" ->
if sandboxed if sandboxed