From 7bc732b2a2434a43ff35bf893006976ae78d2a70 Mon Sep 17 00:00:00 2001 From: Vidar Holen Date: Mon, 5 Nov 2012 01:08:00 -0800 Subject: [PATCH] Added and fixed checkes related to "$@"/$* --- Shpell/Analytics.hs | 24 ++++++++++++++++++++++-- badcase/forindollarstar | 1 + badcase/unquoteddoubleat | 1 + goodcase/forargs | 1 + goodcase/fornoin | 1 + goodcase/heredoc | 3 +++ 6 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 badcase/forindollarstar create mode 100644 badcase/unquoteddoubleat create mode 100644 goodcase/forargs create mode 100644 goodcase/fornoin create mode 100644 goodcase/heredoc diff --git a/Shpell/Analytics.hs b/Shpell/Analytics.hs index 57a0ce1..d7b791d 100644 --- a/Shpell/Analytics.hs +++ b/Shpell/Analytics.hs @@ -20,7 +20,9 @@ basicChecks = [ checkMissingForQuotes, checkUnquotedExpansions, checkRedirectToSame, - checkShorthandIf + checkShorthandIf, + checkForInDollarStar, + checkUnquotedDollarAt ] modifyMap = modify @@ -73,9 +75,14 @@ checkUuoc (T_Pipeline _ (T_Redirecting _ _ f@(T_SimpleCommand id _ _):_:_)) = checkUuoc _ = return () +isMagicInQuotes (T_DollarVariable _ "@") = True +isMagicInQuotes _ = False + prop_checkForInQuoted = verify checkForInQuoted "for f in \"$(ls)\"; do echo foo; done" +prop_checkForInQuoted2 = verifyNot checkForInQuoted "for f in \"$@\"; do echo foo; done" checkForInQuoted (T_ForIn _ f [T_NormalWord _ [T_DoubleQuoted id list]] _) = - when (any willSplit list) $ addNoteFor id $ Note ErrorC $ "Since you double quoted this, it will not word split, and the loop will only run once" + when (any (\x -> willSplit x && not (isMagicInQuotes x)) list) $ + addNoteFor id $ Note ErrorC $ "Since you double quoted this, it will not word split, and the loop will only run once" checkForInQuoted _ = return () @@ -135,4 +142,17 @@ checkShorthandIf (T_AndIf id _ (T_OrIf _ _ _)) = addNoteFor id $ Note InfoC "Note that A && B || C is not if-then-else. C may run when A is true." checkShorthandIf _ = return () + +prop_checkForInDollarStar = verify checkForInDollarStar "for f in $*; do ..; done" +checkForInDollarStar (T_ForIn _ var [T_NormalWord _ [(T_DollarVariable id "*")]] _) = + addNoteFor id $ Note WarningC $ "Use 'for " ++ var ++ " in \"$@\"; ..' if you want to loop over arguments." +checkForInDollarStar _ = return () + + +prop_checkUnquotedDollarAt = verify checkUnquotedDollarAt "ls $@" +prop_checkUnquotedDollarAt2 = verifyNot checkUnquotedDollarAt "ls \"$@\"" +checkUnquotedDollarAt (T_NormalWord _ [T_DollarVariable id "@"]) = + addNoteFor id $ Note ErrorC $ "Add double quotes around $@, otherwise it's just like $* and breaks on spaces" +checkUnquotedDollarAt _ = return () + lt x = trace (show x) x diff --git a/badcase/forindollarstar b/badcase/forindollarstar new file mode 100644 index 0000000..a030e08 --- /dev/null +++ b/badcase/forindollarstar @@ -0,0 +1 @@ +for f in $*; do echo "$f"; done diff --git a/badcase/unquoteddoubleat b/badcase/unquoteddoubleat new file mode 100644 index 0000000..64903a1 --- /dev/null +++ b/badcase/unquoteddoubleat @@ -0,0 +1 @@ +myapp $@ diff --git a/goodcase/forargs b/goodcase/forargs new file mode 100644 index 0000000..a3393bc --- /dev/null +++ b/goodcase/forargs @@ -0,0 +1 @@ +for f in "$@"; do echo "$f"; done diff --git a/goodcase/fornoin b/goodcase/fornoin new file mode 100644 index 0000000..28562bf --- /dev/null +++ b/goodcase/fornoin @@ -0,0 +1 @@ +for f; do echo "$f"; done diff --git a/goodcase/heredoc b/goodcase/heredoc new file mode 100644 index 0000000..a664927 --- /dev/null +++ b/goodcase/heredoc @@ -0,0 +1,3 @@ +cat << FOO +test +FOO