diff options
author | Werner Koch <[email protected]> | 2014-10-29 16:07:51 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2014-10-29 16:07:51 +0000 |
commit | 0d73a242cb53522669cf712b5ece7d1ed05d003a (patch) | |
tree | ae9494b2b7b11cd349afc7a5400cbdcffdd32be7 /common/argparse.c | |
parent | Fix stdint.h problem for Apple. (diff) | |
download | gnupg-0d73a242cb53522669cf712b5ece7d1ed05d003a.tar.gz gnupg-0d73a242cb53522669cf712b5ece7d1ed05d003a.zip |
common: Check option arguments for a valid range.
* common/argparse.h (ARGPARSE_INVALID_ARG): New.
* common/argparse.c: Include limits h and errno.h.
(initialize): Add error strings for new error constant.
(set_opt_arg): Add range checking.
Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'common/argparse.c')
-rw-r--r-- | common/argparse.c | 53 |
1 files changed, 45 insertions, 8 deletions
diff --git a/common/argparse.c b/common/argparse.c index c713bf609..844c1707e 100644 --- a/common/argparse.c +++ b/common/argparse.c @@ -39,6 +39,8 @@ #include <ctype.h> #include <string.h> #include <stdarg.h> +#include <limits.h> +#include <errno.h> #include "libjnlib-config.h" #include "mischelp.h" @@ -262,6 +264,8 @@ initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno ) s = _("keyword too long"); else if ( arg->r_opt == ARGPARSE_MISSING_ARG ) s = _("missing argument"); + else if ( arg->r_opt == ARGPARSE_INVALID_ARG ) + s = _("invalid argument"); else if ( arg->r_opt == ARGPARSE_INVALID_COMMAND ) s = _("invalid command"); else if ( arg->r_opt == ARGPARSE_INVALID_ALIAS ) @@ -278,6 +282,8 @@ initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno ) if ( arg->r_opt == ARGPARSE_MISSING_ARG ) jnlib_log_error (_("missing argument for option \"%.50s\"\n"), s); + else if ( arg->r_opt == ARGPARSE_INVALID_ARG ) + jnlib_log_error (_("invalid argument for option \"%.50s\"\n"), s); else if ( arg->r_opt == ARGPARSE_UNEXPECTED_ARG ) jnlib_log_error (_("option \"%.50s\" does not expect an " "argument\n"), s ); @@ -588,7 +594,7 @@ optfile_parse (FILE *fp, const char *filename, unsigned *lineno, p[strlen(p)-1] = 0; } if (!set_opt_arg (arg, opts[idx].flags, p)) - jnlib_free(buffer); + jnlib_free(buffer); } } break; @@ -1032,23 +1038,54 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts) } - +/* Returns: -1 on error, 0 for an integer type and 1 for a non integer + type argument. */ static int -set_opt_arg(ARGPARSE_ARGS *arg, unsigned flags, char *s) +set_opt_arg (ARGPARSE_ARGS *arg, unsigned flags, char *s) { int base = (flags & ARGPARSE_OPT_PREFIX)? 0 : 10; + long l; switch ( (arg->r_type = (flags & ARGPARSE_TYPE_MASK)) ) { - case ARGPARSE_TYPE_INT: - arg->r.ret_int = (int)strtol(s,NULL,base); - return 0; case ARGPARSE_TYPE_LONG: - arg->r.ret_long= strtol(s,NULL,base); + case ARGPARSE_TYPE_INT: + errno = 0; + l = strtol (s, NULL, base); + if ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE) + { + arg->r_opt = ARGPARSE_INVALID_ARG; + return -1; + } + if (arg->r_type == ARGPARSE_TYPE_LONG) + arg->r.ret_long = l; + else if ( (l < 0 && l < INT_MIN) || l > INT_MAX ) + { + arg->r_opt = ARGPARSE_INVALID_ARG; + return -1; + } + else + arg->r.ret_int = (int)l; return 0; + case ARGPARSE_TYPE_ULONG: - arg->r.ret_ulong= strtoul(s,NULL,base); + while (isascii (*s) && isspace(*s)) + s++; + if (*s == '-') + { + arg->r.ret_ulong = 0; + arg->r_opt = ARGPARSE_INVALID_ARG; + return -1; + } + errno = 0; + arg->r.ret_ulong = strtoul (s, NULL, base); + if (arg->r.ret_ulong == ULONG_MAX && errno == ERANGE) + { + arg->r_opt = ARGPARSE_INVALID_ARG; + return -1; + } return 0; + case ARGPARSE_TYPE_STRING: default: arg->r.ret_str = s; |