From fd3aec925b763a0293e67f9ad5f87c9de0cd7211 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Mon, 12 Feb 2018 17:40:17 +0100 Subject: [PATCH] Bug 1437152 - NS_ReadInputStreamToString doesn't reallocate the string if the size is passed, r=froydnj --- netwerk/base/nsNetUtil.cpp | 21 +++++++++++++++++- netwerk/test/gtest/TestReadStreamToString.cpp | 22 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/netwerk/base/nsNetUtil.cpp b/netwerk/base/nsNetUtil.cpp index c7135e50c5df..95780266379a 100644 --- a/netwerk/base/nsNetUtil.cpp +++ b/netwerk/base/nsNetUtil.cpp @@ -1874,11 +1874,30 @@ NS_ReadInputStreamToString(nsIInputStream* aInputStream, aWritten = &dummyWritten; } + // Nothing to do if aCount is 0. + if (aCount == 0) { + aDest.Truncate(); + *aWritten = 0; + return NS_OK; + } + + // If we have the size, we can pre-allocate the buffer. + if (aCount > 0) { + if (NS_WARN_IF(aCount >= INT32_MAX) || + NS_WARN_IF(!aDest.SetLength(aCount, mozilla::fallible))) { + return NS_ERROR_OUT_OF_MEMORY; + } + + void* dest = aDest.BeginWriting(); + return NS_ReadInputStreamToBuffer(aInputStream, &dest, aCount, + aWritten); + } + + // If the size is unknown, BufferWriter will allocate the buffer. void* dest = nullptr; nsresult rv = NS_ReadInputStreamToBuffer(aInputStream, &dest, aCount, aWritten); MOZ_ASSERT_IF(NS_FAILED(rv), dest == nullptr); - NS_ENSURE_SUCCESS(rv, rv); if (!dest) { diff --git a/netwerk/test/gtest/TestReadStreamToString.cpp b/netwerk/test/gtest/TestReadStreamToString.cpp index a43fdaaf0519..f4aa0cd1e8f7 100644 --- a/netwerk/test/gtest/TestReadStreamToString.cpp +++ b/netwerk/test/gtest/TestReadStreamToString.cpp @@ -3,6 +3,28 @@ #include "nsCOMPtr.h" #include "nsNetUtil.h" +// Here we test the reading a pre-allocated size +TEST(TestReadStreamToString, SyncStreamPreAllocatedSize) { + nsCString buffer; + buffer.AssignLiteral("Hello world!"); + + nsCOMPtr stream; + ASSERT_EQ(NS_OK, NS_NewCStringInputStream(getter_AddRefs(stream), buffer)); + + uint64_t written; + nsAutoCString result; + result.SetLength(5); + + void* ptr = result.BeginWriting(); + + ASSERT_EQ(NS_OK, NS_ReadInputStreamToString(stream, result, 5, &written)); + ASSERT_EQ((uint64_t)5, written); + ASSERT_TRUE(nsCString(buffer.get(), 5).Equals(result)); + + // The pointer should be equal: no relocation. + ASSERT_EQ(ptr, result.BeginWriting()); +} + // Here we test the reading the full size of a sync stream TEST(TestReadStreamToString, SyncStreamFullSize) { nsCString buffer;