Bug 1600491 - Try not to crash if we fail to allocate memory in MemStream. r=bobowen
authorMatt Woodrow <mwoodrow@mozilla.com>
Mon, 16 Dec 2019 08:13:06 +0000
changeset 507236 c238b47d7d57e651a92b4f134641fa694e4ea900
parent 507235 1c513665e7fb4e4811be559ff55e020fa0665b9f
child 507237 44298fb8f4e295facdf395741b8500c6553afc3a
push id36923
push userccoroiu@mozilla.com
push dateMon, 16 Dec 2019 21:47:33 +0000
treeherdermozilla-central@c238b47d7d57 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbobowen
bugs1600491
milestone73.0a1
first release with
nightly linux32
c238b47d7d57 / 73.0a1 / 20191216214733 / files
nightly linux64
c238b47d7d57 / 73.0a1 / 20191216214733 / files
nightly mac
c238b47d7d57 / 73.0a1 / 20191216214733 / files
nightly win32
c238b47d7d57 / 73.0a1 / 20191216214733 / files
nightly win64
c238b47d7d57 / 73.0a1 / 20191216214733 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1600491 - Try not to crash if we fail to allocate memory in MemStream. r=bobowen Differential Revision: https://phabricator.services.mozilla.com/D57052
gfx/2d/RecordedEvent.h
gfx/ipc/CrossProcessPaint.cpp
--- a/gfx/2d/RecordedEvent.h
+++ b/gfx/2d/RecordedEvent.h
@@ -234,32 +234,44 @@ class EventRingBuffer {
   char* mBufPos = nullptr;
   uint32_t mAvailable = 0;
 };
 
 struct MemStream {
   char* mData;
   size_t mLength;
   size_t mCapacity;
-  void Resize(size_t aSize) {
+  bool mValid = true;
+  bool Resize(size_t aSize) {
+    if (!mValid) {
+      return false;
+    }
     mLength = aSize;
     if (mLength > mCapacity) {
       mCapacity = mCapacity * 2;
       // check if the doubled capacity is enough
       // otherwise use double mLength
       if (mLength > mCapacity) {
         mCapacity = mLength * 2;
       }
       mData = (char*)realloc(mData, mCapacity);
     }
+    if (mData) {
+      return true;
+    }
+    NS_ERROR("Failed to allocate MemStream!");
+    mValid = false;
+    mLength = 0;
+    return false;
   }
 
   void write(const char* aData, size_t aSize) {
-    Resize(mLength + aSize);
-    memcpy(mData + mLength - aSize, aData, aSize);
+    if (Resize(mLength + aSize)) {
+      memcpy(mData + mLength - aSize, aData, aSize);
+    }
   }
 
   MemStream() : mData(nullptr), mLength(0), mCapacity(0) {}
   ~MemStream() { free(mData); }
 };
 
 class EventStream {
  public:
@@ -411,17 +423,19 @@ class RecordedEventDerived : public Reco
   void RecordToStream(EventRingBuffer& aStream) const final {
     aStream.RecordEvent(static_cast<const Derived*>(this));
   }
   void RecordToStream(MemStream& aStream) const override {
     SizeCollector size;
     WriteElement(size, this->mType);
     static_cast<const Derived*>(this)->Record(size);
 
-    aStream.Resize(aStream.mLength + size.mTotalSize);
+    if (!aStream.Resize(aStream.mLength + size.mTotalSize)) {
+      return;
+    }
 
     MemWriter writer(aStream.mData + aStream.mLength - size.mTotalSize);
     WriteElement(writer, this->mType);
     static_cast<const Derived*>(this)->Record(writer);
   }
 };
 
 }  // namespace gfx
--- a/gfx/ipc/CrossProcessPaint.cpp
+++ b/gfx/ipc/CrossProcessPaint.cpp
@@ -129,16 +129,20 @@ PaintFragment PaintFragment::Record(nsID
 
     RefPtr<gfxContext> thebes = gfxContext::CreateOrNull(dt);
     thebes->SetMatrix(Matrix::Scaling(aScale, aScale));
     RefPtr<PresShell> presShell = presContext->PresShell();
     Unused << presShell->RenderDocument(r, renderDocFlags, aBackgroundColor,
                                         thebes);
   }
 
+  if (!recorder->mOutputStream.mValid) {
+    return PaintFragment{};
+  }
+
   ByteBuf recording = ByteBuf((uint8_t*)recorder->mOutputStream.mData,
                               recorder->mOutputStream.mLength,
                               recorder->mOutputStream.mCapacity);
   recorder->mOutputStream.mData = nullptr;
   recorder->mOutputStream.mLength = 0;
   recorder->mOutputStream.mCapacity = 0;
 
   return PaintFragment{