Bug 1539261, part 2 - Mark various JSStructuredCloneData methods MOZ_MUST_USE. r=sfink
☠☠ backed out by bf00743b877b ☠ ☠
authorAndrew McCreight <continuation@gmail.com>
Wed, 27 Mar 2019 19:34:46 +0000
changeset 466439 526daf87fff9637b1acd7b0381e59378c6dde443
parent 466438 5b070b6ae224de2ba67c668e41e1f828dec6ed63
child 466440 656f17a2553b480fd019d0ef1f754295ff7bffcd
push id81602
push useramccreight@mozilla.com
push dateWed, 27 Mar 2019 19:35:47 +0000
treeherderautoland@526daf87fff9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1539261
milestone68.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 1539261, part 2 - Mark various JSStructuredCloneData methods MOZ_MUST_USE. r=sfink Also, fix up various places that call these methods. Depends on D24991 Differential Revision: https://phabricator.services.mozilla.com/D24992
dom/base/nsStructuredCloneContainer.cpp
dom/ipc/StructuredCloneData.h
ipc/glue/IPCMessageUtils.h
js/public/StructuredClone.h
js/src/builtin/TestingFunctions.cpp
--- a/dom/base/nsStructuredCloneContainer.cpp
+++ b/dom/base/nsStructuredCloneContainer.cpp
@@ -125,17 +125,19 @@ nsStructuredCloneContainer::GetDataAsBas
   if (HasClonedDOMObjects()) {
     return NS_ERROR_FAILURE;
   }
 
   auto iter = Data().Start();
   size_t size = Data().Size();
   nsAutoCString binaryData;
   binaryData.SetLength(size);
