Bug 1270126 - Avoid out of memory in safebrowsing::ByteSliceWrite. r=gcp
authorEric Rahm <erahm@mozilla.com>
Thu, 05 May 2016 17:37:27 -0700
changeset 321169 386b19f67f2cf4737390b4d1c67712967d45f23e
parent 321168 648d9d0fd2f8dc75dfd2edf1e15aa6c1efeca4c4
child 321170 ff2c2c132be933d9f3729030957869168c1437f4
push id9671
push userraliiev@mozilla.com
push dateMon, 06 Jun 2016 20:27:52 +0000
treeherdermozilla-aurora@cea65ca3d0bd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgcp
bugs1270126
milestone49.0a1
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.
toolkit/components/url-classifier/HashStore.cpp
--- 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)
 {