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)
This commit is contained in:
Richard Levitte 2021-06-18 10:54:01 +02:00 committed by Pauli
parent 08ee6addf7
commit 2086818a31
2 changed files with 42 additions and 16 deletions

View File

@ -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);

View File

@ -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
/*