script/execute.c: fix memory leak.

Make sure to continue loop over array after failure to free
allocated strings.

Found by: Coverity scan.
This commit is contained in:
Andrei Borzenkov 2015-01-28 20:35:28 +03:00
parent 2efab86d5a
commit 9883307a52

View file

@ -635,57 +635,77 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist,
{ {
case GRUB_SCRIPT_ARG_TYPE_VAR: case GRUB_SCRIPT_ARG_TYPE_VAR:
case GRUB_SCRIPT_ARG_TYPE_DQVAR: case GRUB_SCRIPT_ARG_TYPE_DQVAR:
values = grub_script_env_get (arg->str, arg->type); {
for (i = 0; values && values[i]; i++) int need_cleanup = 0;
{
if (i != 0 && grub_script_argv_next (&result))
goto fail;
if (arg->type == GRUB_SCRIPT_ARG_TYPE_VAR) values = grub_script_env_get (arg->str, arg->type);
{ for (i = 0; values && values[i]; i++)
int len; {
char ch; if (!need_cleanup)
char *p; {
char *op; if (i != 0 && grub_script_argv_next (&result))
const char *s = values[i]; {
need_cleanup = 1;
goto cleanup;
}
len = grub_strlen (values[i]); if (arg->type == GRUB_SCRIPT_ARG_TYPE_VAR)
/* \? -> \\\? */ {
/* \* -> \\\* */ int len;
/* \ -> \\ */ char ch;
p = grub_malloc (len * 2 + 1); char *p;
if (! p) char *op;
goto fail; const char *s = values[i];
op = p; len = grub_strlen (values[i]);
while ((ch = *s++)) /* \? -> \\\? */
{ /* \* -> \\\* */
if (ch == '\\') /* \ -> \\ */
{ p = grub_malloc (len * 2 + 1);
*op++ = '\\'; if (! p)
if (*s == '?' || *s == '*') {
*op++ = '\\'; need_cleanup = 1;
} goto cleanup;
*op++ = ch; }
}
*op = '\0';
if (grub_script_argv_append (&result, p, op - p)) op = p;
{ while ((ch = *s++))
grub_free (p); {
goto fail; if (ch == '\\')
} {
} *op++ = '\\';
else if (*s == '?' || *s == '*')
{ *op++ = '\\';
if (append (&result, values[i], 1)) }
goto fail; *op++ = ch;
} }
*op = '\0';
grub_free (values[i]); if (grub_script_argv_append (&result, p, op - p))
} {
grub_free (values); grub_free (p);
break; need_cleanup = 1;
/* Fall through to cleanup */
}
}
else
{
if (append (&result, values[i], 1))
need_cleanup = 1;
/* Fall through to cleanup */
}
}
cleanup:
grub_free (values[i]);
}
grub_free (values);
if (need_cleanup)
goto fail;
break;
}
case GRUB_SCRIPT_ARG_TYPE_BLOCK: case GRUB_SCRIPT_ARG_TYPE_BLOCK:
{ {