already_AddRefed<File> DataTransferItem::GetAsFile(nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) { // This is done even if we have an mCachedFile, as it performs the necessary // permissions checks to ensure that we are allowed to access this type. nsCOMPtr<nsIVariant> data = Data(&aSubjectPrincipal, aRv); if (NS_WARN_IF(!data || aRv.Failed())) { return nullptr; } // We have to check our kind after getting the data, because if we have // external data and the OS lied to us (which unfortunately does happen // sometimes), then we might not have the same type of data as we did coming // into this function. if (NS_WARN_IF(mKind != KIND_FILE)) { return nullptr; } // Generate the dom::File from the stored data, caching it so that the // same object is returned in the future. if (!mCachedFile) { nsCOMPtr<nsISupports> supports; aRv = data->GetAsISupports(getter_AddRefs(supports)); MOZ_ASSERT(!aRv.Failed() && supports, "File objects should be stored as nsISupports variants"); if (aRv.Failed() || !supports) { return nullptr; } if (nsCOMPtr<nsIDOMBlob> domBlob = do_QueryInterface(supports)) { Blob* blob = static_cast<Blob*>(domBlob.get()); mCachedFile = blob->ToFile(); } else if (nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(supports)) { MOZ_ASSERT(blobImpl->IsFile()); mCachedFile = File::Create(mDataTransfer, blobImpl); } else if (nsCOMPtr<nsIFile> ifile = do_QueryInterface(supports)) { mCachedFile = File::CreateFromFile(mDataTransfer, ifile); } else { MOZ_ASSERT(false, "One of the above code paths should be taken"); return nullptr; } } RefPtr<File> file = mCachedFile; return file.forget(); }
already_AddRefed<File> DataTransferItem::GetAsFileWithPrincipal(nsIPrincipal* aPrincipal, ErrorResult& aRv) { if (mKind != KIND_FILE) { return nullptr; } // This is done even if we have an mCachedFile, as it performs the necessary // permissions checks to ensure that we are allowed to access this type. nsCOMPtr<nsIVariant> data = Data(aPrincipal, aRv); if (NS_WARN_IF(!data || aRv.Failed())) { return nullptr; } // Generate the dom::File from the stored data, caching it so that the // same object is returned in the future. if (!mCachedFile) { nsCOMPtr<nsISupports> supports; aRv = data->GetAsISupports(getter_AddRefs(supports)); MOZ_ASSERT(!aRv.Failed() && supports, "File objects should be stored as nsISupports variants"); if (aRv.Failed() || !supports) { return nullptr; } if (nsCOMPtr<nsIDOMBlob> domBlob = do_QueryInterface(supports)) { Blob* blob = static_cast<Blob*>(domBlob.get()); mCachedFile = blob->ToFile(); } else if (nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(supports)) { MOZ_ASSERT(blobImpl->IsFile()); mCachedFile = File::Create(mDataTransfer, blobImpl); } else if (nsCOMPtr<nsIFile> ifile = do_QueryInterface(supports)) { mCachedFile = File::CreateFromFile(mDataTransfer, ifile); } else { MOZ_ASSERT(false, "One of the above code paths should be taken"); } } RefPtr<File> file = mCachedFile; return file.forget(); }