From ae1df2b2a201d9bc0da6c0846fad17ac4e02b658 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini <amarchesini@mozilla.com> Date: Fri, 4 Dec 2015 21:15:46 +0000 Subject: [PATCH] Bug 1230509 - BlobImplFile should return false in IsDateUnknown and IsSizeUnknown, r=bz --- dom/base/BlobSet.h | 3 +- dom/base/File.cpp | 33 ++++++++++---- dom/base/File.h | 7 ++- dom/base/MultipartBlobImpl.cpp | 67 ++++++++++++++++++++++------ dom/base/MultipartBlobImpl.h | 47 ++++++++++++-------- dom/base/StructuredCloneHolder.cpp | 70 +++++++++++++++++++++++++----- dom/base/nsFormData.cpp | 52 +++++++++++++++++----- dom/base/nsFormData.h | 12 +++-- dom/base/nsXMLHttpRequest.cpp | 17 +++++--- dom/base/nsXMLHttpRequest.h | 2 +- dom/fetch/FetchUtil.cpp | 14 ++++-- dom/ipc/Blob.cpp | 12 +++-- dom/webidl/FormData.webidl | 4 ++ 13 files changed, 255 insertions(+), 85 deletions(-) diff --git a/dom/base/BlobSet.h b/dom/base/BlobSet.h index 8e5aa0af6204..7b2151aeed3f 100644 --- a/dom/base/BlobSet.h +++ b/dom/base/BlobSet.h @@ -32,7 +32,8 @@ public: nsTArray<RefPtr<BlobImpl>>& GetBlobImpls() { Flush(); return mBlobImpls; } already_AddRefed<Blob> GetBlobInternal(nsISupports* aParent, - const nsACString& aContentType); + const nsACString& aContentType, + ErrorResult& aRv); protected: bool ExpandBufferSize(uint64_t aSize) diff --git a/dom/base/File.cpp b/dom/base/File.cpp index e3df761998a9..5cc20a76e46e 100644 --- a/dom/base/File.cpp +++ b/dom/base/File.cpp @@ -257,7 +257,7 @@ Blob::ToFile() } already_AddRefed<File> -Blob::ToFile(const nsAString& aName) const +Blob::ToFile(const nsAString& aName, ErrorResult& aRv) const { nsAutoTArray<RefPtr<BlobImpl>, 1> blobImpls; blobImpls.AppendElement(mImpl); @@ -266,7 +266,10 @@ Blob::ToFile(const nsAString& aName) const mImpl->GetType(contentType); RefPtr<MultipartBlobImpl> impl = - new MultipartBlobImpl(blobImpls, aName, contentType); + MultipartBlobImpl::Create(blobImpls, aName, contentType, aRv); + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } RefPtr<File> file = new File(mParent, impl); return file.forget(); @@ -347,7 +350,11 @@ Blob::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv) { RefPtr<MultipartBlobImpl> impl = new MultipartBlobImpl(); - impl->InitializeBlob(); + impl->InitializeBlob(aRv); + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } + MOZ_ASSERT(!impl->IsFile()); RefPtr<Blob> blob = Blob::Create(aGlobal.GetAsSupports(), impl); @@ -851,7 +858,7 @@ BlobImplFile::GetMozFullPathInternal(nsAString& aFilename, ErrorResult& aRv) con uint64_t BlobImplFile::GetSize(ErrorResult& aRv) { - if (IsSizeUnknown()) { + if (BlobImplBase::IsSizeUnknown()) { NS_ASSERTION(mWholeFile, "Should only use lazy size when using the whole file"); int64_t fileSize; @@ -902,7 +909,7 @@ int64_t BlobImplFile::GetLastModified(ErrorResult& aRv) { NS_ASSERTION(mIsFile, "Should only be called on files"); - if (IsDateUnknown()) { + if (BlobImplBase::IsDateUnknown()) { PRTime msecs; aRv = mFile->GetLastModifiedTime(&msecs); if (NS_WARN_IF(aRv.Failed())) { @@ -1121,11 +1128,19 @@ BlobImplTemporaryBlob::GetInternalStream(nsIInputStream** aStream, // BlobSet implementation already_AddRefed<Blob> -BlobSet::GetBlobInternal(nsISupports* aParent, const nsACString& aContentType) +BlobSet::GetBlobInternal(nsISupports* aParent, + const nsACString& aContentType, + ErrorResult& aRv) { - RefPtr<Blob> blob = Blob::Create(aParent, - new MultipartBlobImpl(GetBlobImpls(), - NS_ConvertASCIItoUTF16(aContentType))); + RefPtr<BlobImpl> blobImpl = + MultipartBlobImpl::Create(GetBlobImpls(), + NS_ConvertASCIItoUTF16(aContentType), + aRv); + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } + + RefPtr<Blob> blob = Blob::Create(aParent, blobImpl); return blob.forget(); } diff --git a/dom/base/File.h b/dom/base/File.h index 8264a9bc679b..43c2ed3b0b3a 100644 --- a/dom/base/File.h +++ b/dom/base/File.h @@ -118,7 +118,8 @@ public: // This method creates a new File object with the given name and the same // BlobImpl. - already_AddRefed<File> ToFile(const nsAString& aName) const; + already_AddRefed<File> ToFile(const nsAString& aName, + ErrorResult& aRv) const; already_AddRefed<Blob> CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType, @@ -798,6 +799,10 @@ public: virtual void LookupAndCacheIsDirectory() override; + // We always have size and date for this kind of blob. + virtual bool IsSizeUnknown() const override { return false; } + virtual bool IsDateUnknown() const override { return false; } + protected: virtual ~BlobImplFile() { if (mFile && mIsTemporary) { diff --git a/dom/base/MultipartBlobImpl.cpp b/dom/base/MultipartBlobImpl.cpp index 4d2c309c2fe5..98671429edad 100644 --- a/dom/base/MultipartBlobImpl.cpp +++ b/dom/base/MultipartBlobImpl.cpp @@ -25,6 +25,37 @@ using namespace mozilla::dom; NS_IMPL_ISUPPORTS_INHERITED0(MultipartBlobImpl, BlobImpl) +/* static */ already_AddRefed<MultipartBlobImpl> +MultipartBlobImpl::Create(const nsTArray<RefPtr<BlobImpl>>& aBlobImpls, + const nsAString& aName, + const nsAString& aContentType, + ErrorResult& aRv) +{ + RefPtr<MultipartBlobImpl> blobImpl = + new MultipartBlobImpl(aBlobImpls, aName, aContentType); + blobImpl->SetLengthAndModifiedDate(aRv); + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } + + return blobImpl.forget(); +} + +/* static */ already_AddRefed<MultipartBlobImpl> +MultipartBlobImpl::Create(const nsTArray<RefPtr<BlobImpl>>& aBlobImpls, + const nsAString& aContentType, + ErrorResult& aRv) +{ + RefPtr<MultipartBlobImpl> blobImpl = + new MultipartBlobImpl(aBlobImpls, aContentType); + blobImpl->SetLengthAndModifiedDate(aRv); + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } + + return blobImpl.forget(); +} + void MultipartBlobImpl::GetInternalStream(nsIInputStream** aStream, ErrorResult& aRv) @@ -125,15 +156,19 @@ MultipartBlobImpl::CreateSlice(uint64_t aStart, uint64_t aLength, } // we can create our blob now - RefPtr<BlobImpl> impl = - new MultipartBlobImpl(blobImpls, aContentType); + RefPtr<BlobImpl> impl = Create(blobImpls, aContentType, aRv); + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } + return impl.forget(); } void -MultipartBlobImpl::InitializeBlob() +MultipartBlobImpl::InitializeBlob(ErrorResult& aRv) { - SetLengthAndModifiedDate(); + SetLengthAndModifiedDate(aRv); + NS_WARN_IF(aRv.Failed()); } void @@ -187,11 +222,12 @@ MultipartBlobImpl::InitializeBlob( mBlobImpls = blobSet.GetBlobImpls(); - SetLengthAndModifiedDate(); + SetLengthAndModifiedDate(aRv); + NS_WARN_IF(aRv.Failed()); } void -MultipartBlobImpl::SetLengthAndModifiedDate() +MultipartBlobImpl::SetLengthAndModifiedDate(ErrorResult& aRv) { MOZ_ASSERT(mLength == UINT64_MAX); MOZ_ASSERT(mLastModificationDate == INT64_MAX); @@ -208,16 +244,19 @@ MultipartBlobImpl::SetLengthAndModifiedDate() MOZ_ASSERT(!blob->IsDateUnknown()); #endif - ErrorResult error; - uint64_t subBlobLength = blob->GetSize(error); - MOZ_ALWAYS_TRUE(!error.Failed()); + uint64_t subBlobLength = blob->GetSize(aRv); + if (NS_WARN_IF(aRv.Failed())) { + return; + } MOZ_ASSERT(UINT64_MAX - subBlobLength >= totalLength); totalLength += subBlobLength; if (blob->IsFile()) { - int64_t partLastModified = blob->GetLastModified(error); - MOZ_ALWAYS_TRUE(!error.Failed()); + int64_t partLastModified = blob->GetLastModified(aRv); + if (NS_WARN_IF(aRv.Failed())) { + return; + } if (lastModified < partLastModified) { lastModified = partLastModified; @@ -314,7 +353,8 @@ MultipartBlobImpl::InitializeChromeFile(Blob& aBlob, blobSet.AppendBlobImpl(aBlob.Impl()); mBlobImpls = blobSet.GetBlobImpls(); - SetLengthAndModifiedDate(); + SetLengthAndModifiedDate(aRv); + NS_WARN_IF(aRv.Failed()); } void @@ -385,7 +425,8 @@ MultipartBlobImpl::InitializeChromeFile(nsPIDOMWindow* aWindow, blobSet.AppendBlobImpl(static_cast<File*>(blob.get())->Impl()); mBlobImpls = blobSet.GetBlobImpls(); - SetLengthAndModifiedDate(); + SetLengthAndModifiedDate(aRv); + NS_WARN_IF(aRv.Failed()); } void diff --git a/dom/base/MultipartBlobImpl.h b/dom/base/MultipartBlobImpl.h index 2a0778be28cc..2239a4936ed3 100644 --- a/dom/base/MultipartBlobImpl.h +++ b/dom/base/MultipartBlobImpl.h @@ -25,25 +25,17 @@ public: NS_DECL_ISUPPORTS_INHERITED // Create as a file - MultipartBlobImpl(const nsTArray<RefPtr<BlobImpl>>& aBlobImpls, - const nsAString& aName, - const nsAString& aContentType) - : BlobImplBase(aName, aContentType, UINT64_MAX), - mBlobImpls(aBlobImpls), - mIsFromNsIFile(false) - { - SetLengthAndModifiedDate(); - } + static already_AddRefed<MultipartBlobImpl> + Create(const nsTArray<RefPtr<BlobImpl>>& aBlobImpls, + const nsAString& aName, + const nsAString& aContentType, + ErrorResult& aRv); // Create as a blob - MultipartBlobImpl(const nsTArray<RefPtr<BlobImpl>>& aBlobImpls, - const nsAString& aContentType) - : BlobImplBase(aContentType, UINT64_MAX), - mBlobImpls(aBlobImpls), - mIsFromNsIFile(false) - { - SetLengthAndModifiedDate(); - } + static already_AddRefed<MultipartBlobImpl> + Create(const nsTArray<RefPtr<BlobImpl>>& aBlobImpls, + const nsAString& aContentType, + ErrorResult& aRv); // Create as a file to be later initialized explicit MultipartBlobImpl(const nsAString& aName) @@ -59,7 +51,7 @@ public: { } - void InitializeBlob(); + void InitializeBlob(ErrorResult& aRv); void InitializeBlob( JSContext* aCx, @@ -120,9 +112,26 @@ public: virtual bool MayBeClonedToOtherThreads() const override; protected: + MultipartBlobImpl(const nsTArray<RefPtr<BlobImpl>>& aBlobImpls, + const nsAString& aName, + const nsAString& aContentType) + : BlobImplBase(aName, aContentType, UINT64_MAX), + mBlobImpls(aBlobImpls), + mIsFromNsIFile(false) + { + } + + MultipartBlobImpl(const nsTArray<RefPtr<BlobImpl>>& aBlobImpls, + const nsAString& aContentType) + : BlobImplBase(aContentType, UINT64_MAX), + mBlobImpls(aBlobImpls), + mIsFromNsIFile(false) + { + } + virtual ~MultipartBlobImpl() {} - void SetLengthAndModifiedDate(); + void SetLengthAndModifiedDate(ErrorResult& aRv); nsTArray<RefPtr<BlobImpl>> mBlobImpls; bool mIsFromNsIFile; diff --git a/dom/base/StructuredCloneHolder.cpp b/dom/base/StructuredCloneHolder.cpp index b069f7d7b1f7..d6932d376dd7 100644 --- a/dom/base/StructuredCloneHolder.cpp +++ b/dom/base/StructuredCloneHolder.cpp @@ -555,7 +555,8 @@ namespace { // Recursive! already_AddRefed<BlobImpl> EnsureBlobForBackgroundManager(BlobImpl* aBlobImpl, - PBackgroundChild* aManager = nullptr) + PBackgroundChild* aManager, + ErrorResult& aRv) { MOZ_ASSERT(aBlobImpl); RefPtr<BlobImpl> blobImpl = aBlobImpl; @@ -604,7 +605,11 @@ EnsureBlobForBackgroundManager(BlobImpl* aBlobImpl, RefPtr<BlobImpl>& newSubBlobImpl = newSubBlobImpls[index]; - newSubBlobImpl = EnsureBlobForBackgroundManager(subBlobImpl, aManager); + newSubBlobImpl = EnsureBlobForBackgroundManager(subBlobImpl, aManager, aRv); + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } + MOZ_ASSERT(newSubBlobImpl); if (subBlobImpl != newSubBlobImpl) { @@ -620,9 +625,14 @@ EnsureBlobForBackgroundManager(BlobImpl* aBlobImpl, nsString name; blobImpl->GetName(name); - blobImpl = new MultipartBlobImpl(newSubBlobImpls, name, contentType); + blobImpl = MultipartBlobImpl::Create(newSubBlobImpls, name, + contentType, aRv); } else { - blobImpl = new MultipartBlobImpl(newSubBlobImpls, contentType); + blobImpl = MultipartBlobImpl::Create(newSubBlobImpls, contentType, aRv); + } + + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; } MOZ_ALWAYS_TRUE(NS_SUCCEEDED(blobImpl->SetMutable(false))); @@ -640,7 +650,13 @@ ReadBlob(JSContext* aCx, MOZ_ASSERT(aIndex < aHolder->BlobImpls().Length()); RefPtr<BlobImpl> blobImpl = aHolder->BlobImpls()[aIndex]; - blobImpl = EnsureBlobForBackgroundManager(blobImpl); + ErrorResult rv; + blobImpl = EnsureBlobForBackgroundManager(blobImpl, nullptr, rv); + if (NS_WARN_IF(rv.Failed())) { + rv.SuppressException(); + return nullptr; + } + MOZ_ASSERT(blobImpl); // RefPtr<File> needs to go out of scope before toObjectOrNull() is @@ -668,7 +684,14 @@ WriteBlob(JSStructuredCloneWriter* aWriter, MOZ_ASSERT(aBlob); MOZ_ASSERT(aHolder); - RefPtr<BlobImpl> blobImpl = EnsureBlobForBackgroundManager(aBlob->Impl()); + ErrorResult rv; + RefPtr<BlobImpl> blobImpl = + EnsureBlobForBackgroundManager(aBlob->Impl(), nullptr, rv); + if (NS_WARN_IF(rv.Failed())) { + rv.SuppressException(); + return false; + } + MOZ_ASSERT(blobImpl); MOZ_ALWAYS_TRUE(NS_SUCCEEDED(blobImpl->SetMutable(false))); @@ -714,7 +737,13 @@ ReadFileList(JSContext* aCx, RefPtr<BlobImpl> blobImpl = aHolder->BlobImpls()[index]; MOZ_ASSERT(blobImpl->IsFile()); - blobImpl = EnsureBlobForBackgroundManager(blobImpl); + ErrorResult rv; + blobImpl = EnsureBlobForBackgroundManager(blobImpl, nullptr, rv); + if (NS_WARN_IF(rv.Failed())) { + rv.SuppressException(); + return nullptr; + } + MOZ_ASSERT(blobImpl); RefPtr<File> file = File::Create(aHolder->ParentDuringRead(), blobImpl); @@ -753,14 +782,22 @@ WriteFileList(JSStructuredCloneWriter* aWriter, return false; } + ErrorResult rv; + nsTArray<RefPtr<BlobImpl>> blobImpls; + for (uint32_t i = 0; i < aFileList->Length(); ++i) { RefPtr<BlobImpl> blobImpl = - EnsureBlobForBackgroundManager(aFileList->Item(i)->Impl()); - MOZ_ASSERT(blobImpl); + EnsureBlobForBackgroundManager(aFileList->Item(i)->Impl(), nullptr, rv); + if (NS_WARN_IF(rv.Failed())) { + rv.SuppressException(); + return false; + } - aHolder->BlobImpls().AppendElement(blobImpl); + MOZ_ASSERT(blobImpl); + blobImpls.AppendElement(blobImpl); } + aHolder->BlobImpls().AppendElements(blobImpls); return true; } @@ -804,7 +841,12 @@ ReadFormData(JSContext* aCx, File::Create(aHolder->ParentDuringRead(), blobImpl); MOZ_ASSERT(file); - formData->Append(name, *file, thirdArg); + ErrorResult rv; + formData->Append(name, *file, thirdArg, rv); + if (NS_WARN_IF(rv.Failed())) { + return nullptr; + } + } else { MOZ_ASSERT(tag == 0); @@ -816,7 +858,11 @@ ReadFormData(JSContext* aCx, return nullptr; } - formData->Append(name, value); + ErrorResult rv; + formData->Append(name, value, rv); + if (NS_WARN_IF(rv.Failed())) { + return nullptr; + } } } diff --git a/dom/base/nsFormData.cpp b/dom/base/nsFormData.cpp index 97f83ff36a7d..c47f7a0bdb49 100644 --- a/dom/base/nsFormData.cpp +++ b/dom/base/nsFormData.cpp @@ -25,7 +25,8 @@ namespace { // Implements steps 3 and 4 of the "create an entry" algorithm of FormData. already_AddRefed<File> -CreateNewFileInstance(Blob& aBlob, const Optional<nsAString>& aFilename) +CreateNewFileInstance(Blob& aBlob, const Optional<nsAString>& aFilename, + ErrorResult& aRv) { // Step 3 "If value is a Blob object and not a File object, set value to // a new File object, representing the same bytes, whose name attribute value @@ -47,7 +48,12 @@ CreateNewFileInstance(Blob& aBlob, const Optional<nsAString>& aFilename) filename = NS_LITERAL_STRING("blob"); } - return aBlob.ToFile(filename); + RefPtr<File> file = aBlob.ToFile(filename, aRv); + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } + + return file.forget(); } } // namespace @@ -101,16 +107,22 @@ nsFormData::GetEncodedSubmission(nsIURI* aURI, } void -nsFormData::Append(const nsAString& aName, const nsAString& aValue) +nsFormData::Append(const nsAString& aName, const nsAString& aValue, + ErrorResult& aRv) { AddNameValuePair(aName, aValue); } void nsFormData::Append(const nsAString& aName, Blob& aBlob, - const Optional<nsAString>& aFilename) + const Optional<nsAString>& aFilename, + ErrorResult& aRv) { - RefPtr<File> file = CreateNewFileInstance(aBlob, aFilename); + RefPtr<File> file = CreateNewFileInstance(aBlob, aFilename, aRv); + if (NS_WARN_IF(aRv.Failed())) { + return; + } + AddNameFilePair(aName, file); } @@ -196,25 +208,31 @@ nsFormData::RemoveAllOthersAndGetFirstFormDataTuple(const nsAString& aName) void nsFormData::Set(const nsAString& aName, Blob& aBlob, - const Optional<nsAString>& aFilename) + const Optional<nsAString>& aFilename, + ErrorResult& aRv) { FormDataTuple* tuple = RemoveAllOthersAndGetFirstFormDataTuple(aName); if (tuple) { - RefPtr<File> file = CreateNewFileInstance(aBlob, aFilename); + RefPtr<File> file = CreateNewFileInstance(aBlob, aFilename, aRv); + if (NS_WARN_IF(aRv.Failed())) { + return; + } + SetNameFilePair(tuple, aName, file); } else { - Append(aName, aBlob, aFilename); + Append(aName, aBlob, aFilename, aRv); } } void -nsFormData::Set(const nsAString& aName, const nsAString& aValue) +nsFormData::Set(const nsAString& aName, const nsAString& aValue, + ErrorResult& aRv) { FormDataTuple* tuple = RemoveAllOthersAndGetFirstFormDataTuple(aName); if (tuple) { SetNameValuePair(tuple, aName, aValue); } else { - Append(aName, aValue); + Append(aName, aValue, aRv); } } @@ -261,7 +279,12 @@ nsFormData::Append(const nsAString& aName, nsIVariant* aValue) RefPtr<Blob> blob = static_cast<Blob*>(domBlob.get()); if (domBlob) { Optional<nsAString> temp; - Append(aName, *blob, temp); + ErrorResult rv; + Append(aName, *blob, temp, rv); + if (NS_WARN_IF(rv.Failed())) { + return rv.StealNSResult(); + } + return NS_OK; } } @@ -274,7 +297,12 @@ nsFormData::Append(const nsAString& aName, nsIVariant* aValue) nsString valAsString; valAsString.Adopt(stringData, stringLen); - Append(aName, valAsString); + ErrorResult error; + Append(aName, valAsString, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } + return NS_OK; } diff --git a/dom/base/nsFormData.h b/dom/base/nsFormData.h index 1b428f7d7ea9..d6e06b05e52a 100644 --- a/dom/base/nsFormData.h +++ b/dom/base/nsFormData.h @@ -93,16 +93,20 @@ public: Constructor(const mozilla::dom::GlobalObject& aGlobal, const mozilla::dom::Optional<mozilla::dom::NonNull<mozilla::dom::HTMLFormElement> >& aFormElement, mozilla::ErrorResult& aRv); - void Append(const nsAString& aName, const nsAString& aValue); + void Append(const nsAString& aName, const nsAString& aValue, + mozilla::ErrorResult& aRv); void Append(const nsAString& aName, Blob& aBlob, - const mozilla::dom::Optional<nsAString>& aFilename); + const mozilla::dom::Optional<nsAString>& aFilename, + mozilla::ErrorResult& aRv); void Delete(const nsAString& aName); void Get(const nsAString& aName, mozilla::dom::Nullable<OwningFileOrUSVString>& aOutValue); void GetAll(const nsAString& aName, nsTArray<OwningFileOrUSVString>& aValues); bool Has(const nsAString& aName); void Set(const nsAString& aName, Blob& aBlob, - const mozilla::dom::Optional<nsAString>& aFilename); - void Set(const nsAString& aName, const nsAString& aValue); + const mozilla::dom::Optional<nsAString>& aFilename, + mozilla::ErrorResult& aRv); + void Set(const nsAString& aName, const nsAString& aValue, + mozilla::ErrorResult& aRv); uint32_t GetIterableLength() const; const nsAString& GetKeyAtIndex(uint32_t aIndex) const; diff --git a/dom/base/nsXMLHttpRequest.cpp b/dom/base/nsXMLHttpRequest.cpp index 95b2b4165cf4..5747dc5cf4c2 100644 --- a/dom/base/nsXMLHttpRequest.cpp +++ b/dom/base/nsXMLHttpRequest.cpp @@ -798,7 +798,7 @@ nsXMLHttpRequest::CreateResponseParsedJSON(JSContext* aCx) } void -nsXMLHttpRequest::CreatePartialBlob() +nsXMLHttpRequest::CreatePartialBlob(ErrorResult& aRv) { if (mDOMBlob) { // Use progress info to determine whether load is complete, but use @@ -807,9 +807,8 @@ nsXMLHttpRequest::CreatePartialBlob() if (mLoadTotal == mLoadTransferred) { mResponseBlob = mDOMBlob; } else { - ErrorResult rv; mResponseBlob = mDOMBlob->CreateSlice(0, mDataAvailable, - EmptyString(), rv); + EmptyString(), aRv); } return; } @@ -824,7 +823,7 @@ nsXMLHttpRequest::CreatePartialBlob() mChannel->GetContentType(contentType); } - mResponseBlob = mBlobSet->GetBlobInternal(GetOwner(), contentType); + mResponseBlob = mBlobSet->GetBlobInternal(GetOwner(), contentType, aRv); } NS_IMETHODIMP nsXMLHttpRequest::GetResponseType(nsAString& aResponseType) @@ -1018,7 +1017,7 @@ nsXMLHttpRequest::GetResponse(JSContext* aCx, } if (!mResponseBlob) { - CreatePartialBlob(); + CreatePartialBlob(aRv); } } @@ -2211,8 +2210,14 @@ nsXMLHttpRequest::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult // Also, no-store response cannot be written in persistent cache. nsAutoCString contentType; mChannel->GetContentType(contentType); - mResponseBlob = mBlobSet->GetBlobInternal(GetOwner(), contentType); + + ErrorResult rv; + mResponseBlob = mBlobSet->GetBlobInternal(GetOwner(), contentType, rv); mBlobSet = nullptr; + + if (NS_WARN_IF(rv.Failed())) { + return rv.StealNSResult(); + } } NS_ASSERTION(mResponseBody.IsEmpty(), "mResponseBody should be empty"); NS_ASSERTION(mResponseText.IsEmpty(), "mResponseText should be empty"); diff --git a/dom/base/nsXMLHttpRequest.h b/dom/base/nsXMLHttpRequest.h index a317fcfe4952..cc2697590c49 100644 --- a/dom/base/nsXMLHttpRequest.h +++ b/dom/base/nsXMLHttpRequest.h @@ -605,7 +605,7 @@ protected: uint32_t count, uint32_t *writeCount); nsresult CreateResponseParsedJSON(JSContext* aCx); - void CreatePartialBlob(); + void CreatePartialBlob(ErrorResult& aRv); bool CreateDOMBlob(nsIRequest *request); // Change the state of the object with this. The broadcast argument // determines if the onreadystatechange listener should be called. diff --git a/dom/fetch/FetchUtil.cpp b/dom/fetch/FetchUtil.cpp index 94f4dd99c5a5..943e63707b8d 100644 --- a/dom/fetch/FetchUtil.cpp +++ b/dom/fetch/FetchUtil.cpp @@ -203,7 +203,9 @@ public: bool URLParamsIterator(const nsString& aName, const nsString& aValue) override { - mFormData->Append(aName, aValue); + ErrorResult rv; + mFormData->Append(aName, aValue, rv); + MOZ_ASSERT(!rv.Failed()); return true; } @@ -392,7 +394,9 @@ private: NS_ConvertUTF8toUTF16 name(mName); if (mFilename.IsVoid()) { - mFormData->Append(name, NS_ConvertUTF8toUTF16(body)); + ErrorResult rv; + mFormData->Append(name, NS_ConvertUTF8toUTF16(body), rv); + MOZ_ASSERT(!rv.Failed()); } else { // Unfortunately we've to copy the data first since all our strings are // going to free it. We also need fallible alloc, so we can't just use @@ -417,7 +421,11 @@ private: NS_ConvertUTF8toUTF16(mFilename), NS_ConvertUTF8toUTF16(mContentType), /* aLastModifiedDate */ 0); Optional<nsAString> dummy; - mFormData->Append(name, *file, dummy); + ErrorResult rv; + mFormData->Append(name, *file, dummy, rv); + if (NS_WARN_IF(rv.Failed())) { + return false; + } } return true; diff --git a/dom/ipc/Blob.cpp b/dom/ipc/Blob.cpp index b3653cf08ff6..cee6625e7907 100644 --- a/dom/ipc/Blob.cpp +++ b/dom/ipc/Blob.cpp @@ -904,13 +904,17 @@ CreateBlobImpl(const nsTArray<BlobData>& aBlobDatas, MOZ_ASSERT(!isMutable); } + ErrorResult rv; RefPtr<BlobImpl> blobImpl; if (!hasRecursed && aMetadata.IsFile()) { - blobImpl = - new MultipartBlobImpl(blobImpls, aMetadata.mName, aMetadata.mContentType); + blobImpl = MultipartBlobImpl::Create(blobImpls, aMetadata.mName, + aMetadata.mContentType, rv); } else { - blobImpl = - new MultipartBlobImpl(blobImpls, aMetadata.mContentType); + blobImpl = MultipartBlobImpl::Create(blobImpls, aMetadata.mContentType, rv); + } + + if (NS_WARN_IF(rv.Failed())) { + return nullptr; } MOZ_ALWAYS_TRUE(NS_SUCCEEDED(blobImpl->SetMutable(false))); diff --git a/dom/webidl/FormData.webidl b/dom/webidl/FormData.webidl index f5902c4efe00..455ea505da9d 100644 --- a/dom/webidl/FormData.webidl +++ b/dom/webidl/FormData.webidl @@ -12,13 +12,17 @@ typedef (File or USVString) FormDataEntryValue; [Constructor(optional HTMLFormElement form), Exposed=(Window,Worker)] interface FormData { + [Throws] void append(USVString name, Blob value, optional USVString filename); + [Throws] void append(USVString name, USVString value); void delete(USVString name); FormDataEntryValue? get(USVString name); sequence<FormDataEntryValue> getAll(USVString name); boolean has(USVString name); + [Throws] void set(USVString name, Blob value, optional USVString filename); + [Throws] void set(USVString name, USVString value); iterable<USVString, FormDataEntryValue>; };