bio/b_print.c: fix %z failure in 32-bit build.
[openssl.git] / crypto / bio / b_print.c
index 545c46981089c13774b8da088149316c909484ee..883af19388e3a01e0ca98a10faab61d774663f71 100644 (file)
@@ -89,6 +89,7 @@ static int _dopr(char **sbuffer, char **buffer,
 #define DP_C_LONG       2
 #define DP_C_LDOUBLE    3
 #define DP_C_LLONG      4
+#define DP_C_SIZE       5
 
 /* Floating point formats */
 #define F_FORMAT        0
@@ -214,6 +215,10 @@ _dopr(char **sbuffer,
                 cflags = DP_C_LDOUBLE;
                 ch = *format++;
                 break;
+            case 'z':
+                cflags = DP_C_SIZE;
+                ch = *format++;
+                break;
             default:
                 break;
             }
@@ -233,6 +238,9 @@ _dopr(char **sbuffer,
                 case DP_C_LLONG:
                     value = va_arg(args, LLONG);
                     break;
+                case DP_C_SIZE:
+                    value = va_arg(args, ossl_ssize_t);
+                    break;
                 default:
                     value = va_arg(args, int);
                     break;
@@ -253,13 +261,16 @@ _dopr(char **sbuffer,
                     value = (unsigned short int)va_arg(args, unsigned int);
                     break;
                 case DP_C_LONG:
-                    value = (LLONG) va_arg(args, unsigned long int);
+                    value = (LLONG)va_arg(args, unsigned long int);
                     break;
                 case DP_C_LLONG:
                     value = va_arg(args, unsigned LLONG);
                     break;
+                case DP_C_SIZE:
+                    value = va_arg(args, size_t);
+                    break;
                 default:
-                    value = (LLONG) va_arg(args, unsigned int);
+                    value = (LLONG)va_arg(args, unsigned int);
                     break;
                 }
                 if (!fmtint(sbuffer, buffer, &currlen, maxlen, value,
@@ -363,9 +374,15 @@ _dopr(char **sbuffer,
             break;
         }
     }
-    *truncated = (currlen > *maxlen - 1);
-    if (*truncated)
-        currlen = *maxlen - 1;
+    /*
+     * We have to truncate if there is no dynamic buffer and we have filled the
+     * static buffer.
+     */
+    if (buffer == NULL) {
+        *truncated = (currlen > *maxlen - 1);
+        if (*truncated)
+            currlen = *maxlen - 1;
+    }
     if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'))
         return 0;
     *retlen = currlen - 1;
@@ -390,8 +407,16 @@ fmtstr(char **sbuffer,
     padlen = min - strln;
     if (min < 0 || padlen < 0)
         padlen = 0;
-    if (max >= 0)
-        max += padlen;      /* The maximum output including padding */
+    if (max >= 0) {
+        /*
+         * Calculate the maximum output including padding.
+         * Make sure max doesn't overflow into negativity
+         */
+        if (max < INT_MAX - padlen)
+            max += padlen;
+        else
+            max = INT_MAX;
+    }
     if (flags & DP_F_MINUS)
         padlen = -padlen;
 
@@ -437,7 +462,7 @@ fmtint(char **sbuffer,
     if (!(flags & DP_F_UNSIGNED)) {
         if (value < 0) {
             signvalue = '-';
-            uvalue = -value;
+            uvalue = 0 - (unsigned LLONG)value;
         } else if (flags & DP_F_PLUS)
             signvalue = '+';
         else if (flags & DP_F_SPACE)