bio: add a malloc failed error to BIO_print
[openssl.git] / crypto / bio / b_print.c
index 056de8652487a6222f99a8f39cb673bf3caa6a02..ba2c6c5b1fd12ef589d303455ea7a2f5893d1b4b 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
  *
- * Licensed under the OpenSSL license (the "License").  You may not use
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
  * in the file LICENSE in the source distribution or at
  * https://www.openssl.org/source/license.html
@@ -9,9 +9,9 @@
 
 #include <stdio.h>
 #include <string.h>
-#include "internal/ctype.h"
-#include "internal/numbers.h"
 #include "internal/cryptlib.h"
+#include "crypto/ctype.h"
+#include "internal/numbers.h"
 #include <openssl/bio.h>
 
 /*
@@ -111,7 +111,7 @@ _dopr(char **sbuffer,
             if (ch == '%')
                 state = DP_S_FLAGS;
             else
-                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
+                if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
                     return 0;
             ch = *format++;
             break;
@@ -293,8 +293,8 @@ _dopr(char **sbuffer,
                     return 0;
                 break;
             case 'c':
-                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen,
-                            va_arg(args, int)))
+                if (!doapr_outch(sbuffer, buffer, &currlen, maxlen,
+                                 va_arg(args, int)))
                     return 0;
                 break;
             case 's':
@@ -323,12 +323,12 @@ _dopr(char **sbuffer,
                 }
                 break;
             case '%':
-                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
+                if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
                     return 0;
                 break;
             case 'w':
                 /* not supported yet, treat as next char */
-                ch = *format++;
+                format++;
                 break;
             default:
                 /* unknown, skip */
@@ -354,7 +354,7 @@ _dopr(char **sbuffer,
         if (*truncated)
             currlen = *maxlen - 1;
     }
-    if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'))
+    if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'))
         return 0;
     *retlen = currlen - 1;
     return 1;
@@ -392,19 +392,19 @@ fmtstr(char **sbuffer,
         padlen = -padlen;
 
     while ((padlen > 0) && (max < 0 || cnt < max)) {
-        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
             return 0;
         --padlen;
         ++cnt;
     }
     while (strln > 0 && (max < 0 || cnt < max)) {
-        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++))
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++))
             return 0;
         --strln;
         ++cnt;
     }
     while ((padlen < 0) && (max < 0 || cnt < max)) {
-        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
             return 0;
         ++padlen;
         ++cnt;
@@ -472,19 +472,19 @@ fmtint(char **sbuffer,
 
     /* spaces */
     while (spadlen > 0) {
-        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
             return 0;
         --spadlen;
     }
 
     /* sign */
     if (signvalue)
-        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
             return 0;
 
     /* prefix */
     while (*prefix) {
-        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix))
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix))
             return 0;
         prefix++;
     }
@@ -492,7 +492,7 @@ fmtint(char **sbuffer,
     /* zeros */
     if (zpadlen > 0) {
         while (zpadlen > 0) {
-            if(!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+            if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
                 return 0;
             --zpadlen;
         }
@@ -635,7 +635,11 @@ fmtfp(char **sbuffer,
             fvalue = tmpvalue;
     }
     ufvalue = abs_val(fvalue);
-    if (ufvalue > ULONG_MAX) {
+    /*
+     * By subtracting 65535 (2^16-1) we cancel the low order 15 bits
+     * of ULONG_MAX to avoid using imprecise floating point values.
+     */
+    if (ufvalue >= (double)(ULONG_MAX - 65535) + 65536.0) {
         /* Number too big */
         return 0;
     }
@@ -665,7 +669,7 @@ fmtfp(char **sbuffer,
         iconvert[iplace++] = "0123456789"[intpart % 10];
         intpart = (intpart / 10);
     } while (intpart && (iplace < (int)sizeof(iconvert)));
-    if (iplace == sizeof iconvert)
+    if (iplace == sizeof(iconvert))
         iplace--;
     iconvert[iplace] = 0;
 
@@ -683,7 +687,7 @@ fmtfp(char **sbuffer,
         fracpart = (fracpart / 10);
     }
 
-    if (fplace == sizeof fconvert)
+    if (fplace == sizeof(fconvert))
         fplace--;
     fconvert[fplace] = 0;
 
@@ -758,8 +762,8 @@ fmtfp(char **sbuffer,
             return 0;
 
         while (fplace > 0) {
-            if(!doapr_outch(sbuffer, buffer, currlen, maxlen,
-                            fconvert[--fplace]))
+            if (!doapr_outch(sbuffer, buffer, currlen, maxlen,
+                             fconvert[--fplace]))
                 return 0;
         }
     }
@@ -819,9 +823,10 @@ doapr_outch(char **sbuffer,
 
         *maxlen += BUFFER_INC;
         if (*buffer == NULL) {
-            *buffer = OPENSSL_malloc(*maxlen);
-            if (*buffer == NULL)
+            if ((*buffer = OPENSSL_malloc(*maxlen)) == NULL) {
+                ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
                 return 0;
+            }
             if (*currlen > 0) {
                 if (!ossl_assert(*sbuffer != NULL))
                     return 0;
@@ -830,9 +835,12 @@ doapr_outch(char **sbuffer,
             *sbuffer = NULL;
         } else {
             char *tmpbuf;
+
             tmpbuf = OPENSSL_realloc(*buffer, *maxlen);
-            if (tmpbuf == NULL)
+            if (tmpbuf == NULL) {
+                ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
                 return 0;
+            }
             *buffer = tmpbuf;
         }
     }
@@ -913,7 +921,7 @@ int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
     size_t retlen;
     int truncated;
 
-    if(!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args))
+    if (!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args))
         return -1;
 
     if (truncated)
@@ -924,6 +932,5 @@ int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
          * been large enough.)
          */
         return -1;
-    else
-        return (retlen <= INT_MAX) ? (int)retlen : -1;
+    return (retlen <= INT_MAX) ? (int)retlen : -1;
 }