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 d2e8753c3..ce973dbde 100644 --- a/script/execute.c +++ b/script/execute.c @@ -318,6 +318,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grub_snprintf (errnobuf, sizeof (errnobuf), "%d", grub_errno); grub_script_env_set ("?", errnobuf); + grub_script_argv_free (&argv); grub_print_error (); return 0; @@ -385,7 +386,8 @@ grub_err_t grub_script_execute_cmdfor (struct grub_script_cmd *cmd) { unsigned i; - int result; + grub_err_t result; + struct grub_script_argv argv; struct grub_script_cmdfor *cmdfor = (struct grub_script_cmdfor *) cmd;