]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
APPS: Make fallback opt_[u]intmax() implementations based on long
authorRichard Levitte <levitte@openssl.org>
Fri, 18 Jun 2021 08:54:01 +0000 (10:54 +0200)
committerPauli <pauli@openssl.org>
Tue, 22 Jun 2021 09:50:04 +0000 (19:50 +1000)
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)

apps/include/opt.h
apps/lib/opt.c

index 4a292213fd9042d21926c3fd422d9814ff1b2b5e..ce0e35cd7223221cc023343fe45bf6883f7c6360 100644 (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);
index c88c99b5e6425fb2b4ebef413c87540caeab1c8d..adb0417bd8ca163809fb9bc7c61af9c8986da76d 100644 (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
 
 /*