Fix incorrect echo options handling.

Reported by: Yves Blusseau.

	* include/grub/command.h (grub_command_flags_t): New flags
	GRUB_COMMAND_ACCEPT_DASH and GRUB_COMMAND_OPTIONS_AT_START.
	* grub-core/lib/arg.c (grub_arg_parse): Handle new flags.
	* grub-core/commands/echo.c (GRUB_MOD_INIT): Use new flags.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-09-14 23:30:06 +02:00
parent ed80f7d586
commit 79c4eeb919
4 changed files with 48 additions and 8 deletions

View file

@ -1,3 +1,13 @@
2010-09-14 Vladimir Serbinenko <phcoder@gmail.com>
Fix incorrect echo options handling.
Reported by: Yves Blusseau.
* include/grub/command.h (grub_command_flags_t): New flags
GRUB_COMMAND_ACCEPT_DASH and GRUB_COMMAND_OPTIONS_AT_START.
* grub-core/lib/arg.c (grub_arg_parse): Handle new flags.
* grub-core/commands/echo.c (GRUB_MOD_INIT): Use new flags.
2010-09-14 Vladimir Serbinenko <phcoder@gmail.com> 2010-09-14 Vladimir Serbinenko <phcoder@gmail.com>
* include/grub/command.h (GRUB_COMMAND_FLAG_CMDLINE): Removed. All * include/grub/command.h (GRUB_COMMAND_FLAG_CMDLINE): Removed. All

View file

@ -113,7 +113,9 @@ static grub_extcmd_t cmd;
GRUB_MOD_INIT(echo) GRUB_MOD_INIT(echo)
{ {
cmd = grub_register_extcmd ("echo", grub_cmd_echo, 0, cmd = grub_register_extcmd ("echo", grub_cmd_echo,
GRUB_COMMAND_ACCEPT_DASH
| GRUB_COMMAND_OPTIONS_AT_START,
N_("[-e|-n] STRING"), N_("Display a line of text."), N_("[-e|-n] STRING"), N_("Display a line of text."),
options); options);
} }

View file

@ -231,7 +231,6 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv,
{ {
int curarg; int curarg;
int arglen; int arglen;
int complete = 0;
char **argl = 0; char **argl = 0;
int num = 0; int num = 0;
auto grub_err_t add_arg (char *s); auto grub_err_t add_arg (char *s);
@ -258,7 +257,8 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv,
char *option = 0; char *option = 0;
/* No option is used. */ /* No option is used. */
if (arg[0] != '-' || grub_strlen (arg) == 1) if ((num && GRUB_COMMAND_OPTIONS_AT_START)
|| arg[0] != '-' || grub_strlen (arg) == 1)
{ {
if (add_arg (arg) != 0) if (add_arg (arg) != 0)
goto fail; goto fail;
@ -269,11 +269,28 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv,
/* One or more short options. */ /* One or more short options. */
if (arg[1] != '-') if (arg[1] != '-')
{ {
char *curshort = arg + 1; char *curshort;
if (cmd->cmd->flags & GRUB_COMMAND_ACCEPT_DASH)
{
for (curshort = arg + 1; *curshort; curshort++)
if (!find_short (cmd->options, *curshort))
break;
if (*curshort)
{
if (add_arg (arg) != 0)
goto fail;
continue;
}
}
curshort = arg + 1;
while (1) while (1)
{ {
opt = find_short (cmd->options, *curshort); opt = find_short (cmd->options, *curshort);
if (! opt) if (! opt)
{ {
grub_error (GRUB_ERR_BAD_ARGUMENT, grub_error (GRUB_ERR_BAD_ARGUMENT,
@ -330,6 +347,14 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv,
} }
opt = find_long (cmd->options, arg + 2, arglen); opt = find_long (cmd->options, arg + 2, arglen);
if (!opt && (cmd->cmd->flags & GRUB_COMMAND_ACCEPT_DASH))
{
if (add_arg (arg) != 0)
goto fail;
continue;
}
if (! opt) if (! opt)
{ {
grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown argument `%s'", arg); grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown argument `%s'", arg);
@ -398,13 +423,12 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv,
} }
} }
complete = 1;
*args = argl; *args = argl;
*argnum = num; *argnum = num;
return 1;
fail: fail:
return complete; return 0;
} }
struct grub_arg_list* struct grub_arg_list*

View file

@ -30,7 +30,11 @@ typedef enum grub_command_flags
/* This is an dynamic command. */ /* This is an dynamic command. */
GRUB_COMMAND_FLAG_DYNCMD = 0x20, GRUB_COMMAND_FLAG_DYNCMD = 0x20,
/* This command accepts block arguments. */ /* This command accepts block arguments. */
GRUB_COMMAND_FLAG_BLOCKS = 0x40 GRUB_COMMAND_FLAG_BLOCKS = 0x40,
/* This command accepts unknown arguments as direct parameters. */
GRUB_COMMAND_ACCEPT_DASH = 0x80,
/* This command accepts only options preceding direct arguments. */
GRUB_COMMAND_OPTIONS_AT_START = 0x100,
} grub_command_flags_t; } grub_command_flags_t;
struct grub_command; struct grub_command;