From 081b2a821bdaa3964a094b6372640751943fdb9e Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Wed, 16 Nov 2016 00:58:05 +0000 Subject: [PATCH] Introduce string_to_uint_ex and string_to_uint_upto functions * defs.h (string_to_uint_ex): New prototype. (string_to_uint_upto): New function, a thin wrapper around string_to_uint_ex. * util.c (string_to_uint_ex): New function. (string_to_uint): Change into a thin wrapper around string_to_uint_upto. * strace.c (init): Use string_to_uint_upto. * syscall.c (qualify_scno, qual_signal, qual_desc): Use string_to_uint_upto instead of string_to_uint. --- defs.h | 8 ++++++++ strace.c | 4 ++-- syscall.c | 22 +++++++++------------- util.c | 29 ++++++++++++++++++++++------- 4 files changed, 41 insertions(+), 22 deletions(-) diff --git a/defs.h b/defs.h index ac61ea39..18217f71 100644 --- a/defs.h +++ b/defs.h @@ -519,7 +519,15 @@ extern const char *xlookup(const struct xlat *, const uint64_t); extern const char *xlat_search(const struct xlat *, const size_t, const uint64_t); extern unsigned long get_pagesize(void); +extern int +string_to_uint_ex(const char *str, char **endptr, + unsigned int max_val, const char *accepted_ending); extern int string_to_uint(const char *str); +static inline int +string_to_uint_upto(const char *const str, unsigned int max_val) +{ + return string_to_uint_ex(str, NULL, max_val, NULL); +} extern int next_set_bit(const void *bit_array, unsigned cur_bit, unsigned size_bits); #define QUOTE_0_TERMINATED 0x01 diff --git a/strace.c b/strace.c index ffb6baec..5a285730 100644 --- a/strace.c +++ b/strace.c @@ -1709,8 +1709,8 @@ init(int argc, char *argv[]) die_out_of_memory(); break; case 'I': - opt_intr = string_to_uint(optarg); - if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS) + opt_intr = string_to_uint_upto(optarg, NUM_INTR_OPTS - 1); + if (opt_intr <= 0) error_opt_arg(c, optarg); break; default: diff --git a/syscall.c b/syscall.c index ba566b11..181e4179 100644 --- a/syscall.c +++ b/syscall.c @@ -431,9 +431,8 @@ static bool qualify_scno(const char *const s, const unsigned int bitflag, const int not) { - unsigned int i; - - if (*s < '0' || *s > '9' || (i = string_to_uint(s)) >= MAX_NSYSCALLS) + int i = string_to_uint_upto(s, MAX_NSYSCALLS - 1); + if (i < 0) return false; qualify_one(i, bitflag, not, -1); @@ -524,8 +523,8 @@ qual_signal(const char *s, const unsigned int bitflag, const int not) unsigned int i; if (*s >= '0' && *s <= '9') { - int signo = string_to_uint(s); - if (signo < 0 || signo > 255) + int signo = string_to_uint_upto(s, 255); + if (signo < 0) return -1; qualify_one(signo, bitflag, not, -1); return 0; @@ -544,14 +543,11 @@ qual_signal(const char *s, const unsigned int bitflag, const int not) static int qual_desc(const char *s, const unsigned int bitflag, const int not) { - if (*s >= '0' && *s <= '9') { - int desc = string_to_uint(s); - if (desc < 0 || desc > 0x7fff) /* paranoia */ - return -1; - qualify_one(desc, bitflag, not, -1); - return 0; - } - return -1; + int desc = string_to_uint_upto(s, 0x7fff); + if (desc < 0) + return -1; + qualify_one(desc, bitflag, not, -1); + return 0; } void diff --git a/util.c b/util.c index f895f227..c75b64cd 100644 --- a/util.c +++ b/util.c @@ -44,18 +44,33 @@ #include "ptrace.h" int -string_to_uint(const char *str) +string_to_uint_ex(const char *const str, char **const endptr, + const unsigned int max_val, const char *const accepted_ending) { - char *error; - long value; + char *end; + long val; if (!*str) return -1; - errno = 0; - value = strtol(str, &error, 10); - if (errno || *error || value < 0 || (long)(int)value != value) + + val = strtol(str, &end, 10); + + if (str == end || val < 0 || (unsigned long) val > max_val) return -1; - return (int)value; + + if (*end && (!accepted_ending || !strchr(accepted_ending, *end))) + return -1; + + if (endptr) + *endptr = end; + + return (int) val; +} + +int +string_to_uint(const char *const str) +{ + return string_to_uint_upto(str, INT_MAX); } int