From 7b3c4025fb322b290bcd0fb061ac7fbf272e72be Mon Sep 17 00:00:00 2001 From: Vidar Holen Date: Sun, 21 Jan 2018 11:12:22 -0800 Subject: [PATCH] Warn about redirs in the middle of 'find' commands. Fixes #405 --- CHANGELOG.md | 1 + ShellCheck/Checks/Commands.hs | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 775f205..d7a097f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Latest - ??? ### Added +- SC2227: Warn about redirections in the middle of 'find' commands - SC2224,SC2225,SC2226: Warn when using mv/cp/ln without a destination - SC2223: Quote warning specific to `: ${var=value}` - SC1127: Warn about C-style comments diff --git a/ShellCheck/Checks/Commands.hs b/ShellCheck/Checks/Commands.hs index 63d3258..f7ce2dd 100644 --- a/ShellCheck/Checks/Commands.hs +++ b/ShellCheck/Checks/Commands.hs @@ -89,6 +89,7 @@ commandChecks = [ ,checkCatastrophicRm ,checkLetUsage ,checkMvArguments, checkCpArguments, checkLnArguments + ,checkFindRedirections ] buildCommandMap :: [CommandCheck] -> Map.Map CommandName (Token -> Analysis) @@ -887,5 +888,23 @@ checkLnArguments = CommandCheck (Basename "ln") $ missingDestination f f t = warn (getId t) 2226 "This ln has no destination. Check the arguments, or specify '.' explicitly." +prop_checkFindRedirections1 = verify checkFindRedirections "find . -exec echo {} > file \\;" +prop_checkFindRedirections2 = verifyNot checkFindRedirections "find . -exec echo {} \\; > file" +prop_checkFindRedirections3 = verifyNot checkFindRedirections "find . -execdir sh -c 'foo > file' \\;" +checkFindRedirections = CommandCheck (Basename "find") f + where + f t = do + redirecting <- getClosestCommandM t + case redirecting of + Just (T_Redirecting _ redirs@(_:_) (T_SimpleCommand _ _ args@(_:_:_))) -> do + -- This assumes IDs are sequential, which is mostly but not always true. + let minRedir = minimum $ map getId redirs + let maxArg = maximum $ map getId args + when (minRedir < maxArg) $ + warn minRedir 2227 + "Redirection applies to the find command itself. Rewrite to work per action (or move to end)." + _ -> return () + + return [] runTests = $( [| $(forAllProperties) (quickCheckWithResult (stdArgs { maxSuccess = 1 }) ) |]) -- GitLab