diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 1de4ebc36..36d240083 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -67,7 +67,7 @@ struct grub_script_arg /* An argument vector. */ struct grub_script_argv { - int argc; + unsigned argc; char **args; }; diff --git a/script/argv.c b/script/argv.c index 1ac81f4b8..56274f263 100644 --- a/script/argv.c +++ b/script/argv.c @@ -20,13 +20,29 @@ #include #include -#define ARG_ALLOCATION_UNIT (32 * sizeof (char)) -#define ARGV_ALLOCATION_UNIT (8 * sizeof (void*)) +static unsigned +round_up_exp (unsigned v) +{ + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + + if (sizeof (v) > 4) + v |= v >> 32; + + v++; + v += (v == 0); + + return v; +} void grub_script_argv_free (struct grub_script_argv *argv) { - int i; + unsigned i; if (argv->args) { @@ -48,7 +64,7 @@ grub_script_argv_next (struct grub_script_argv *argv) if (argv->argc == 0) { - p = grub_malloc (ALIGN_UP (2 * sizeof (char *), ARG_ALLOCATION_UNIT)); + p = grub_malloc (2 * sizeof (char *)); if (! p) return 1; @@ -62,8 +78,7 @@ grub_script_argv_next (struct grub_script_argv *argv) if (! argv->args[argv->argc - 1]) return 0; - p = grub_realloc (p, ALIGN_UP ((argv->argc + 1) * sizeof (char *), - ARG_ALLOCATION_UNIT)); + p = grub_realloc (p, round_up_exp ((argv->argc + 1) * sizeof (char *))); if (! p) return 1; @@ -86,8 +101,7 @@ grub_script_argv_append (struct grub_script_argv *argv, const char *s) a = p ? grub_strlen (p) : 0; b = grub_strlen (s); - p = grub_realloc (p, ALIGN_UP ((a + b + 1) * sizeof (char), - ARG_ALLOCATION_UNIT)); + p = grub_realloc (p, round_up_exp ((a + b + 1) * sizeof (char))); if (! p) return 1; diff --git a/script/execute.c b/script/execute.c index acce5afe9..1ea90ebb0 100644 --- a/script/execute.c +++ b/script/execute.c @@ -99,7 +99,7 @@ grub_script_env_get (const char *name, grub_script_arg_type_t type) } else if (grub_strcmp (name, "*") == 0) { - int i; + unsigned i; for (i = 0; ! errors && i < scope->argv.argc; i++) if (type == GRUB_SCRIPT_ARG_TYPE_VAR) @@ -119,7 +119,7 @@ grub_script_env_get (const char *name, grub_script_arg_type_t type) } else if (grub_strcmp (name, "@") == 0) { - int i; + unsigned i; for (i = 0; ! errors && i < scope->argv.argc; i++) { @@ -312,6 +312,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grub_snprintf (errnobuf, sizeof (errnobuf), "%d", grub_errno); grub_env_set ("?", errnobuf); + grub_script_argv_free (&argv); grub_print_error (); return 0; @@ -378,8 +379,8 @@ grub_script_execute_cmdif (struct grub_script_cmd *cmd) grub_err_t grub_script_execute_cmdfor (struct grub_script_cmd *cmd) { - int i; - int result; + unsigned i; + grub_err_t result; struct grub_script_argv argv; struct grub_script_cmdfor *cmdfor = (struct grub_script_cmdfor *) cmd;