Fix a possible crash in the getopt_long reimplementation.
This commit is contained in:
parent
6ca3b49e69
commit
192812ef51
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* zzuf - general purpose fuzzer
|
* zzuf - general purpose fuzzer
|
||||||
*
|
*
|
||||||
* Copyright © 2002—2015 Sam Hocevar <sam@hocevar.net>
|
* Copyright © 2002—2016 Sam Hocevar <sam@hocevar.net>
|
||||||
*
|
*
|
||||||
* This program is free software. It comes without any warranty, to
|
* This program is free software. It comes without any warranty, to
|
||||||
* the extent permitted by applicable law. You can redistribute it
|
* the extent permitted by applicable law. You can redistribute it
|
||||||
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#if defined HAVE_GETOPT_H && defined HAVE_GETOPT_LONG
|
#if HAVE_GETOPT_H && HAVE_GETOPT_LONG
|
||||||
# include <getopt.h>
|
# include <getopt.h>
|
||||||
#endif
|
#endif
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -32,7 +32,7 @@ char *zz_optarg = NULL;
|
|||||||
int zz_getopt(int argc, char * const _argv[], char const *optstring,
|
int zz_getopt(int argc, char * const _argv[], char const *optstring,
|
||||||
zzuf_option_t const *longopts, int *longindex)
|
zzuf_option_t const *longopts, int *longindex)
|
||||||
{
|
{
|
||||||
#if defined HAVE_GETOPT_LONG
|
#if HAVE_GETOPT_LONG
|
||||||
optind = zz_optind;
|
optind = zz_optind;
|
||||||
optarg = zz_optarg;
|
optarg = zz_optarg;
|
||||||
int ret = getopt_long(argc, _argv, optstring,
|
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')
|
if (flag[2] != '\0')
|
||||||
zz_optarg = flag + 2;
|
zz_optarg = flag + 2;
|
||||||
else
|
else if (zz_optind < argc)
|
||||||
zz_optarg = argv[zz_optind++];
|
zz_optarg = argv[zz_optind++];
|
||||||
|
else
|
||||||
|
goto too_few;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +112,12 @@ int zz_getopt(int argc, char * const _argv[], char const *optstring,
|
|||||||
*longindex = i;
|
*longindex = i;
|
||||||
zz_optind++;
|
zz_optind++;
|
||||||
if (longopts[i].has_arg)
|
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;
|
return longopts[i].val;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -119,6 +126,11 @@ int zz_getopt(int argc, char * const _argv[], char const *optstring,
|
|||||||
bad_opt:
|
bad_opt:
|
||||||
fprintf(stderr, "%s: unrecognized option `%s'\n", argv[0], flag);
|
fprintf(stderr, "%s: unrecognized option `%s'\n", argv[0], flag);
|
||||||
return '?';
|
return '?';
|
||||||
|
|
||||||
|
too_few:
|
||||||
|
fprintf(stderr, "%s: option `%s' requires an argument\n",
|
||||||
|
argv[0], flag);
|
||||||
|
return '?';
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user