diff --git a/src/bio.c b/src/bio.c index beb0acfe6..1a19f586f 100644 --- a/src/bio.c +++ b/src/bio.c @@ -328,30 +328,41 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len) while (bio != NULL && ret >= 0) { /* check for formating */ if (bio && bio->type == WOLFSSL_BIO_BASE64) { - #if defined(WOLFSSL_BASE64_ENCODE) + word32 sz = 0; + if (bio->flags & WOLFSSL_BIO_FLAG_BASE64_NO_NL) { if (Base64_Encode_NoNl((const byte*)data, len, NULL, - &frmtSz) != LENGTH_ONLY_E) { + &sz) != LENGTH_ONLY_E) { WOLFSSL_MSG("Error with base 64 get length"); ret = SSL_FATAL_ERROR; } } else { - if (Base64_Encode((const byte*)data, len, NULL, &frmtSz) != + if (Base64_Encode((const byte*)data, len, NULL, &sz) != LENGTH_ONLY_E) { WOLFSSL_MSG("Error with base 64 get length"); ret = SSL_FATAL_ERROR; } } - if (frmt == NULL && frmtSz > 0 && ret != SSL_FATAL_ERROR) { - frmt = (void*)XMALLOC(frmtSz, bio->heap, + if (frmt == NULL && sz > 0 && ret != SSL_FATAL_ERROR) { + frmt = (void*)XMALLOC(sz, front->heap, DYNAMIC_TYPE_TMP_BUFFER); if (frmt == NULL) { WOLFSSL_MSG("Memory error"); ret = SSL_FATAL_ERROR; } + frmtSz = sz; + } + else if (sz > frmtSz) { + frmt = (void*)XREALLOC(frmt, sz, front->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (frmt == NULL) { + WOLFSSL_MSG("Memory error"); + ret = SSL_FATAL_ERROR; + } + frmtSz = sz; } #endif /* defined(WOLFSSL_BASE64_ENCODE) */ @@ -394,7 +405,7 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len) } if (frmt != NULL) { - XFREE(frmt, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(frmt, front->heap, DYNAMIC_TYPE_TMP_BUFFER); } return ret; diff --git a/tests/api.c b/tests/api.c index f7c245421..5f1784cbd 100644 --- a/tests/api.c +++ b/tests/api.c @@ -15579,6 +15579,21 @@ static void test_wolfSSL_BIO_write(void) AssertIntEQ(XMEMCMP(out, expected, sz), 0); BIO_free_all(bio); /* frees bio64 also */ + + /* test with more than one bio64 in list */ + AssertNotNull(bio64 = BIO_new(BIO_f_base64())); + AssertNotNull(bio = BIO_push(bio64, BIO_new(BIO_f_base64()))); + AssertNotNull(bio = BIO_push(bio, BIO_new(BIO_s_mem()))); + + /* now should convert to base64(x2) when stored and then decode with read */ + AssertIntEQ(BIO_write(bio, msg, sizeof(msg)), 25); + BIO_flush(bio); + sz = sizeof(out); + XMEMSET(out, 0, sz); + AssertIntEQ((sz = BIO_read(bio, out, sz)), 16); + AssertIntEQ(XMEMCMP(out, msg, sz), 0); + BIO_free_all(bio); /* frees bio64s also */ + printf(resultFmt, passed); #endif }