The open-coded check for -v only matches it as the first argument, so
'hash sha256 -v 0 4 <expected>' treats -v as the algorithm name and
fails. Replace with getopt(), which also lets -v appear anywhere in the
command line.

Guard the option-parsing loop with IS_ENABLED(CONFIG_HASH_VERIFY) so it
is compiled out when verification is disabled. After parsing,
getopt_pop() pulls the algorithm off the positional list, strlower()
normalises it, and the tail is forwarded to hash_command() unchanged.

CMD_HASH selects GETOPT so the parser is linked in on boards that did
not already enable it.

Tweak the var declarations to use Reverse Christmas Tree.

Signed-off-by: Simon Glass <[email protected]>
---

 cmd/Kconfig |  1 +
 cmd/hash.c  | 37 +++++++++++++++++++++----------------
 2 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 709696c3c41..eb7c85c1fe9 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -2798,6 +2798,7 @@ config CMD_BLOB
 
 config CMD_HASH
        bool "Support 'hash' command"
+       select GETOPT
        select HASH
        help
          This provides a way to hash data in memory using various supported
diff --git a/cmd/hash.c b/cmd/hash.c
index 96d0e443a5b..566bb617328 100644
--- a/cmd/hash.c
+++ b/cmd/hash.c
@@ -11,8 +11,9 @@
 
 #include <command.h>
 #include <env.h>
+#include <getopt.h>
 #include <hash.h>
-#include <linux/ctype.h>
+#include <linux/string.h>
 
 #if IS_ENABLED(CONFIG_HASH_VERIFY)
 #define HARGS 6
@@ -23,25 +24,29 @@
 static int do_hash(struct cmd_tbl *cmdtp, int flag, int argc,
                   char *const argv[])
 {
-       char *s;
        int flags = HASH_FLAG_ENV;
+       struct getopt_state gs;
+       char *algo;
 
-       if (argc < 4)
-               return CMD_RET_USAGE;
+       getopt_init_state(&gs, argc, argv);
+       if (IS_ENABLED(CONFIG_HASH_VERIFY)) {
+               int opt;
 
-#if IS_ENABLED(CONFIG_HASH_VERIFY)
-       if (!strcmp(argv[1], "-v")) {
-               flags |= HASH_FLAG_VERIFY;
-               argc--;
-               argv++;
+               while ((opt = getopt(&gs, "v")) > 0) {
+                       if (opt != 'v')
+                               return CMD_RET_USAGE;
+                       flags |= HASH_FLAG_VERIFY;
+               }
        }
-#endif
-       /* Move forward to 'algorithm' parameter */
-       argc--;
-       argv++;
-       for (s = *argv; *s; s++)
-               *s = tolower(*s);
-       return hash_command(*argv, flags, cmdtp, flag, argc - 1, argv + 1);
+
+       /* Need at least: algorithm address count */
+       if (gs.nonopts < 3)
+               return CMD_RET_USAGE;
+
+       algo = strlower(getopt_pop(&gs));
+
+       return hash_command(algo, flags, cmdtp, flag,
+                           gs.nonopts, &gs.args[gs.index]);
 }
 
 U_BOOT_CMD(
-- 
2.43.0

Reply via email to