diff options
author | Richard Levitte <levitte@openssl.org> | 2021-06-18 10:54:01 +0200 |
---|---|---|
committer | Pauli <pauli@openssl.org> | 2021-06-22 19:50:04 +1000 |
commit | 2086818a3142510031f58cfac85747d0393637ed (patch) | |
tree | 90db2be0b76548d28f0dd136abf2dc86edd8dc0f /apps | |
parent | 08ee6addf7343e7523db47dcc7e84e1670d52e15 (diff) |
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 <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15825)
Diffstat (limited to 'apps')
-rw-r--r-- | apps/include/opt.h | 13 | ||||
-rw-r--r-- | apps/lib/opt.c | 45 |
2 files changed, 42 insertions, 16 deletions
diff --git a/apps/include/opt.h b/apps/include/opt.h index 4a292213fd..ce0e35cd72 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 c88c99b5e6..adb0417bd8 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 <string.h> #if !defined(OPENSSL_SYS_MSDOS) # include <unistd.h> @@ -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 /* |