aboutsummaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2021-06-18 10:54:01 +0200
committerPauli <pauli@openssl.org>2021-06-22 19:50:04 +1000
commit2086818a3142510031f58cfac85747d0393637ed (patch)
tree90db2be0b76548d28f0dd136abf2dc86edd8dc0f /apps
parent08ee6addf7343e7523db47dcc7e84e1670d52e15 (diff)
downloadopenssl-2086818a3142510031f58cfac85747d0393637ed.zip
openssl-2086818a3142510031f58cfac85747d0393637ed.tar.gz
openssl-2086818a3142510031f58cfac85747d0393637ed.tar.bz2
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.h13
-rw-r--r--apps/lib/opt.c45
2 files changed, 42 insertions, 16 deletions
diff --git a/apps/include/opt.h b/apps/include/opt.h
index 4a29221..ce0e35c 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 c88c99b..adb0417 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
/*