From 3342902d9a354c71ba72a939af82d535f043d079 Mon Sep 17 00:00:00 2001
From: ArenM <aren@peacevolution.org>
Date: Thu, 17 Nov 2022 18:06:10 -0500
Subject: [PATCH 1/2] Warn about 'read' without a variable in POSIX sh

Dash throws an error if the read command isn't supplied a variable name.
---
 src/ShellCheck/Checks/ShellSupport.hs | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/src/ShellCheck/Checks/ShellSupport.hs b/src/ShellCheck/Checks/ShellSupport.hs
index 30a19b9..eda6882 100644
--- a/src/ShellCheck/Checks/ShellSupport.hs
+++ b/src/ShellCheck/Checks/ShellSupport.hs
@@ -184,6 +184,10 @@ prop_checkBashisms96 = verifyNot checkBashisms "#!/bin/dash\necho $_"
 prop_checkBashisms97 = verify checkBashisms "#!/bin/sh\necho ${var,}"
 prop_checkBashisms98 = verify checkBashisms "#!/bin/sh\necho ${var^^}"
 prop_checkBashisms99 = verify checkBashisms "#!/bin/dash\necho [^f]oo"
+prop_checkBashisms100 = verify checkBashisms "read -r"
+prop_checkBashisms101 = verify checkBashisms "read"
+prop_checkBashisms102 = verifyNot checkBashisms "read -r foo"
+prop_checkBashisms103 = verifyNot checkBashisms "read foo"
 checkBashisms = ForShell [Sh, Dash] $ \t -> do
     params <- ask
     kludge params t
@@ -284,6 +288,13 @@ checkBashisms = ForShell [Sh, Dash] $ \t -> do
           argString = concat $ oversimplify arg
           flagRegex = mkRegex "^-[eEsn]+$"
 
+    bashism t@(T_SimpleCommand _ _ (cmd:args))
+        | t `isCommand` "read" && length (onlyNames args) == 0 =
+            warnMsg (getId cmd) 3061 "read without a variable is"
+      where
+        notFlag arg = head (concat $ oversimplify arg) /= '-'
+        onlyNames = filter (notFlag)
+
     bashism t@(T_SimpleCommand _ _ (cmd:arg:_))
         | getLiteralString cmd == Just "exec" && "-" `isPrefixOf` concat (oversimplify arg) =
             warnMsg (getId arg) 3038 "exec flags are"

From 46b678fca8f8aac035d04e676f77f1a92f6742f4 Mon Sep 17 00:00:00 2001
From: Vidar Holen <vidar@vidarholen.net>
Date: Sun, 30 Apr 2023 14:37:37 -0700
Subject: [PATCH 2/2] Minor fixes to POSIX read without variable check

---
 src/ShellCheck/Checks/ShellSupport.hs | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/src/ShellCheck/Checks/ShellSupport.hs b/src/ShellCheck/Checks/ShellSupport.hs
index eda6882..cf8acc9 100644
--- a/src/ShellCheck/Checks/ShellSupport.hs
+++ b/src/ShellCheck/Checks/ShellSupport.hs
@@ -188,6 +188,7 @@ prop_checkBashisms100 = verify checkBashisms "read -r"
 prop_checkBashisms101 = verify checkBashisms "read"
 prop_checkBashisms102 = verifyNot checkBashisms "read -r foo"
 prop_checkBashisms103 = verifyNot checkBashisms "read foo"
+prop_checkBashisms104 = verifyNot checkBashisms "read ''"
 checkBashisms = ForShell [Sh, Dash] $ \t -> do
     params <- ask
     kludge params t
@@ -288,13 +289,6 @@ checkBashisms = ForShell [Sh, Dash] $ \t -> do
           argString = concat $ oversimplify arg
           flagRegex = mkRegex "^-[eEsn]+$"
 
-    bashism t@(T_SimpleCommand _ _ (cmd:args))
-        | t `isCommand` "read" && length (onlyNames args) == 0 =
-            warnMsg (getId cmd) 3061 "read without a variable is"
-      where
-        notFlag arg = head (concat $ oversimplify arg) /= '-'
-        onlyNames = filter (notFlag)
-
     bashism t@(T_SimpleCommand _ _ (cmd:arg:_))
         | getLiteralString cmd == Just "exec" && "-" `isPrefixOf` concat (oversimplify arg) =
             warnMsg (getId arg) 3038 "exec flags are"
@@ -390,6 +384,9 @@ checkBashisms = ForShell [Sh, Dash] $ \t -> do
                 let literal = onlyLiteralString format
                 guard $ "%q" `isInfixOf` literal
                 return $ warnMsg (getId format) 3050 "printf %q is"
+
+            when (name == "read" && all isFlag rest) $
+                warnMsg (getId cmd) 3061 "read without a variable is"
       where
         unsupportedCommands = [
             "let", "caller", "builtin", "complete", "compgen", "declare", "dirs", "disown",