Bug 1230509 - BlobImplFile should return false in IsDateUnknown and IsSizeUnknown, r=bz

This commit is contained in:
Andrea Marchesini 2015-12-04 21:15:46 +00:00
parent 4ad532de1a
commit ae1df2b2a2
13 changed files with 255 additions and 85 deletions

View File

@ -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)

View File

@ -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();
}

View File

@ -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) {

View File

@ -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

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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");

View File

@ -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.

View File

@ -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;

View File

@ -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)));

View File

@ -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>;
};