From 5969209bdc0f1169ed7707537c05638d7a0c1040 Mon Sep 17 00:00:00 2001 From: Henri Sivonen Date: Tue, 28 Aug 2018 14:29:40 +0000 Subject: [PATCH] Bug 1484987 - Avoid writing past the logical length of a string in XPCOM. r=froydnj MozReview-Commit-ID: 3qkhOiQduLQ Differential Revision: https://phabricator.services.mozilla.com/D3883 --HG-- extra : moz-landing-system : lando --- xpcom/io/Base64.cpp | 35 ++++++++++++++++------------------- xpcom/io/nsStorageStream.cpp | 8 +++++--- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/xpcom/io/Base64.cpp b/xpcom/io/Base64.cpp index b57c2d03c41c..fb5c681c7022 100644 --- a/xpcom/io/Base64.cpp +++ b/xpcom/io/Base64.cpp @@ -391,16 +391,14 @@ Base64EncodeHelper(const T& aBinary, T& aBase64) uint32_t base64Len = ((aBinary.Length() + 2) / 3) * 4; - // Add one byte for null termination. - if (!aBase64.SetCapacity(base64Len + 1, fallible)) { - return NS_ERROR_OUT_OF_MEMORY; + nsresult rv; + auto handle = aBase64.BulkWrite(base64Len, 0, false, rv); + if (NS_FAILED(rv)) { + return rv; } - typename T::char_type* base64 = aBase64.BeginWriting(); - Encode(aBinary.BeginReading(), aBinary.Length(), base64); - base64[base64Len] = '\0'; - - aBase64.SetLength(base64Len); + Encode(aBinary.BeginReading(), aBinary.Length(), handle.Elements()); + handle.Finish(base64Len, false); return NS_OK; } @@ -575,20 +573,19 @@ Base64DecodeString(const T& aBase64, T& aBinary) uint32_t binaryLen = ((aBase64.Length() * 3) / 4); - // Add one byte for null termination. - if (!aBinary.SetCapacity(binaryLen + 1, fallible)) { - return NS_ERROR_OUT_OF_MEMORY; - } - - typename T::char_type* binary = aBinary.BeginWriting(); - nsresult rv = Base64DecodeHelper(aBase64.BeginReading(), aBase64.Length(), - binary, &binaryLen); - if (NS_FAILED(rv)) { - aBinary.Truncate(); + nsresult rv; + auto handle = aBinary.BulkWrite(binaryLen, 0, false, rv); + if(NS_FAILED(rv)) { return rv; } - aBinary.SetLength(binaryLen); + rv = Base64DecodeHelper(aBase64.BeginReading(), aBase64.Length(), + handle.Elements(), &binaryLen); + if (NS_FAILED(rv)) { + return rv; + } + + handle.Finish(binaryLen, true); return NS_OK; } diff --git a/xpcom/io/nsStorageStream.cpp b/xpcom/io/nsStorageStream.cpp index cca546d6863e..65c915b2cd62 100644 --- a/xpcom/io/nsStorageStream.cpp +++ b/xpcom/io/nsStorageStream.cpp @@ -585,13 +585,15 @@ nsStorageInputStream::Serialize(InputStreamParams& aParams, FileDescriptorArray& rv = Available(&remaining); MOZ_ASSERT(NS_SUCCEEDED(rv)); - combined.SetCapacity(remaining); + auto handle = combined.BulkWrite(remaining, 0, false, rv); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + uint32_t numRead = 0; - rv = Read(combined.BeginWriting(), remaining, &numRead); + rv = Read(handle.Elements(), remaining, &numRead); MOZ_ASSERT(NS_SUCCEEDED(rv)); MOZ_ASSERT(numRead == remaining); - combined.SetLength(numRead); + handle.Finish(numRead, false); rv = Seek(NS_SEEK_SET, offset); MOZ_ASSERT(NS_SUCCEEDED(rv));