Bug 1274732 - Avoid allocate 128k buffer on stack r=mcmanus
authorNatanael Copa <ncopa@alpinelinux.org>
Sun, 29 May 2016 15:59:24 +0200
changeset 341548 5bc75c0144b55d799e80ea23a2e3244870d2f834
parent 341547 1f056b981b1f7e6e449cf1e67ee55481e569cdc7
child 341549 f3e63f44521d972be0e614d17bd50939a4c3c8c4
push id1183
push userraliiev@mozilla.com
push dateMon, 05 Sep 2016 20:01:49 +0000
treeherdermozilla-release@3148731bed45 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcmanus
bugs1274732
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1274732 - Avoid allocate 128k buffer on stack r=mcmanus Move the 128k buffer for brotli decompression to the heap instead of stack. This fixes crash with musl libc which provides 80k stack by default. MozReview-Commit-ID: 9cDlFO5eoi1
netwerk/streamconv/converters/nsHTTPCompressConv.cpp
--- a/netwerk/streamconv/converters/nsHTTPCompressConv.cpp
+++ b/netwerk/streamconv/converters/nsHTTPCompressConv.cpp
@@ -160,31 +160,36 @@ nsHTTPCompressConv::OnStopRequest(nsIReq
 NS_METHOD
 nsHTTPCompressConv::BrotliHandler(nsIInputStream *stream, void *closure, const char *dataIn,
                                   uint32_t, uint32_t aAvail, uint32_t *countRead)
 {
   MOZ_ASSERT(stream);
   nsHTTPCompressConv *self = static_cast<nsHTTPCompressConv *>(closure);
   *countRead = 0;
 
-  const uint32_t kOutSize = 128 * 1024; // just a chunk size, we call in a loop
-  unsigned char outBuffer[kOutSize];
-  unsigned char *outPtr;
+  const size_t kOutSize = 128 * 1024; // just a chunk size, we call in a loop
+  uint8_t *outPtr;
   size_t outSize;
   size_t avail = aAvail;
   BrotliResult res;
 
   if (!self->mBrotli) {
     *countRead = aAvail;
     return NS_OK;
   }
 
+  auto outBuffer = MakeUniqueFallible<uint8_t[]>(kOutSize);
+  if (outBuffer == nullptr) {
+    self->mBrotli->mStatus = NS_ERROR_OUT_OF_MEMORY;
+    return self->mBrotli->mStatus;
+  }
+
   do {
     outSize = kOutSize;
-    outPtr = outBuffer;
+    outPtr = outBuffer.get();
 
     // brotli api is documented in brotli/dec/decode.h and brotli/dec/decode.c
     LOG(("nsHttpCompresssConv %p brotlihandler decompress %d\n", self, avail));
     res = ::BrotliDecompressStream(
       &avail, reinterpret_cast<const unsigned char **>(&dataIn),
       &outSize, &outPtr, &self->mBrotli->mTotalOut, &self->mBrotli->mState);
     outSize = kOutSize - outSize;
     LOG(("nsHttpCompresssConv %p brotlihandler decompress rv=%x out=%d\n",
@@ -205,17 +210,17 @@ nsHTTPCompressConv::BrotliHandler(nsIInp
         self->mBrotli->mStatus = NS_ERROR_UNEXPECTED;
         return self->mBrotli->mStatus;
       }
     }
     if (outSize > 0) {
       nsresult rv = self->do_OnDataAvailable(self->mBrotli->mRequest,
                                              self->mBrotli->mContext,
                                              self->mBrotli->mSourceOffset,
-                                             reinterpret_cast<const char *>(outBuffer),
+                                             reinterpret_cast<const char *>(outBuffer.get()),
                                              outSize);
       LOG(("nsHttpCompressConv %p BrotliHandler ODA rv=%x", self, rv));
       if (NS_FAILED(rv)) {
         self->mBrotli->mStatus = rv;
         return self->mBrotli->mStatus;
       }
     }