You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
437 lines
13 KiB
437 lines
13 KiB
diff -up openssl-1.0.1e/crypto/bio/b_print.c.bio-printf openssl-1.0.1e/crypto/bio/b_print.c |
|
--- openssl-1.0.1e/crypto/bio/b_print.c.bio-printf 2013-02-11 16:26:04.000000000 +0100 |
|
+++ openssl-1.0.1e/crypto/bio/b_print.c 2016-04-07 14:36:55.538117697 +0200 |
|
@@ -125,14 +125,14 @@ |
|
#define LLONG long |
|
#endif |
|
|
|
-static void fmtstr (char **, char **, size_t *, size_t *, |
|
+static int fmtstr(char **, char **, size_t *, size_t *, |
|
const char *, int, int, int); |
|
-static void fmtint (char **, char **, size_t *, size_t *, |
|
+static int fmtint(char **, char **, size_t *, size_t *, |
|
LLONG, int, int, int, int); |
|
-static void fmtfp (char **, char **, size_t *, size_t *, |
|
+static int fmtfp(char **, char **, size_t *, size_t *, |
|
LDOUBLE, int, int, int); |
|
-static void doapr_outch (char **, char **, size_t *, size_t *, int); |
|
-static void _dopr(char **sbuffer, char **buffer, |
|
+static int doapr_outch(char **, char **, size_t *, size_t *, int); |
|
+static int _dopr(char **sbuffer, char **buffer, |
|
size_t *maxlen, size_t *retlen, int *truncated, |
|
const char *format, va_list args); |
|
|
|
@@ -165,7 +165,7 @@ static void _dopr(char **sbuffer, char * |
|
#define char_to_int(p) (p - '0') |
|
#define OSSL_MAX(p,q) ((p >= q) ? p : q) |
|
|
|
-static void |
|
+static int |
|
_dopr( |
|
char **sbuffer, |
|
char **buffer, |
|
@@ -200,7 +200,8 @@ _dopr( |
|
if (ch == '%') |
|
state = DP_S_FLAGS; |
|
else |
|
- doapr_outch(sbuffer,buffer, &currlen, maxlen, ch); |
|
+ if (!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch)) |
|
+ return 0; |
|
ch = *format++; |
|
break; |
|
case DP_S_FLAGS: |
|
@@ -306,8 +307,9 @@ _dopr( |
|
value = va_arg(args, int); |
|
break; |
|
} |
|
- fmtint(sbuffer, buffer, &currlen, maxlen, |
|
- value, 10, min, max, flags); |
|
+ if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, min, |
|
+ max, flags)) |
|
+ return 0; |
|
break; |
|
case 'X': |
|
flags |= DP_F_UP; |
|
@@ -332,17 +334,19 @@ _dopr( |
|
unsigned int); |
|
break; |
|
} |
|
- fmtint(sbuffer, buffer, &currlen, maxlen, value, |
|
+ if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, |
|
ch == 'o' ? 8 : (ch == 'u' ? 10 : 16), |
|
- min, max, flags); |
|
+ min, max, flags)) |
|
+ return 0; |
|
break; |
|
case 'f': |
|
if (cflags == DP_C_LDOUBLE) |
|
fvalue = va_arg(args, LDOUBLE); |
|
else |
|
fvalue = va_arg(args, double); |
|
- fmtfp(sbuffer, buffer, &currlen, maxlen, |
|
- fvalue, min, max, flags); |
|
+ if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max, |
|
+ flags)) |
|
+ return 0; |
|
break; |
|
case 'E': |
|
flags |= DP_F_UP; |
|
@@ -361,8 +365,9 @@ _dopr( |
|
fvalue = va_arg(args, double); |
|
break; |
|
case 'c': |
|
- 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': |
|
strvalue = va_arg(args, char *); |
|
@@ -372,13 +377,15 @@ _dopr( |
|
else |
|
max = *maxlen; |
|
} |
|
- fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue, |
|
- flags, min, max); |
|
+ if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue, |
|
+ flags, min, max)) |
|
+ return 0; |
|
break; |
|
case 'p': |
|
value = (long)va_arg(args, void *); |
|
- fmtint(sbuffer, buffer, &currlen, maxlen, |
|
- value, 16, min, max, flags|DP_F_NUM); |
|
+ if (!fmtint(sbuffer, buffer, &currlen, maxlen, |
|
+ value, 16, min, max, flags | DP_F_NUM)) |
|
+ return 0; |
|
break; |
|
case 'n': /* XXX */ |
|
if (cflags == DP_C_SHORT) { |
|
@@ -400,7 +407,8 @@ _dopr( |
|
} |
|
break; |
|
case '%': |
|
- 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 */ |
|
@@ -424,12 +432,13 @@ _dopr( |
|
*truncated = (currlen > *maxlen - 1); |
|
if (*truncated) |
|
currlen = *maxlen - 1; |
|
- doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'); |
|
+ if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0')) |
|
+ return 0; |
|
*retlen = currlen - 1; |
|
- return; |
|
+ return 1; |
|
} |
|
|
|
-static void |
|
+static int |
|
fmtstr( |
|
char **sbuffer, |
|
char **buffer, |
|
@@ -440,36 +449,44 @@ fmtstr( |
|
int min, |
|
int max) |
|
{ |
|
- int padlen, strln; |
|
+ int padlen; |
|
+ size_t strln; |
|
int cnt = 0; |
|
|
|
if (value == 0) |
|
value = "<NULL>"; |
|
- for (strln = 0; value[strln]; ++strln) |
|
- ; |
|
+ |
|
+ strln = strlen(value); |
|
+ if (strln > INT_MAX) |
|
+ strln = INT_MAX; |
|
+ |
|
padlen = min - strln; |
|
- if (padlen < 0) |
|
+ if (min < 0 || padlen < 0) |
|
padlen = 0; |
|
if (flags & DP_F_MINUS) |
|
padlen = -padlen; |
|
|
|
while ((padlen > 0) && (cnt < max)) { |
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' '); |
|
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) |
|
+ return 0; |
|
--padlen; |
|
++cnt; |
|
} |
|
while (*value && (cnt < max)) { |
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, *value++); |
|
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++)) |
|
+ return 0; |
|
++cnt; |
|
} |
|
while ((padlen < 0) && (cnt < max)) { |
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' '); |
|
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) |
|
+ return 0; |
|
++padlen; |
|
++cnt; |
|
} |
|
+ return 1; |
|
} |
|
|
|
-static void |
|
+static int |
|
fmtint( |
|
char **sbuffer, |
|
char **buffer, |
|
@@ -533,37 +550,44 @@ fmtint( |
|
|
|
/* spaces */ |
|
while (spadlen > 0) { |
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' '); |
|
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) |
|
+ return 0; |
|
--spadlen; |
|
} |
|
|
|
/* sign */ |
|
if (signvalue) |
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue); |
|
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue)) |
|
+ return 0; |
|
|
|
/* prefix */ |
|
while (*prefix) { |
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix); |
|
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix)) |
|
+ return 0; |
|
prefix++; |
|
} |
|
|
|
/* zeros */ |
|
if (zpadlen > 0) { |
|
while (zpadlen > 0) { |
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, '0'); |
|
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, '0')) |
|
+ return 0; |
|
--zpadlen; |
|
} |
|
} |
|
/* digits */ |
|
- while (place > 0) |
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]); |
|
+ while (place > 0) { |
|
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place])) |
|
+ return 0; |
|
+ } |
|
|
|
/* left justified spaces */ |
|
while (spadlen < 0) { |
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' '); |
|
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) |
|
+ return 0; |
|
++spadlen; |
|
} |
|
- return; |
|
+ return 1; |
|
} |
|
|
|
static LDOUBLE |
|
@@ -597,7 +621,7 @@ roundv(LDOUBLE value) |
|
return intpart; |
|
} |
|
|
|
-static void |
|
+static int |
|
fmtfp( |
|
char **sbuffer, |
|
char **buffer, |
|
@@ -616,7 +640,6 @@ fmtfp( |
|
int fplace = 0; |
|
int padlen = 0; |
|
int zpadlen = 0; |
|
- int caps = 0; |
|
long intpart; |
|
long fracpart; |
|
long max10; |
|
@@ -650,9 +673,7 @@ fmtfp( |
|
|
|
/* convert integer part */ |
|
do { |
|
- iconvert[iplace++] = |
|
- (caps ? "0123456789ABCDEF" |
|
- : "0123456789abcdef")[intpart % 10]; |
|
+ iconvert[iplace++] = "0123456789"[intpart % 10]; |
|
intpart = (intpart / 10); |
|
} while (intpart && (iplace < (int)sizeof(iconvert))); |
|
if (iplace == sizeof iconvert) |
|
@@ -661,9 +682,7 @@ fmtfp( |
|
|
|
/* convert fractional part */ |
|
do { |
|
- fconvert[fplace++] = |
|
- (caps ? "0123456789ABCDEF" |
|
- : "0123456789abcdef")[fracpart % 10]; |
|
+ fconvert[fplace++] = "0123456789"[fracpart % 10]; |
|
fracpart = (fracpart / 10); |
|
} while (fplace < max); |
|
if (fplace == sizeof fconvert) |
|
@@ -682,47 +701,61 @@ fmtfp( |
|
|
|
if ((flags & DP_F_ZERO) && (padlen > 0)) { |
|
if (signvalue) { |
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue); |
|
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue)) |
|
+ return 0; |
|
--padlen; |
|
signvalue = 0; |
|
} |
|
while (padlen > 0) { |
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, '0'); |
|
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0')) |
|
+ return 0; |
|
--padlen; |
|
} |
|
} |
|
while (padlen > 0) { |
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' '); |
|
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) |
|
+ return 0; |
|
--padlen; |
|
} |
|
- if (signvalue) |
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue); |
|
+ if (signvalue && !doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue)) |
|
+ return 0; |
|
|
|
- while (iplace > 0) |
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]); |
|
+ while (iplace > 0) { |
|
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace])) |
|
+ return 0; |
|
+ } |
|
|
|
/* |
|
* Decimal point. This should probably use locale to find the correct |
|
* char to print out. |
|
*/ |
|
if (max > 0 || (flags & DP_F_NUM)) { |
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, '.'); |
|
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '.')) |
|
+ return 0; |
|
|
|
- while (fplace > 0) |
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, fconvert[--fplace]); |
|
+ while (fplace > 0) { |
|
+ if(!doapr_outch(sbuffer, buffer, currlen, maxlen, |
|
+ fconvert[--fplace])) |
|
+ return 0; |
|
+ } |
|
} |
|
while (zpadlen > 0) { |
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, '0'); |
|
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0')) |
|
+ return 0; |
|
--zpadlen; |
|
} |
|
|
|
while (padlen < 0) { |
|
- doapr_outch(sbuffer, buffer, currlen, maxlen, ' '); |
|
+ if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) |
|
+ return 0; |
|
++padlen; |
|
} |
|
+ return 1; |
|
} |
|
|
|
-static void |
|
+#define BUFFER_INC 1024 |
|
+ |
|
+static int |
|
doapr_outch( |
|
char **sbuffer, |
|
char **buffer, |
|
@@ -733,24 +766,30 @@ doapr_outch( |
|
/* If we haven't at least one buffer, someone has doe a big booboo */ |
|
assert(*sbuffer != NULL || buffer != NULL); |
|
|
|
- if (buffer) { |
|
- while (*currlen >= *maxlen) { |
|
- if (*buffer == NULL) { |
|
- if (*maxlen == 0) |
|
- *maxlen = 1024; |
|
+ /* |currlen| must always be <= |*maxlen| */ |
|
+ assert(*currlen <= *maxlen); |
|
+ |
|
+ if (buffer && *currlen == *maxlen) { |
|
+ if (*maxlen > INT_MAX - BUFFER_INC) |
|
+ return 0; |
|
+ |
|
+ *maxlen += BUFFER_INC; |
|
+ if (*buffer == NULL) { |
|
*buffer = OPENSSL_malloc(*maxlen); |
|
+ if (*buffer == NULL) |
|
+ return 0; |
|
if (*currlen > 0) { |
|
assert(*sbuffer != NULL); |
|
memcpy(*buffer, *sbuffer, *currlen); |
|
} |
|
*sbuffer = NULL; |
|
- } else { |
|
- *maxlen += 1024; |
|
- *buffer = OPENSSL_realloc(*buffer, *maxlen); |
|
- } |
|
+ } else { |
|
+ char *tmpbuf; |
|
+ tmpbuf = OPENSSL_realloc(*buffer, *maxlen); |
|
+ if (tmpbuf == NULL) |
|
+ return 0; |
|
+ *buffer = tmpbuf; |
|
} |
|
- /* What to do if *buffer is NULL? */ |
|
- assert(*sbuffer != NULL || *buffer != NULL); |
|
} |
|
|
|
if (*currlen < *maxlen) { |
|
@@ -760,7 +799,7 @@ doapr_outch( |
|
(*buffer)[(*currlen)++] = (char)c; |
|
} |
|
|
|
- return; |
|
+ return 1; |
|
} |
|
|
|
/***************************************************************************/ |
|
@@ -792,11 +831,15 @@ int BIO_vprintf (BIO *bio, const char *f |
|
|
|
dynbuf = NULL; |
|
CRYPTO_push_info("doapr()"); |
|
- _dopr(&hugebufp, &dynbuf, &hugebufsize, |
|
- &retlen, &ignored, format, args); |
|
+ if (!_dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format, |
|
+ args)) |
|
+ { |
|
+ OPENSSL_free(dynbuf); |
|
+ return -1; |
|
+ } |
|
if (dynbuf) |
|
{ |
|
- ret=BIO_write(bio, dynbuf, (int)retlen); |
|
+ ret = BIO_write(bio, dynbuf, (int)retlen); |
|
OPENSSL_free(dynbuf); |
|
} |
|
else |
|
@@ -829,7 +872,8 @@ int BIO_vsnprintf(char *buf, size_t n, c |
|
size_t retlen; |
|
int truncated; |
|
|
|
- _dopr(&buf, NULL, &n, &retlen, &truncated, format, args); |
|
+ if(!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args)) |
|
+ return -1; |
|
|
|
if (truncated) |
|
/* In case of truncation, return -1 like traditional snprintf.
|
|
|