Fail on trailing text after numbers, such as --width=100mm

Fail on any text after booleans, such as --flag=false

Also fixed reading of memory after the null terminator of a long
option with no = sign in it.
---
 shared/option-parser.c |   89 +++++++++++++++++++++++++++++++++---------------
 1 file changed, 61 insertions(+), 28 deletions(-)

diff --git a/shared/option-parser.c b/shared/option-parser.c
index c00349a..b8e7394 100644
--- a/shared/option-parser.c
+++ b/shared/option-parser.c
@@ -30,53 +30,86 @@
 
 #include "config-parser.h"
 
-static void
+static int
 handle_option(const struct weston_option *option, char *value)
 {
+       char* p;
+
        switch (option->type) {
        case WESTON_OPTION_INTEGER:
-               * (int32_t *) option->data = strtol(value, NULL, 0);
-               return;
+               * (int32_t *) option->data = strtol(value, &p, 0);
+               return *value && !*p;
        case WESTON_OPTION_UNSIGNED_INTEGER:
-               * (uint32_t *) option->data = strtoul(value, NULL, 0);
-               return;
+               * (uint32_t *) option->data = strtoul(value, &p, 0);
+               return *value && !*p;
        case WESTON_OPTION_STRING:
                * (char **) option->data = strdup(value);
-               return;
-       case WESTON_OPTION_BOOLEAN:
-               * (int32_t *) option->data = 1;
-               return;
+               return 1;
        default:
                assert(0);
        }
 }
 
+static int
+long_option(const struct weston_option *options, int count, char* arg)
+{
+       int k, len;
+
+       for (k = 0; k < count; k++) {
+               if (!options[k].name)
+                       continue;
+               len = strlen(options[k].name);
+               if (strncmp(options[k].name, arg + 2, len) != 0)
+                       continue;
+               if (options[k].type == WESTON_OPTION_BOOLEAN) {
+                       if (!arg[len + 2]) {
+                               * (int32_t *) options[k].data = 1;
+                               return 1;
+                       }
+               } else if (arg[len+2] == '=') {
+                       return handle_option(options + k, arg + len + 3);
+               }
+       }
+       return 0;
+}
+
+static int
+short_option(const struct weston_option *options, int count, char* arg)
+{
+       int k;
+
+       if (!arg[1])
+               return 0;
+       for (k = 0; k < count; k++) {
+               if (options[k].short_name != arg[1])
+                       continue;
+               if (options[k].type == WESTON_OPTION_BOOLEAN) {
+                       if (!arg[2]) {
+                               * (int32_t *) options[k].data = 1;
+                               return 1;
+                       }
+               } else {
+                       return handle_option(options + k, arg + 2);
+               }
+       }
+       return 0;
+}
+
 int
 parse_options(const struct weston_option *options,
              int count, int *argc, char *argv[])
 {
-       int i, j, k, len = 0;
+       int i, j;
 
        for (i = 1, j = 1; i < *argc; i++) {
-               for (k = 0; k < count; k++) {
-                       if (options[k].name)
-                               len = strlen(options[k].name);
-                       if (options[k].name &&
-                           argv[i][0] == '-' &&
-                           argv[i][1] == '-' &&
-                           strncmp(options[k].name, &argv[i][2], len) == 0 &&
-                           (argv[i][len + 2] == '=' || argv[i][len + 2] == 
'\0')) {
-                               handle_option(&options[k], &argv[i][len + 3]);
-                               break;
-                       } else if (options[k].short_name &&
-                                  argv[i][0] == '-' &&
-                                  options[k].short_name == argv[i][1]) {
-                               handle_option(&options[k], &argv[i][2]);
-                               break;
-                       }
+               if (argv[i][0] == '-') {
+                       if (argv[i][1] == '-') {
+                               if (long_option(options, count, argv[i]))
+                                       continue;
+                       } else if (short_option(options, count, argv[i]))
+                               continue;
                }
-               if (k == count)
-                       argv[j++] = argv[i];
+               argv[j++] = argv[i];
        }
        argv[j] = NULL;
        *argc = j;
-- 
1.7.9.5

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to