void MultipartBlobImpl::InitializeChromeFile(Blob& aBlob, const ChromeFilePropertyBag& aBag, ErrorResult& aRv) { NS_ASSERTION(!mImmutable, "Something went wrong ..."); if (mImmutable) { aRv.Throw(NS_ERROR_UNEXPECTED); return; } MOZ_ASSERT(nsContentUtils::IsCallerChrome()); mName = aBag.mName; mContentType = aBag.mType; mIsFromNsIFile = true; // XXXkhuey this is terrible if (mContentType.IsEmpty()) { aBlob.GetType(mContentType); } BlobSet blobSet; blobSet.AppendBlobImpl(aBlob.Impl()); mBlobImpls = blobSet.GetBlobImpls(); SetLengthAndModifiedDate(); }
void MultipartBlobImpl::InitializeBlob( JSContext* aCx, const Sequence<OwningArrayBufferOrArrayBufferViewOrBlobOrString>& aData, const nsAString& aContentType, bool aNativeEOL, ErrorResult& aRv) { mContentType = aContentType; BlobSet blobSet; for (uint32_t i = 0, len = aData.Length(); i < len; ++i) { const OwningArrayBufferOrArrayBufferViewOrBlobOrString& data = aData[i]; if (data.IsBlob()) { nsRefPtr<Blob> blob = data.GetAsBlob().get(); blobSet.AppendBlobImpl(blob->Impl()); } else if (data.IsString()) { aRv = blobSet.AppendString(data.GetAsString(), aNativeEOL, aCx); if (aRv.Failed()) { return; } } else if (data.IsArrayBuffer()) { const ArrayBuffer& buffer = data.GetAsArrayBuffer(); buffer.ComputeLengthAndData(); aRv = blobSet.AppendVoidPtr(buffer.Data(), buffer.Length()); if (aRv.Failed()) { return; } } else if (data.IsArrayBufferView()) { const ArrayBufferView& buffer = data.GetAsArrayBufferView(); buffer.ComputeLengthAndData(); aRv = blobSet.AppendVoidPtr(buffer.Data(), buffer.Length()); if (aRv.Failed()) { return; } } else { MOZ_CRASH("Impossible blob data type."); } } mBlobImpls = blobSet.GetBlobImpls(); SetLengthAndModifiedDate(); }
void MultipartBlobImpl::InitializeBlob(const Sequence<Blob::BlobPart>& aData, const nsAString& aContentType, bool aNativeEOL, ErrorResult& aRv) { mContentType = aContentType; BlobSet blobSet; for (uint32_t i = 0, len = aData.Length(); i < len; ++i) { const Blob::BlobPart& data = aData[i]; if (data.IsBlob()) { RefPtr<Blob> blob = data.GetAsBlob().get(); blobSet.AppendBlobImpl(blob->Impl()); } else if (data.IsUSVString()) { aRv = blobSet.AppendString(data.GetAsUSVString(), aNativeEOL); if (aRv.Failed()) { return; } } else if (data.IsArrayBuffer()) { const ArrayBuffer& buffer = data.GetAsArrayBuffer(); buffer.ComputeLengthAndData(); aRv = blobSet.AppendVoidPtr(buffer.Data(), buffer.Length()); if (aRv.Failed()) { return; } } else if (data.IsArrayBufferView()) { const ArrayBufferView& buffer = data.GetAsArrayBufferView(); buffer.ComputeLengthAndData(); aRv = blobSet.AppendVoidPtr(buffer.Data(), buffer.Length()); if (aRv.Failed()) { return; } } else { MOZ_CRASH("Impossible blob data type."); } } mBlobImpls = blobSet.GetBlobImpls(); SetLengthAndModifiedDate(aRv); NS_WARNING_ASSERTION(!aRv.Failed(), "SetLengthAndModifiedDate failed"); }
void MultipartBlobImpl::InitializeChromeFile(nsPIDOMWindow* aWindow, nsIFile* aFile, const ChromeFilePropertyBag& aBag, bool aIsFromNsIFile, ErrorResult& aRv) { NS_ASSERTION(!mImmutable, "Something went wrong ..."); if (mImmutable) { aRv.Throw(NS_ERROR_UNEXPECTED); return; } MOZ_ASSERT(nsContentUtils::IsCallerChrome()); mName = aBag.mName; mContentType = aBag.mType; mIsFromNsIFile = aIsFromNsIFile; bool exists; aRv = aFile->Exists(&exists); if (NS_WARN_IF(aRv.Failed())) { return; } if (!exists) { aRv.Throw(NS_ERROR_FILE_NOT_FOUND); return; } bool isDir; aRv = aFile->IsDirectory(&isDir); if (NS_WARN_IF(aRv.Failed())) { return; } if (isDir) { aRv.Throw(NS_ERROR_FILE_IS_DIRECTORY); return; } if (mName.IsEmpty()) { aFile->GetLeafName(mName); } nsRefPtr<File> blob = File::CreateFromFile(aWindow, aFile, aBag.mTemporary); // Pre-cache size. blob->GetSize(aRv); if (NS_WARN_IF(aRv.Failed())) { return; } // Pre-cache modified date. blob->GetLastModified(aRv); if (NS_WARN_IF(aRv.Failed())) { return; } // XXXkhuey this is terrible if (mContentType.IsEmpty()) { blob->GetType(mContentType); } BlobSet blobSet; blobSet.AppendBlobImpl(static_cast<File*>(blob.get())->Impl()); mBlobImpls = blobSet.GetBlobImpls(); SetLengthAndModifiedDate(); }
nsresult MultipartBlobImpl::InitializeChromeFile(nsIFile* aFile, const nsAString& aType, const nsAString& aName, bool aLastModifiedPassed, int64_t aLastModified, bool aIsFromNsIFile) { MOZ_ASSERT(!mImmutable, "Something went wrong ..."); if (mImmutable) { return NS_ERROR_UNEXPECTED; } mName = aName; mContentType = aType; mIsFromNsIFile = aIsFromNsIFile; bool exists; nsresult rv= aFile->Exists(&exists); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } if (!exists) { return NS_ERROR_FILE_NOT_FOUND; } bool isDir; rv = aFile->IsDirectory(&isDir); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } if (isDir) { return NS_ERROR_FILE_IS_DIRECTORY; } if (mName.IsEmpty()) { aFile->GetLeafName(mName); } RefPtr<File> blob = File::CreateFromFile(nullptr, aFile); // Pre-cache size. ErrorResult error; blob->GetSize(error); if (NS_WARN_IF(error.Failed())) { return error.StealNSResult(); } // Pre-cache modified date. blob->GetLastModified(error); if (NS_WARN_IF(error.Failed())) { return error.StealNSResult(); } // XXXkhuey this is terrible if (mContentType.IsEmpty()) { blob->GetType(mContentType); } BlobSet blobSet; blobSet.AppendBlobImpl(static_cast<File*>(blob.get())->Impl()); mBlobImpls = blobSet.GetBlobImpls(); SetLengthAndModifiedDate(error); if (NS_WARN_IF(error.Failed())) { return error.StealNSResult(); } if (aLastModifiedPassed) { SetLastModified(aLastModified); } return NS_OK; }
nsresult nsDOMMultipartFile::InitInternal(JSContext* aCx, PRUint32 aArgc, jsval* aArgv, UnwrapFuncPtr aUnwrapFunc) { bool nativeEOL = false; if (aArgc > 1) { mozilla::dom::BlobPropertyBag d; nsresult rv = d.Init(aCx, &aArgv[1]); NS_ENSURE_SUCCESS(rv, rv); mContentType = d.type; if (d.endings.EqualsLiteral("native")) { nativeEOL = true; } else if (!d.endings.EqualsLiteral("transparent")) { return NS_ERROR_DOM_INVALID_STATE_ERR; } } if (aArgc > 0) { if (!aArgv[0].isObject()) { return NS_ERROR_INVALID_ARG; // We're not interested } JSObject& obj = aArgv[0].toObject(); if (!JS_IsArrayObject(aCx, &obj)) { return NS_ERROR_INVALID_ARG; // We're not interested } BlobSet blobSet; uint32_t length; JS_ALWAYS_TRUE(JS_GetArrayLength(aCx, &obj, &length)); for (uint32_t i = 0; i < length; ++i) { jsval element; if (!JS_GetElement(aCx, &obj, i, &element)) return NS_ERROR_INVALID_ARG; if (element.isObject()) { JSObject& obj = element.toObject(); nsCOMPtr<nsIDOMBlob> blob = aUnwrapFunc(aCx, &obj); if (blob) { // Flatten so that multipart blobs will never nest nsDOMFileBase* file = static_cast<nsDOMFileBase*>( static_cast<nsIDOMBlob*>(blob)); const nsTArray<nsCOMPtr<nsIDOMBlob> >* subBlobs = file->GetSubBlobs(); if (subBlobs) { blobSet.AppendBlobs(*subBlobs); } else { blobSet.AppendBlob(blob); } } else if (JS_IsArrayBufferObject(&obj, aCx)) { blobSet.AppendArrayBuffer(&obj, aCx); } else { // neither arraybuffer nor blob return NS_ERROR_DOM_INVALID_STATE_ERR; } } else if (element.isString()) { blobSet.AppendString(element.toString(), nativeEOL, aCx); } else { // neither object nor string return NS_ERROR_DOM_INVALID_STATE_ERR; } } mBlobs = blobSet.GetBlobs(); } return NS_OK; }
nsresult nsDOMMultipartFile::InitInternal(JSContext* aCx, uint32_t aArgc, jsval* aArgv, UnwrapFuncPtr aUnwrapFunc) { bool nativeEOL = false; if (aArgc > 1) { if (NS_IsMainThread()) { BlobPropertyBag d; if (!d.Init(aCx, nullptr, aArgv[1])) { return NS_ERROR_TYPE_ERR; } mContentType = d.type; nativeEOL = d.endings == EndingTypesValues::Native; } else { BlobPropertyBagWorkers d; if (!d.Init(aCx, nullptr, aArgv[1])) { return NS_ERROR_TYPE_ERR; } mContentType = d.type; nativeEOL = d.endings == EndingTypesValues::Native; } } if (aArgc > 0) { if (!aArgv[0].isObject()) { return NS_ERROR_TYPE_ERR; // We're not interested } JSObject& obj = aArgv[0].toObject(); if (!JS_IsArrayObject(aCx, &obj)) { return NS_ERROR_TYPE_ERR; // We're not interested } BlobSet blobSet; uint32_t length; JS_ALWAYS_TRUE(JS_GetArrayLength(aCx, &obj, &length)); for (uint32_t i = 0; i < length; ++i) { jsval element; if (!JS_GetElement(aCx, &obj, i, &element)) return NS_ERROR_TYPE_ERR; if (element.isObject()) { JSObject& obj = element.toObject(); nsCOMPtr<nsIDOMBlob> blob = aUnwrapFunc(aCx, &obj); if (blob) { // Flatten so that multipart blobs will never nest nsDOMFileBase* file = static_cast<nsDOMFileBase*>( static_cast<nsIDOMBlob*>(blob)); const nsTArray<nsCOMPtr<nsIDOMBlob> >* subBlobs = file->GetSubBlobs(); if (subBlobs) { blobSet.AppendBlobs(*subBlobs); } else { blobSet.AppendBlob(blob); } continue; } if (JS_IsArrayBufferViewObject(&obj, aCx)) { blobSet.AppendVoidPtr(JS_GetArrayBufferViewData(&obj, aCx), JS_GetArrayBufferViewByteLength(&obj, aCx)); continue; } if (JS_IsArrayBufferObject(&obj, aCx)) { blobSet.AppendArrayBuffer(&obj, aCx); continue; } // neither Blob nor ArrayBuffer(View) } else if (element.isString()) { blobSet.AppendString(element.toString(), nativeEOL, aCx); continue; } // coerce it to a string JSString* str = JS_ValueToString(aCx, element); NS_ENSURE_TRUE(str, NS_ERROR_TYPE_ERR); blobSet.AppendString(str, nativeEOL, aCx); } mBlobs = blobSet.GetBlobs(); } return NS_OK; }
nsresult nsDOMMultipartFile::InitFile(JSContext* aCx, uint32_t aArgc, jsval* aArgv) { nsresult rv; NS_ASSERTION(!mImmutable, "Something went wrong ..."); NS_ENSURE_TRUE(!mImmutable, NS_ERROR_UNEXPECTED); if (!nsContentUtils::IsCallerChrome()) { return NS_ERROR_DOM_SECURITY_ERR; // Real short trip } NS_ENSURE_TRUE(aArgc > 0, NS_ERROR_UNEXPECTED); bool nativeEOL = false; if (aArgc > 1) { FilePropertyBag d; if (!d.Init(aCx, nullptr, aArgv[1])) { return NS_ERROR_TYPE_ERR; } mName = d.mName; mContentType = d.mType; nativeEOL = d.mEndings == EndingTypesValues::Native; } // We expect to get a path to represent as a File object, // an nsIFile, or an nsIDOMFile. nsCOMPtr<nsIFile> file; nsCOMPtr<nsIDOMFile> domFile; if (!aArgv[0].isString()) { // Lets see if it's an nsIFile if (!aArgv[0].isObject()) { return NS_ERROR_UNEXPECTED; // We're not interested } JSObject* obj = &aArgv[0].toObject(); nsISupports* supports = nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj); if (!supports) { return NS_ERROR_UNEXPECTED; } domFile = do_QueryInterface(supports); file = do_QueryInterface(supports); if (!domFile && !file) { return NS_ERROR_UNEXPECTED; } } else { // It's a string JSString* str = JS_ValueToString(aCx, aArgv[0]); NS_ENSURE_TRUE(str, NS_ERROR_XPC_BAD_CONVERT_JS); nsDependentJSString xpcomStr; if (!xpcomStr.init(aCx, str)) { return NS_ERROR_XPC_BAD_CONVERT_JS; } rv = NS_NewLocalFile(xpcomStr, false, getter_AddRefs(file)); NS_ENSURE_SUCCESS(rv, rv); } if (file) { bool exists; rv = file->Exists(&exists); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(exists, NS_ERROR_FILE_NOT_FOUND); bool isDir; rv = file->IsDirectory(&isDir); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_FALSE(isDir, NS_ERROR_FILE_IS_DIRECTORY); if (mName.IsEmpty()) { file->GetLeafName(mName); } domFile = new nsDOMFileFile(file); } // XXXkhuey this is terrible if (mContentType.IsEmpty()) { domFile->GetType(mContentType); } BlobSet blobSet; blobSet.AppendBlob(domFile); mBlobs = blobSet.GetBlobs(); return NS_OK; }
nsresult DOMMultipartFileImpl::InitChromeFile(JSContext* aCx, uint32_t aArgc, JS::Value* aArgv) { nsresult rv; NS_ASSERTION(!mImmutable, "Something went wrong ..."); NS_ENSURE_TRUE(!mImmutable, NS_ERROR_UNEXPECTED); MOZ_ASSERT(nsContentUtils::IsCallerChrome()); NS_ENSURE_TRUE(aArgc > 0, NS_ERROR_UNEXPECTED); if (aArgc > 1) { FilePropertyBag d; if (!d.Init(aCx, JS::Handle<JS::Value>::fromMarkedLocation(&aArgv[1]))) { return NS_ERROR_TYPE_ERR; } mName = d.mName; mContentType = d.mType; } // We expect to get a path to represent as a File object or // Blob object, an nsIFile, or an nsIDOMFile. nsCOMPtr<nsIFile> file; nsCOMPtr<nsIDOMBlob> blob; if (!aArgv[0].isString()) { // Lets see if it's an nsIFile if (!aArgv[0].isObject()) { return NS_ERROR_UNEXPECTED; // We're not interested } JSObject* obj = &aArgv[0].toObject(); nsISupports* supports = nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj); if (!supports) { return NS_ERROR_UNEXPECTED; } blob = do_QueryInterface(supports); file = do_QueryInterface(supports); if (!blob && !file) { return NS_ERROR_UNEXPECTED; } mIsFromNsiFile = true; } else { // It's a string JSString* str = JS::ToString(aCx, JS::Handle<JS::Value>::fromMarkedLocation(&aArgv[0])); NS_ENSURE_TRUE(str, NS_ERROR_XPC_BAD_CONVERT_JS); nsAutoJSString xpcomStr; if (!xpcomStr.init(aCx, str)) { return NS_ERROR_XPC_BAD_CONVERT_JS; } rv = NS_NewLocalFile(xpcomStr, false, getter_AddRefs(file)); NS_ENSURE_SUCCESS(rv, rv); } if (file) { bool exists; rv = file->Exists(&exists); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(exists, NS_ERROR_FILE_NOT_FOUND); bool isDir; rv = file->IsDirectory(&isDir); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_FALSE(isDir, NS_ERROR_FILE_IS_DIRECTORY); if (mName.IsEmpty()) { file->GetLeafName(mName); } nsRefPtr<DOMFile> domFile = DOMFile::CreateFromFile(file); // Pre-cache size. uint64_t unused; rv = domFile->GetSize(&unused); NS_ENSURE_SUCCESS(rv, rv); // Pre-cache modified date. rv = domFile->GetMozLastModifiedDate(&unused); NS_ENSURE_SUCCESS(rv, rv); blob = domFile.forget(); } // XXXkhuey this is terrible if (mContentType.IsEmpty()) { blob->GetType(mContentType); } BlobSet blobSet; blobSet.AppendBlobImpl(static_cast<DOMFile*>(blob.get())->Impl()); mBlobImpls = blobSet.GetBlobImpls(); SetLengthAndModifiedDate(); return NS_OK; }
nsresult DOMMultipartFileImpl::ParseBlobArrayArgument(JSContext* aCx, JS::Value& aValue, bool aNativeEOL, UnwrapFuncPtr aUnwrapFunc) { if (!aValue.isObject()) { return NS_ERROR_TYPE_ERR; // We're not interested } JS::Rooted<JSObject*> obj(aCx, &aValue.toObject()); if (!JS_IsArrayObject(aCx, obj)) { return NS_ERROR_TYPE_ERR; // We're not interested } BlobSet blobSet; uint32_t length; MOZ_ALWAYS_TRUE(JS_GetArrayLength(aCx, obj, &length)); for (uint32_t i = 0; i < length; ++i) { JS::Rooted<JS::Value> element(aCx); if (!JS_GetElement(aCx, obj, i, &element)) return NS_ERROR_TYPE_ERR; if (element.isObject()) { JS::Rooted<JSObject*> obj(aCx, &element.toObject()); nsCOMPtr<nsIDOMBlob> blob = aUnwrapFunc(aCx, obj); if (blob) { nsRefPtr<DOMFileImpl> blobImpl = static_cast<DOMFile*>(blob.get())->Impl(); // Flatten so that multipart blobs will never nest const nsTArray<nsRefPtr<DOMFileImpl>>* subBlobImpls = blobImpl->GetSubBlobImpls(); if (subBlobImpls) { blobSet.AppendBlobImpls(*subBlobImpls); } else { blobSet.AppendBlobImpl(blobImpl); } continue; } if (JS_IsArrayBufferViewObject(obj)) { nsresult rv = blobSet.AppendVoidPtr( JS_GetArrayBufferViewData(obj), JS_GetArrayBufferViewByteLength(obj)); NS_ENSURE_SUCCESS(rv, rv); continue; } if (JS_IsArrayBufferObject(obj)) { nsresult rv = blobSet.AppendArrayBuffer(obj); NS_ENSURE_SUCCESS(rv, rv); continue; } } // coerce it to a string JSString* str = JS::ToString(aCx, element); NS_ENSURE_TRUE(str, NS_ERROR_TYPE_ERR); nsresult rv = blobSet.AppendString(str, aNativeEOL, aCx); NS_ENSURE_SUCCESS(rv, rv); } mBlobImpls = blobSet.GetBlobImpls(); SetLengthAndModifiedDate(); return NS_OK; }