From 6a8c4ffada73e1a8d7eb2265f003cbfc3ca263ab Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Tue, 19 Jul 2011 09:27:46 -0700 Subject: [PATCH] Bug 664254: Make DOM File objects implement nsIMutable so they can be immutabilized for sharing across threads. r=sicking --- content/base/public/nsDOMFile.h | 16 +++++++++++----- content/base/src/nsDOMFile.cpp | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/content/base/public/nsDOMFile.h b/content/base/public/nsDOMFile.h index 351898eba774..691a848d4ad4 100644 --- a/content/base/public/nsDOMFile.h +++ b/content/base/public/nsDOMFile.h @@ -46,6 +46,7 @@ #include "nsIDOMFileError.h" #include "nsIInputStream.h" #include "nsIJSNativeInitializer.h" +#include "nsIMutable.h" #include "nsCOMArray.h" #include "nsCOMPtr.h" #include "mozilla/AutoRestore.h" @@ -66,21 +67,22 @@ class nsIBlobBuilder; nsresult NS_NewBlobBuilder(nsISupports* *aSupports); class nsDOMFileBase : public nsIDOMFile, - public nsIXHRSendable + public nsIXHRSendable, + public nsIMutable { public: nsDOMFileBase(const nsAString& aName, const nsAString& aContentType, PRUint64 aLength) - : mIsFile(true), mContentType(aContentType), mName(aName), - mStart(0), mLength(aLength) + : mIsFile(true), mImmutable(false), mContentType(aContentType), + mName(aName), mStart(0), mLength(aLength) { // Ensure non-null mContentType by default mContentType.SetIsVoid(PR_FALSE); } nsDOMFileBase(const nsAString& aContentType, PRUint64 aLength) - : mIsFile(false), mContentType(aContentType), + : mIsFile(false), mImmutable(false), mContentType(aContentType), mStart(0), mLength(aLength) { // Ensure non-null mContentType by default @@ -89,7 +91,7 @@ public: nsDOMFileBase(const nsAString& aContentType, PRUint64 aStart, PRUint64 aLength) - : mIsFile(false), mContentType(aContentType), + : mIsFile(false), mImmutable(false), mContentType(aContentType), mStart(aStart), mLength(aLength) { NS_ASSERTION(aLength != PR_UINT64_MAX, @@ -108,6 +110,7 @@ public: NS_DECL_NSIDOMBLOB NS_DECL_NSIDOMFILE NS_DECL_NSIXHRSENDABLE + NS_DECL_NSIMUTABLE protected: bool IsSizeUnknown() @@ -116,6 +119,7 @@ protected: } bool mIsFile; + bool mImmutable; nsString mContentType; nsString mName; @@ -186,6 +190,7 @@ protected: mCacheToken(aOther->mCacheToken) { NS_ASSERTION(mFile, "must have file"); + mImmutable = aOther->mImmutable; } virtual already_AddRefed CreateSlice(PRUint64 aStart, PRUint64 aLength, @@ -230,6 +235,7 @@ protected: mDataOwner(aOther->mDataOwner) { NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data"); + mImmutable = aOther->mImmutable; } virtual already_AddRefed CreateSlice(PRUint64 aStart, PRUint64 aLength, diff --git a/content/base/src/nsDOMFile.cpp b/content/base/src/nsDOMFile.cpp index ededcc26d2df..d4169f32d8fc 100644 --- a/content/base/src/nsDOMFile.cpp +++ b/content/base/src/nsDOMFile.cpp @@ -143,6 +143,7 @@ NS_INTERFACE_MAP_BEGIN(nsDOMFileBase) NS_INTERFACE_MAP_ENTRY(nsIDOMBlob) NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIDOMFile, mIsFile) NS_INTERFACE_MAP_ENTRY(nsIXHRSendable) + NS_INTERFACE_MAP_ENTRY(nsIMutable) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(File, mIsFile) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(Blob, !mIsFile) NS_INTERFACE_MAP_END @@ -313,6 +314,35 @@ nsDOMFileBase::GetSendInfo(nsIInputStream** aBody, return NS_OK; } +NS_IMETHODIMP +nsDOMFileBase::GetMutable(PRBool* aMutable) +{ + *aMutable = !mImmutable; + return NS_OK; +} + +NS_IMETHODIMP +nsDOMFileBase::SetMutable(PRBool aMutable) +{ + nsresult rv = NS_OK; + + NS_ENSURE_ARG(!mImmutable || !aMutable); + + if (!mImmutable && !aMutable) { + // Force the content type and size to be cached + nsString dummyString; + rv = this->GetType(dummyString); + NS_ENSURE_SUCCESS(rv, rv); + + PRUint64 dummyInt; + rv = this->GetSize(&dummyInt); + NS_ENSURE_SUCCESS(rv, rv); + } + + mImmutable = !aMutable; + return rv; +} + //////////////////////////////////////////////////////////////////////////// // nsDOMFileFile implementation @@ -413,6 +443,9 @@ nsDOMFileFile::Initialize(nsISupports* aOwner, { 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 }