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