From: Richard Levitte Date: Fri, 18 Jun 2021 08:54:01 +0000 (+0200) Subject: APPS: Make fallback opt_[u]intmax() implementations based on long X-Git-Tag: openssl-3.0.0-beta2~243 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2086818a3142510031f58cfac85747d0393637ed;p=thirdparty%2Fopenssl.git APPS: Make fallback opt_[u]intmax() implementations based on long Also ensure that opt_intmax() and opt_uintmax() does the right thing if sizeof([u]intmax_t) is smaller than sizeof(ossl_[u]intmax_t). Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/15825) --- diff --git a/apps/include/opt.h b/apps/include/opt.h index 4a292213fd9..ce0e35cd722 100644 --- a/apps/include/opt.h +++ b/apps/include/opt.h @@ -375,17 +375,8 @@ int opt_int(const char *arg, int *result); int opt_int_arg(void); int opt_long(const char *arg, long *result); int opt_ulong(const char *arg, unsigned long *result); -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \ - defined(INTMAX_MAX) && defined(UINTMAX_MAX) && \ - !defined(OPENSSL_NO_INTTYPES_H) -int opt_intmax(const char *arg, intmax_t *result); -int opt_uintmax(const char *arg, uintmax_t *result); -#else -# define opt_intmax opt_long -# define opt_uintmax opt_ulong -# define intmax_t long -# define uintmax_t unsigned long -#endif +int opt_intmax(const char *arg, ossl_intmax_t *result); +int opt_uintmax(const char *arg, ossl_uintmax_t *result); int opt_isdir(const char *name); int opt_format(const char *s, unsigned long flags, int *result); diff --git a/apps/lib/opt.c b/apps/lib/opt.c index c88c99b5e64..adb0417bd8c 100644 --- a/apps/lib/opt.c +++ b/apps/lib/opt.c @@ -14,6 +14,7 @@ #include "fmt.h" #include "app_libctx.h" #include "internal/nelem.h" +#include "internal/numbers.h" #include #if !defined(OPENSSL_SYS_MSDOS) # include @@ -555,7 +556,7 @@ int opt_long(const char *value, long *result) !defined(OPENSSL_NO_INTTYPES_H) /* Parse an intmax_t, put it into *result; return 0 on failure, else 1. */ -int opt_intmax(const char *value, intmax_t *result) +int opt_intmax(const char *value, ossl_intmax_t *result) { int oerrno = errno; intmax_t m; @@ -565,19 +566,26 @@ int opt_intmax(const char *value, intmax_t *result) m = strtoimax(value, &endp, 0); if (*endp || endp == value - || ((m == INTMAX_MAX || m == INTMAX_MIN) && errno == ERANGE) + || ((m == INTMAX_MAX || m == INTMAX_MIN) + && errno == ERANGE) || (m == 0 && errno != 0)) { opt_number_error(value); errno = oerrno; return 0; } - *result = m; + /* Ensure that the value in |m| is never too big for |*result| */ + if (sizeof(m) > sizeof(*result) + && (m < OSSL_INTMAX_MIN || m > OSSL_INTMAX_MAX)) { + opt_number_error(value); + return 0; + } + *result = (ossl_intmax_t)m; errno = oerrno; return 1; } /* Parse a uintmax_t, put it into *result; return 0 on failure, else 1. */ -int opt_uintmax(const char *value, uintmax_t *result) +int opt_uintmax(const char *value, ossl_uintmax_t *result) { int oerrno = errno; uintmax_t m; @@ -593,10 +601,37 @@ int opt_uintmax(const char *value, uintmax_t *result) errno = oerrno; return 0; } - *result = m; + /* Ensure that the value in |m| is never too big for |*result| */ + if (sizeof(m) > sizeof(*result) + && m > OSSL_UINTMAX_MAX) { + opt_number_error(value); + return 0; + } + *result = (ossl_intmax_t)m; errno = oerrno; return 1; } +#else +/* Fallback implementations based on long */ +int opt_intmax(const char *value, ossl_intmax_t *result) +{ + long m; + int ret; + + if ((ret = opt_long(value, &m))) + *result = m; + return ret; +} + +int opt_uintmax(const char *value, ossl_uintmax_t *result) +{ + unsigned long m; + int ret; + + if ((ret = opt_ulong(value, &m))) + *result = m; + return ret; +} #endif /*