Bug 1270126 - Avoid out of memory in safebrowsing::ByteSliceWrite. r=gcp
Switch over to using a single fallible array in ByteSliceWrite. This allows us
to only use 2 transient arrays 1/4 the size of the input array rather than 5
transient arrays.
--- a/toolkit/components/url-classifier/HashStore.cpp
+++ b/toolkit/components/url-classifier/HashStore.cpp
@@ -645,43 +645,56 @@ nsresult InflateReadTArray(nsIInputStrea
NS_ASSERTION(outsize == aExpectedSize * sizeof(T), "Decompression size mismatch");
return NS_OK;
}
static nsresult
ByteSliceWrite(nsIOutputStream* aOut, nsTArray<uint32_t>& aData)
{
- nsTArray<uint8_t> slice1;
- nsTArray<uint8_t> slice2;
- nsTArray<uint8_t> slice3;
- nsTArray<uint8_t> slice4;
+ nsTArray<uint8_t> slice;
uint32_t count = aData.Length();
- slice1.SetCapacity(count);
- slice2.SetCapacity(count);
- slice3.SetCapacity(count);
- slice4.SetCapacity(count);
+ // Only process one slice at a time to avoid using too much memory.
+ if (!slice.SetLength(count, fallible)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ // Process slice 1.
for (uint32_t i = 0; i < count; i++) {
- slice1.AppendElement( aData[i] >> 24);
- slice2.AppendElement((aData[i] >> 16) & 0xFF);
- slice3.AppendElement((aData[i] >> 8) & 0xFF);
- slice4.AppendElement( aData[i] & 0xFF);
+ slice[i] = (aData[i] >> 24);
+ }
+
+ nsresult rv = DeflateWriteTArray(aOut, slice);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Process slice 2.
+ for (uint32_t i = 0; i < count; i++) {
+ slice[i] = ((aData[i] >> 16) & 0xFF);
}
- nsresult rv = DeflateWriteTArray(aOut, slice1);
+ rv = DeflateWriteTArray(aOut, slice);
NS_ENSURE_SUCCESS(rv, rv);
- rv = DeflateWriteTArray(aOut, slice2);
+
+ // Process slice 3.
+ for (uint32_t i = 0; i < count; i++) {
+ slice[i] = ((aData[i] >> 8) & 0xFF);
+ }
+
+ rv = DeflateWriteTArray(aOut, slice);
NS_ENSURE_SUCCESS(rv, rv);
- rv = DeflateWriteTArray(aOut, slice3);
- NS_ENSURE_SUCCESS(rv, rv);
+
+ // Process slice 4.
+ for (uint32_t i = 0; i < count; i++) {
+ slice[i] = (aData[i] & 0xFF);
+ }
+
// The LSB slice is generally uncompressible, don't bother
// compressing it.
- rv = WriteTArray(aOut, slice4);
+ rv = WriteTArray(aOut, slice);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
static nsresult
ByteSliceRead(nsIInputStream* aInStream, FallibleTArray<uint32_t>* aData, uint32_t count)
{