From 3323a8eda3d4cbb29909f6761cee96cc5e164cf2 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Wed, 29 Jul 2020 10:52:30 +0000 Subject: [xpcom] Make Base64 compatible with ReadSegments() with small buffers. --- xpcom/io/Base64.cpp | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'xpcom') diff --git a/xpcom/io/Base64.cpp b/xpcom/io/Base64.cpp index 911c0595a..b9fa7baf8 100644 --- a/xpcom/io/Base64.cpp +++ b/xpcom/io/Base64.cpp @@ -108,30 +108,51 @@ EncodeInputStream_Encoder(nsIInputStream* aStream, EncodeInputStream_State* state = static_cast*>(aClosure); + // We always consume all data. + *aWriteCount = aCount; + // If we have any data left from last time, encode it now. uint32_t countRemaining = aCount; const unsigned char* src = (const unsigned char*)aFromSegment; if (state->charsOnStack) { + MOZ_ASSERT(state->charsOnStack == 1 || state->charsOnStack == 2); + + // Not enough data to compose a triple. + if (state->charsOnStack == 1 && countRemaining == 1) { + state->charsOnStack = 2; + state->c[1] = src[0]; + return NS_OK; + } + + uint32_t consumed = 0; unsigned char firstSet[4]; if (state->charsOnStack == 1) { firstSet[0] = state->c[0]; firstSet[1] = src[0]; - firstSet[2] = (countRemaining > 1) ? src[1] : '\0'; + firstSet[2] = src[1]; firstSet[3] = '\0'; + consumed = 2; } else /* state->charsOnStack == 2 */ { firstSet[0] = state->c[0]; firstSet[1] = state->c[1]; firstSet[2] = src[0]; firstSet[3] = '\0'; + consumed = 1; } + Encode(firstSet, 3, state->buffer); state->buffer += 4; - countRemaining -= (3 - state->charsOnStack); - src += (3 - state->charsOnStack); + countRemaining -= consumed; + src += consumed; state->charsOnStack = 0; + + // Bail if there is nothing left. + if (!countRemaining) { + return NS_OK; + } } - // Encode the bulk of the + // Encode as many full triplets as possible. uint32_t encodeLength = countRemaining - countRemaining % 3; MOZ_ASSERT(encodeLength % 3 == 0, "Should have an exact number of triplets!"); @@ -140,9 +161,6 @@ EncodeInputStream_Encoder(nsIInputStream* aStream, src += encodeLength; countRemaining -= encodeLength; - // We must consume all data, so if there's some data left stash it - *aWriteCount = aCount; - if (countRemaining) { // We should never have a full triplet left at this point. MOZ_ASSERT(countRemaining < 3, "We should have encoded more!"); -- cgit v1.2.3