[cli] Fix parsing of commands with trailing whitespaces.
authorMatthias Bolte <matthias.bolte@googlemail.com>
Sat, 11 Apr 2009 13:59:30 +0000 (15:59 +0200)
committerMatthias Bolte <matthias.bolte@googlemail.com>
Sat, 11 Apr 2009 13:59:30 +0000 (15:59 +0200)
  * A trailing whitespace was parsed as empty command, resulting
    in a segfault when trying to execute it.

Signed-off-by: Matthias Bolte <matthias.bolte@googlemail.com>

cli/command.c
cli/core.c
cli/option.c
cli/option.h
include/libvsccli/command.h

index 8b971a3..e344fe7 100644 (file)
@@ -128,17 +128,18 @@ vsc_cli_command_list_free (struct VscCliCommand **command_list)
                       (VscList_FreeFunction) _command_free);
 }
 
-void
+int /* command_parsed */
 vsc_cli_command_parse (struct VscError *error,
                        const char *input, const char **input_tail,
                        struct VscCliCommand *command)
 {
        int i;
+       int command_parsed = TRUE;
        char *command_name = NULL;
        const struct VscCliCommandInfo *command_info;
        const struct VscCliOptionInfo *option_info;
        struct VscCliOption option;
-       int num_options_parsed;
+       int option_parsed;
        int data_option_index = 0;
 
        VSC__ASSERT (error != NULL);
@@ -187,7 +188,7 @@ vsc_cli_command_parse (struct VscError *error,
         * Parse command options.
         */
        while (TRUE) {
-               num_options_parsed =
+               option_parsed =
                   _vsc_cli_option_parse (error, command_info->option_infos,
                                          data_option_index, command_name, *input_tail,
                                          input_tail, &option);
@@ -197,7 +198,7 @@ vsc_cli_command_parse (struct VscError *error,
                        goto failure;
                }
 
-               if (num_options_parsed > 0) {
+               if (option_parsed) {
                        if (option.info->type == VSC_CLI__OPTION_TYPE__DATA) {
                                ++data_option_index;
                        }
@@ -239,10 +240,12 @@ vsc_cli_command_parse (struct VscError *error,
 cleanup:
        vsc_free (&command_name);
 
-       return;
+       return command_parsed;
 
 failure:
        vsc_cli_option_list_free (&command->option_list);
 
+       command_parsed = FALSE;
+
        goto cleanup;
 }
index 1987988..eeae6fd 100644 (file)
@@ -270,7 +270,7 @@ struct VscCliOption * /* option_list */
 vsc_cli_parse_option_list (struct VscError *error, const char *input,
                            const char **input_tail)
 {
-       int num_options_parsed;
+       int option_parsed;
        struct VscCliOption option;
        struct VscCliOption *option_list = NULL;
 
@@ -282,7 +282,7 @@ vsc_cli_parse_option_list (struct VscError *error, const char *input,
        *input_tail = input;
 
        while (*input_tail != NULL && **input_tail != '\0') {
-               num_options_parsed =
+               option_parsed =
                   _vsc_cli_option_parse (error, _vsc_cli_option_infos, -1, NULL,
                                          *input_tail, input_tail, &option);
 
@@ -291,7 +291,7 @@ vsc_cli_parse_option_list (struct VscError *error, const char *input,
                        goto failure;
                }
 
-               if (num_options_parsed > 0) {
+               if (option_parsed) {
                        if (strcmp (option.info->long_name,
                                    VSC_CLI__VERBOSE_ERRORS__OPTION_INFO__LONG_NAME) == 0) {
                                _verbose_errors = TRUE;
@@ -324,6 +324,7 @@ struct VscCliCommand * /* command_list */
 vsc_cli_parse_command_list (struct VscError *error, const char *input,
                             const char **input_tail)
 {
+       int command_parsed;
        struct VscCliCommand command;
        struct VscCliCommand *command_list = NULL;
 
@@ -335,19 +336,24 @@ vsc_cli_parse_command_list (struct VscError *error, const char *input,
        *input_tail = input;
 
        while (*input_tail != NULL && **input_tail != '\0') {
-               vsc_cli_command_parse (error, *input_tail, input_tail, &command);
+               command_parsed =
+                  vsc_cli_command_parse (error, *input_tail, input_tail, &command);
 
                if (error->occured) {
                        VSC__APPEND_ERROR0 (error, VSC__ERROR_CODE__TRACE);
                        goto failure;
                }
 
-               _vsc_cli_command_list_append (error, &command_list, &command);
-               vsc_cli_option_list_free (&command.option_list);
+               if (command_parsed) {
+                       _vsc_cli_command_list_append (error, &command_list, &command);
+                       vsc_cli_option_list_free (&command.option_list);
 
-               if (error->occured) {
-                       VSC__APPEND_ERROR0 (error, VSC__ERROR_CODE__TRACE);
-                       goto failure;
+                       if (error->occured) {
+                               VSC__APPEND_ERROR0 (error, VSC__ERROR_CODE__TRACE);
+                               goto failure;
+                       }
+               } else {
+                       break;
                }
        }
 
index 3f9baa5..0b3064e 100644 (file)
@@ -79,14 +79,14 @@ _vsc_cli_option_syntax (const struct VscCliOptionInfo *option_info,
        return buffer3;
 }
 
-int /* num_options_parsed */
+int /* option_parsed */
 _vsc_cli_option_parse (struct VscError *error,
                        const struct VscCliOptionInfo *option_infos,
                        int data_option_index, const char *command_name,
                        const char *input, const char **input_tail,
                        struct VscCliOption *option)
 {
-       int num_options_parsed = 1;
+       int option_parsed = TRUE;
        const struct VscCliOptionInfo *option_info;
        const char *tail = NULL;
        char *token = NULL;
@@ -109,7 +109,7 @@ _vsc_cli_option_parse (struct VscError *error,
        }
 
        if (token == NULL) {
-               return 0;
+               return FALSE;
        }
 
        memset (option, 0, sizeof (struct VscCliOption));
@@ -231,22 +231,22 @@ _vsc_cli_option_parse (struct VscError *error,
                        goto failure;
                }
        } else {
-               num_options_parsed = 0;
+               option_parsed = FALSE;
        }
 
-       if (num_options_parsed > 0) {
+       if (option_parsed) {
                *input_tail = tail;
        }
 
 cleanup:
        vsc_free (&token);
 
-       return num_options_parsed;
+       return option_parsed;
 
 failure:
        vsc_free (&option->string);
 
-       num_options_parsed = -1;
+       option_parsed = FALSE;
 
        goto cleanup;
 }
index 68c17f1..6965856 100644 (file)
@@ -27,7 +27,7 @@ const char *
 _vsc_cli_option_syntax (const struct VscCliOptionInfo *option_info,
                         int synopsis);
 
-int /* num_options_parsed */
+int /* option_parsed */
 _vsc_cli_option_parse (struct VscError *error,
                        const struct VscCliOptionInfo *option_infos,
                        int data_option_index, const char *command_name,
index 1eb1ce9..e9660cd 100644 (file)
@@ -30,7 +30,7 @@ extern "C" {
 void
 vsc_cli_command_list_free (struct VscCliCommand **command_list);
 
-void
+int /* command_parsed */
 vsc_cli_command_parse (struct VscError *error, const char *input,
                        const char **input_tail, struct VscCliCommand *command);