From 192812ef513a40d6fe76e5e0e95edfab1dac2f92 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Tue, 20 Sep 2016 08:57:14 +0200 Subject: [PATCH] Fix a possible crash in the getopt_long reimplementation. --- src/util/getopt.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/util/getopt.c b/src/util/getopt.c index 444d672..93dcc08 100644 --- a/src/util/getopt.c +++ b/src/util/getopt.c @@ -1,7 +1,7 @@ /* * zzuf - general purpose fuzzer * - * Copyright © 2002—2015 Sam Hocevar + * Copyright © 2002—2016 Sam Hocevar * * This program is free software. It comes without any warranty, to * the extent permitted by applicable law. You can redistribute it @@ -19,7 +19,7 @@ #include #include -#if defined HAVE_GETOPT_H && defined HAVE_GETOPT_LONG +#if HAVE_GETOPT_H && HAVE_GETOPT_LONG # include #endif #include @@ -32,7 +32,7 @@ char *zz_optarg = NULL; int zz_getopt(int argc, char * const _argv[], char const *optstring, zzuf_option_t const *longopts, int *longindex) { -#if defined HAVE_GETOPT_LONG +#if HAVE_GETOPT_LONG optind = zz_optind; optarg = zz_optarg; int ret = getopt_long(argc, _argv, optstring, @@ -68,8 +68,10 @@ int zz_getopt(int argc, char * const _argv[], char const *optstring, { if (flag[2] != '\0') zz_optarg = flag + 2; - else + else if (zz_optind < argc) zz_optarg = argv[zz_optind++]; + else + goto too_few; return ret; } @@ -110,7 +112,12 @@ int zz_getopt(int argc, char * const _argv[], char const *optstring, *longindex = i; zz_optind++; if (longopts[i].has_arg) - zz_optarg = argv[zz_optind++]; + { + if (zz_optind < argc) + zz_optarg = argv[zz_optind++]; + else + goto too_few; + } return longopts[i].val; default: break; @@ -119,6 +126,11 @@ int zz_getopt(int argc, char * const _argv[], char const *optstring, bad_opt: fprintf(stderr, "%s: unrecognized option `%s'\n", argv[0], flag); return '?'; + + too_few: + fprintf(stderr, "%s: option `%s' requires an argument\n", + argv[0], flag); + return '?'; } return -1;