mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-12 22:11:29 +02:00
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 <wk@gnupg.org> [ This is a backport of 0d73a242cb53522669cf712b5ece7d1ed05d003a from master to STABLE-BRANCH-2-0 ] Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
This commit is contained in:
parent
2f3de06ff4
commit
25e2b27b00
@ -27,6 +27,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include "libjnlib-config.h"
|
#include "libjnlib-config.h"
|
||||||
#include "mischelp.h"
|
#include "mischelp.h"
|
||||||
@ -198,6 +201,8 @@ initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno )
|
|||||||
s = _("keyword too long");
|
s = _("keyword too long");
|
||||||
else if ( arg->r_opt == ARGPARSE_MISSING_ARG )
|
else if ( arg->r_opt == ARGPARSE_MISSING_ARG )
|
||||||
s = _("missing argument");
|
s = _("missing argument");
|
||||||
|
else if ( arg->r_opt == ARGPARSE_INVALID_ARG )
|
||||||
|
s = _("invalid argument");
|
||||||
else if ( arg->r_opt == ARGPARSE_INVALID_COMMAND )
|
else if ( arg->r_opt == ARGPARSE_INVALID_COMMAND )
|
||||||
s = _("invalid command");
|
s = _("invalid command");
|
||||||
else if ( arg->r_opt == ARGPARSE_INVALID_ALIAS )
|
else if ( arg->r_opt == ARGPARSE_INVALID_ALIAS )
|
||||||
@ -214,6 +219,8 @@ initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno )
|
|||||||
|
|
||||||
if ( arg->r_opt == ARGPARSE_MISSING_ARG )
|
if ( arg->r_opt == ARGPARSE_MISSING_ARG )
|
||||||
jnlib_log_error (_("missing argument for option \"%.50s\"\n"), s);
|
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 )
|
else if ( arg->r_opt == ARGPARSE_UNEXPECTED_ARG )
|
||||||
jnlib_log_error (_("option \"%.50s\" does not expect an "
|
jnlib_log_error (_("option \"%.50s\" does not expect an "
|
||||||
"argument\n"), s );
|
"argument\n"), s );
|
||||||
@ -524,7 +531,7 @@ optfile_parse (FILE *fp, const char *filename, unsigned *lineno,
|
|||||||
p[strlen(p)-1] = 0;
|
p[strlen(p)-1] = 0;
|
||||||
}
|
}
|
||||||
if (!set_opt_arg (arg, opts[idx].flags, p))
|
if (!set_opt_arg (arg, opts[idx].flags, p))
|
||||||
jnlib_free(buffer);
|
jnlib_free(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -966,23 +973,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
|
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;
|
int base = (flags & ARGPARSE_OPT_PREFIX)? 0 : 10;
|
||||||
|
long l;
|
||||||
|
|
||||||
switch ( (arg->r_type = (flags & ARGPARSE_TYPE_MASK)) )
|
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:
|
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;
|
return 0;
|
||||||
|
|
||||||
case ARGPARSE_TYPE_ULONG:
|
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;
|
return 0;
|
||||||
|
|
||||||
case ARGPARSE_TYPE_STRING:
|
case ARGPARSE_TYPE_STRING:
|
||||||
default:
|
default:
|
||||||
arg->r.ret_str = s;
|
arg->r.ret_str = s;
|
||||||
|
@ -177,6 +177,7 @@ typedef struct
|
|||||||
#define ARGPARSE_AMBIGUOUS_COMMAND (-9)
|
#define ARGPARSE_AMBIGUOUS_COMMAND (-9)
|
||||||
#define ARGPARSE_INVALID_ALIAS (-10)
|
#define ARGPARSE_INVALID_ALIAS (-10)
|
||||||
#define ARGPARSE_OUT_OF_CORE (-11)
|
#define ARGPARSE_OUT_OF_CORE (-11)
|
||||||
|
#define ARGPARSE_INVALID_ARG (-12)
|
||||||
|
|
||||||
|
|
||||||
int arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts);
|
int arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user