-  Data().ReadBytes(iter, binaryData.BeginWriting(), size);
+  if (!Data().ReadBytes(iter, binaryData.BeginWriting(), size)) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
   nsAutoCString base64Data;
   nsresult rv = Base64Encode(binaryData, base64Data);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   if (!CopyASCIItoUTF16(base64Data, aOut, fallible)) {
     return NS_ERROR_OUT_OF_MEMORY;
--- a/dom/ipc/StructuredCloneData.h
+++ b/dom/ipc/StructuredCloneData.h
@@ -47,26 +47,26 @@ namespace ipc {
 class SharedJSAllocatedData final {
  public:
   explicit SharedJSAllocatedData(JSStructuredCloneData&& aData)
       : mData(std::move(aData)) {}
 
   static already_AddRefed<SharedJSAllocatedData> CreateFromExternalData(
       const char* aData, size_t aDataLength) {
     JSStructuredCloneData buf(JS::StructuredCloneScope::DifferentProcess);
-    buf.AppendBytes(aData, aDataLength);
+    NS_ENSURE_TRUE(buf.AppendBytes(aData, aDataLength), nullptr);
     RefPtr<SharedJSAllocatedData> sharedData =
         new SharedJSAllocatedData(std::move(buf));
     return sharedData.forget();
   }
 
   static already_AddRefed<SharedJSAllocatedData> CreateFromExternalData(
       const JSStructuredCloneData& aData) {
     JSStructuredCloneData buf(aData.scope());
-    buf.Append(aData);
+    NS_ENSURE_TRUE(buf.Append(aData), nullptr);
     RefPtr<SharedJSAllocatedData> sharedData =
         new SharedJSAllocatedData(std::move(buf));
     return sharedData.forget();
   }
 
   NS_INLINE_DECL_REFCOUNTING(SharedJSAllocatedData)
 
   JSStructuredCloneData& Data() { return mData; }
--- a/ipc/glue/IPCMessageUtils.h
+++ b/ipc/glue/IPCMessageUtils.h
@@ -79,17 +79,17 @@ struct SerializedStructuredCloneBuffer f
       : SerializedStructuredCloneBuffer() {
     *this = aOther;
   }
 
   SerializedStructuredCloneBuffer& operator=(
       const SerializedStructuredCloneBuffer& aOther) {
     data.Clear();
     data.initScope(aOther.data.scope());
-    data.Append(aOther.data);
+    MOZ_RELEASE_ASSERT(data.Append(aOther.data), "out of memory");
     return *this;
   }
 
   bool operator==(const SerializedStructuredCloneBuffer& aOther) const {
     // The copy assignment operator and the equality operator are
     // needed by the IPDL generated code. We relied on the copy
     // assignment operator at some places but we never use the
     // equality operator.
--- a/js/public/StructuredClone.h
+++ b/js/public/StructuredClone.h
@@ -434,17 +434,17 @@ class MOZ_NON_MEMMOVABLE JS_PUBLIC_API J
 
   void setCallbacks(const JSStructuredCloneCallbacks* callbacks, void* closure,
                     OwnTransferablePolicy policy) {
     callbacks_ = callbacks;
     closure_ = closure;
     ownTransferables_ = policy;
   }
 
-  bool Init(size_t initialCapacity = 0) {
+  MOZ_MUST_USE bool Init(size_t initialCapacity = 0) {
     return bufList_.Init(0, initialCapacity);
   }
 
   JS::StructuredCloneScope scope() const { return scope_; }
 
   void initScope(JS::StructuredCloneScope scope) {
     MOZ_ASSERT(Size() == 0, "initScope() of nonempty JSStructuredCloneData");
     if (scope_ != JS::StructuredCloneScope::Unassigned) {
@@ -453,33 +453,34 @@ class MOZ_NON_MEMMOVABLE JS_PUBLIC_API J
     }
     scope_ = scope;
   }
 
   size_t Size() const { return bufList_.Size(); }
 
   const Iterator Start() const { return bufList_.Iter(); }
 
-  bool Advance(Iterator& iter, size_t distance) const {
+  MOZ_MUST_USE bool Advance(Iterator& iter, size_t distance) const {
     return iter.AdvanceAcrossSegments(bufList_, distance);
   }
 
-  bool ReadBytes(Iterator& iter, char* buffer, size_t size) const {
+  MOZ_MUST_USE bool ReadBytes(Iterator& iter, char* buffer, size_t size) const {
     return bufList_.ReadBytes(iter, buffer, size);
   }
 
   // Append new data to the end of the buffer.
-  bool AppendBytes(const char* data, size_t size) {
+  MOZ_MUST_USE bool AppendBytes(const char* data, size_t size) {
     MOZ_ASSERT(scope_ != JS::StructuredCloneScope::Unassigned);
     return bufList_.WriteBytes(data, size);
   }
 
   // Update data stored within the existing buffer. There must be at least
   // 'size' bytes between the position of 'iter' and the end of the buffer.
-  bool UpdateBytes(Iterator& iter, const char* data, size_t size) const {
+  MOZ_MUST_USE bool UpdateBytes(Iterator& iter, const char* data,
+                                size_t size) const {
     MOZ_ASSERT(scope_ != JS::StructuredCloneScope::Unassigned);
     while (size > 0) {
       size_t remaining = iter.RemainingInSegment();
       size_t nbytes = std::min(remaining, size);
       memcpy(iter.Data(), data, nbytes);
       data += nbytes;
       size -= nbytes;
       iter.Advance(bufList_, nbytes);
@@ -519,17 +520,17 @@ class MOZ_NON_MEMMOVABLE JS_PUBLIC_API J
         return false;
       }
       iter.Advance(bufList_, iter.RemainingInSegment());
     }
     return true;
   }
 
   // Append the entire contents of other's bufList_ to our own.
-  bool Append(const JSStructuredCloneData& other) {
+  MOZ_MUST_USE bool Append(const JSStructuredCloneData& other) {
     MOZ_ASSERT(scope_ == other.scope());
     return other.ForEachDataChunk(
         [&](const char* data, size_t size) { return AppendBytes(data, size); });
   }
 
   size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) {
     return bufList_.SizeOfExcludingThis(mallocSizeOf);
   }
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -2939,17 +2939,20 @@ class CloneBufferObject : public NativeO
 
     size_t size = data->Size();
     UniqueChars buffer(js_pod_malloc<char>(size));
     if (!buffer) {
       ReportOutOfMemory(cx);
       return false;
     }
     auto iter = data->Start();
-    data->ReadBytes(iter, buffer.get(), size);
+    if (!data->ReadBytes(iter, buffer.get(), size)) {
+      ReportOutOfMemory(cx);
+      return false;
+    }
     JSString* str = JS_NewStringCopyN(cx, buffer.get(), size);
     if (!str) {
       return false;
     }
     args.rval().setString(str);
     return true;
   }
 
@@ -2971,17 +2974,20 @@ class CloneBufferObject : public NativeO
 
     size_t size = data->Size();
     UniqueChars buffer(js_pod_malloc<char>(size));
     if (!buffer) {
       ReportOutOfMemory(cx);
       return false;
     }
     auto iter = data->Start();
-    data->ReadBytes(iter, buffer.get(), size);
+    if (!data->ReadBytes(iter, buffer.get(), size)) {
+      ReportOutOfMemory(cx);
+      return false;
+    }
 
     auto* rawBuffer = buffer.release();
     JSObject* arrayBuffer = JS::NewArrayBufferWithContents(cx, size, rawBuffer);
     if (!arrayBuffer) {
       js_free(rawBuffer);
       return false;
     }