Bug 1306222 - Use NeedsSubjectPrincipal in DataTransfer, r=ehsan
authorAndrea Marchesini <amarchesini@mozilla.com>
Fri, 30 Sep 2016 19:54:28 +0200
changeset 419818 d1ea28929a0cd640b17ec9817ad6c66e7812dc30
parent 419817 069d41a294b8179a226e359de8c9936e003f5309
child 419819 ed543800e8086463fb87b97bf136216c48b15bec
push id31023
push usercykesiopka.bmo@gmail.com
push dateSat, 01 Oct 2016 01:30:33 +0000
reviewersehsan
bugs1306222
milestone52.0a1
Bug 1306222 - Use NeedsSubjectPrincipal in DataTransfer, r=ehsan
dom/events/ClipboardEvent.cpp
dom/events/DataTransfer.cpp
dom/events/DataTransfer.h
dom/webidl/DataTransfer.webidl
--- a/dom/events/ClipboardEvent.cpp
+++ b/dom/events/ClipboardEvent.cpp
@@ -70,17 +70,18 @@ ClipboardEvent::Constructor(const Global
   RefPtr<DataTransfer> clipboardData;
   if (e->mEventIsInternal) {
     InternalClipboardEvent* event = e->mEvent->AsClipboardEvent();
     if (event) {
       // Always create a clipboardData for the copy event. If this is changed to
       // support other types of events, make sure that read/write privileges are
       // checked properly within DataTransfer.
       clipboardData = new DataTransfer(ToSupports(e), eCopy, false, -1);
-      clipboardData->SetData(aParam.mDataType, aParam.mData, aRv);
+      clipboardData->SetData(aParam.mDataType, aParam.mData,
+                             Some(aGlobal.GetSubjectPrincipal()), aRv);
       NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
     }
   }
 
   e->InitClipboardEvent(aType, aParam.mBubbles, aParam.mCancelable,
                         clipboardData);
   e->SetTrusted(trusted);
   return e.forget();
--- a/dom/events/DataTransfer.cpp
+++ b/dom/events/DataTransfer.cpp
@@ -279,19 +279,21 @@ DataTransfer::SetEffectAllowedInt(uint32
 NS_IMETHODIMP
 DataTransfer::GetMozUserCancelled(bool* aUserCancelled)
 {
   *aUserCancelled = MozUserCancelled();
   return NS_OK;
 }
 
 already_AddRefed<FileList>
-DataTransfer::GetFiles(ErrorResult& aRv)
+DataTransfer::GetFiles(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
+                       ErrorResult& aRv)
 {
-  return mItems->Files(nsContentUtils::SubjectPrincipal());
+  MOZ_ASSERT(aSubjectPrincipal.isSome());
+  return mItems->Files(aSubjectPrincipal.value());
 }
 
 NS_IMETHODIMP
 DataTransfer::GetFiles(nsIDOMFileList** aFileList)
 {
   if (!aFileList) {
     return NS_ERROR_FAILURE;
   }
@@ -369,24 +371,27 @@ DataTransfer::GetTypes(nsISupports** aTy
   }
 
   types.forget(aTypes);
   return NS_OK;
 }
 
 void
 DataTransfer::GetData(const nsAString& aFormat, nsAString& aData,
+                      const Maybe<nsIPrincipal*>& aSubjectPrincipal,
                       ErrorResult& aRv)
 {
+  MOZ_ASSERT(aSubjectPrincipal.isSome());
+
   // return an empty string if data for the format was not found
   aData.Truncate();
 
   nsCOMPtr<nsIVariant> data;
   nsresult rv =
-    GetDataAtInternal(aFormat, 0, nsContentUtils::SubjectPrincipal(),
+    GetDataAtInternal(aFormat, 0, aSubjectPrincipal.value(),
                       getter_AddRefs(data));
   if (NS_FAILED(rv)) {
     if (rv != NS_ERROR_DOM_INDEX_SIZE_ERR) {
       aRv.Throw(rv);
     }
     return;
   }
 
@@ -428,29 +433,31 @@ DataTransfer::GetData(const nsAString& a
     }
   }
 }
 
 NS_IMETHODIMP
 DataTransfer::GetData(const nsAString& aFormat, nsAString& aData)
 {
   ErrorResult rv;
-  GetData(aFormat, aData, rv);
+  GetData(aFormat, aData, Some(nsContentUtils::SubjectPrincipal()), rv);
   return rv.StealNSResult();
 }
 
 void
 DataTransfer::SetData(const nsAString& aFormat, const nsAString& aData,
+                      const Maybe<nsIPrincipal*>& aSubjectPrincipal,
                       ErrorResult& aRv)
 {
+  MOZ_ASSERT(aSubjectPrincipal.isSome());
+
   RefPtr<nsVariantCC> variant = new nsVariantCC();
   variant->SetAsAString(aData);
 
-  aRv = SetDataAtInternal(aFormat, variant, 0,
-                          nsContentUtils::SubjectPrincipal());
+  aRv = SetDataAtInternal(aFormat, variant, 0, aSubjectPrincipal.value());
 }
 
 void
 DataTransfer::ClearData(const Optional<nsAString>& aFormat,
                         const Maybe<nsIPrincipal*>& aSubjectPrincipal,
                         ErrorResult& aRv)
 {
   MOZ_ASSERT(aSubjectPrincipal.isSome());
@@ -636,20 +643,23 @@ DataTransfer::GetDataAtInternal(const ns
   data.forget(aData);
   return NS_OK;
 }
 
 void
 DataTransfer::MozGetDataAt(JSContext* aCx, const nsAString& aFormat,
                            uint32_t aIndex,
                            JS::MutableHandle<JS::Value> aRetval,
+                           const Maybe<nsIPrincipal*>& aSubjectPrincipal,
                            mozilla::ErrorResult& aRv)
 {
+  MOZ_ASSERT(aSubjectPrincipal.isSome());
+
   nsCOMPtr<nsIVariant> data;
-  aRv = GetDataAtInternal(aFormat, aIndex, nsContentUtils::SubjectPrincipal(),
+  aRv = GetDataAtInternal(aFormat, aIndex, aSubjectPrincipal.value(),
                           getter_AddRefs(data));
   if (aRv.Failed()) {
     return;
   }
 
   if (!data) {
     aRetval.setNull();
     return;
@@ -718,25 +728,27 @@ DataTransfer::SetDataAtInternal(const ns
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   return SetDataWithPrincipal(aFormat, aData, aIndex, aSubjectPrincipal);
 }
 
 void
 DataTransfer::MozSetDataAt(JSContext* aCx, const nsAString& aFormat,
-                           JS::Handle<JS::Value> aData,
-                           uint32_t aIndex, ErrorResult& aRv)
+                           JS::Handle<JS::Value> aData, uint32_t aIndex,
+                           const Maybe<nsIPrincipal*>& aSubjectPrincipal,
+                           ErrorResult& aRv)
 {
+  MOZ_ASSERT(aSubjectPrincipal.isSome());
+
   nsCOMPtr<nsIVariant> data;
   aRv = nsContentUtils::XPConnect()->JSValToVariant(aCx, aData,
                                                     getter_AddRefs(data));
   if (!aRv.Failed()) {
-    aRv = SetDataAtInternal(aFormat, data, aIndex,
-                            nsContentUtils::SubjectPrincipal());
+    aRv = SetDataAtInternal(aFormat, data, aIndex, aSubjectPrincipal.value());
   }
 }
 
 void
 DataTransfer::MozClearDataAt(const nsAString& aFormat, uint32_t aIndex,
                              const Maybe<nsIPrincipal*>& aSubjectPrincipal,
                              ErrorResult& aRv)
 {
@@ -813,18 +825,21 @@ DataTransfer::SetDragImage(nsIDOMElement
   nsCOMPtr<Element> image = do_QueryInterface(aImage);
   if (image) {
     SetDragImage(*image, aX, aY, rv);
   }
   return rv.StealNSResult();
 }
 
 already_AddRefed<Promise>
-DataTransfer::GetFilesAndDirectories(ErrorResult& aRv)
+DataTransfer::GetFilesAndDirectories(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
+                                     ErrorResult& aRv)
 {
+  MOZ_ASSERT(aSubjectPrincipal.isSome());
+
   nsCOMPtr<nsINode> parentNode = do_QueryInterface(mParent);
   if (!parentNode) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsCOMPtr<nsIGlobalObject> global = parentNode->OwnerDoc()->GetScopeObject();
   MOZ_ASSERT(global);
@@ -833,37 +848,39 @@ DataTransfer::GetFilesAndDirectories(Err
     return nullptr;
   }
 
   RefPtr<Promise> p = Promise::Create(global, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
-  RefPtr<FileList> files = mItems->Files(nsContentUtils::SubjectPrincipal());
+  RefPtr<FileList> files = mItems->Files(aSubjectPrincipal.value());
   if (NS_WARN_IF(!files)) {
     return nullptr;
   }
 
   Sequence<RefPtr<File>> filesSeq;
   files->ToSequence(filesSeq, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   p->MaybeResolve(filesSeq);
 
   return p.forget();
 }
 
 already_AddRefed<Promise>
-DataTransfer::GetFiles(bool aRecursiveFlag, ErrorResult& aRv)
+DataTransfer::GetFiles(bool aRecursiveFlag,
+                       const Maybe<nsIPrincipal*>& aSubjectPrincipal,
+                       ErrorResult& aRv)
 {
   // Currently we don't support directories.
-  return GetFilesAndDirectories(aRv);
+  return GetFilesAndDirectories(aSubjectPrincipal, aRv);
 }
 
 void
 DataTransfer::AddElement(Element& aElement, ErrorResult& aRv)
 {
   if (mReadOnly) {
     aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
     return;
--- a/dom/events/DataTransfer.h
+++ b/dom/events/DataTransfer.h
@@ -133,30 +133,40 @@ public:
     }
   }
 
   void SetDragImage(Element& aElement, int32_t aX, int32_t aY,
                     ErrorResult& aRv);
 
   already_AddRefed<DOMStringList> GetTypes(ErrorResult& rv) const;
 
-  void GetData(const nsAString& aFormat, nsAString& aData, ErrorResult& aRv);
+  void GetData(const nsAString& aFormat, nsAString& aData,
+               const Maybe<nsIPrincipal*>& aSubjectPrincipal,
+               ErrorResult& aRv);
 
   void SetData(const nsAString& aFormat, const nsAString& aData,
+               const Maybe<nsIPrincipal*>& aSubjectPrincipal,
                ErrorResult& aRv);
 
   void ClearData(const mozilla::dom::Optional<nsAString>& aFormat,
                  const Maybe<nsIPrincipal*>& aSubjectPrincipal,
                  mozilla::ErrorResult& aRv);
 
-  already_AddRefed<FileList> GetFiles(mozilla::ErrorResult& aRv);
+  already_AddRefed<FileList>
+  GetFiles(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
+           mozilla::ErrorResult& aRv);
 
-  already_AddRefed<Promise> GetFilesAndDirectories(ErrorResult& aRv);
+  already_AddRefed<Promise>
+  GetFilesAndDirectories(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
+                         mozilla::ErrorResult& aRv);
 
-  already_AddRefed<Promise> GetFiles(bool aRecursiveFlag, ErrorResult& aRv);
+  already_AddRefed<Promise>
+  GetFiles(bool aRecursiveFlag,
+           const Maybe<nsIPrincipal*>& aSubjectPrincipal,
+           ErrorResult& aRv);
 
 
   void AddElement(Element& aElement, mozilla::ErrorResult& aRv);
 
   uint32_t MozItemCount() const;
 
   void GetMozCursor(nsString& aCursor)
   {
@@ -171,20 +181,22 @@ public:
                                              mozilla::ErrorResult& aRv) const;
 
   void MozClearDataAt(const nsAString& aFormat, uint32_t aIndex,
                       const Maybe<nsIPrincipal*>& aSubjectPrincipal,
                       mozilla::ErrorResult& aRv);
 
   void MozSetDataAt(JSContext* aCx, const nsAString& aFormat,
                     JS::Handle<JS::Value> aData, uint32_t aIndex,
+                    const Maybe<nsIPrincipal*>& aSubjectPrincipal,
                     mozilla::ErrorResult& aRv);
 
   void MozGetDataAt(JSContext* aCx, const nsAString& aFormat,
                     uint32_t aIndex, JS::MutableHandle<JS::Value> aRetval,
+                    const Maybe<nsIPrincipal*>& aSubjectPrincipal,
                     mozilla::ErrorResult& aRv);
 
   bool MozUserCancelled() const
   {
     return mUserCancelled;
   }
 
   already_AddRefed<nsINode> GetMozSourceNode();
@@ -358,9 +370,8 @@ protected:
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(DataTransfer, NS_DATATRANSFER_IID)
 
 } // namespace dom
 } // namespace mozilla
 
 #endif /* mozilla_dom_DataTransfer_h */
-
--- a/dom/webidl/DataTransfer.webidl
+++ b/dom/webidl/DataTransfer.webidl
@@ -14,31 +14,31 @@ interface DataTransfer {
 
   readonly attribute DataTransferItemList items;
 
   [Throws]
   void setDragImage(Element image, long x, long y);
 
   [Throws]
   readonly attribute DOMStringList types;
-  [Throws]
+  [Throws, NeedsSubjectPrincipal]
   DOMString getData(DOMString format);
-  [Throws]
+  [Throws, NeedsSubjectPrincipal]
   void setData(DOMString format, DOMString data);
   [Throws, NeedsSubjectPrincipal]
   void clearData(optional DOMString format);
-  [Throws]
+  [Throws, NeedsSubjectPrincipal]
   readonly attribute FileList? files;
 };
 
 partial interface DataTransfer {
-  [Throws, Pref="dom.input.dirpicker"]
+  [Throws, Pref="dom.input.dirpicker", NeedsSubjectPrincipal]
   Promise<sequence<(File or Directory)>> getFilesAndDirectories();
 
-  [Throws, Pref="dom.input.dirpicker"]
+  [Throws, Pref="dom.input.dirpicker", NeedsSubjectPrincipal]
   Promise<sequence<File>>                getFiles(optional boolean recursiveFlag = false);
 };
 
 // Mozilla specific stuff
 partial interface DataTransfer {
   /*
    * Set the drag source. Usually you would not change this, but it will
    * affect which node the drag and dragend events are fired at. The
@@ -110,29 +110,29 @@ partial interface DataTransfer {
    * (which will be converted into a string) or an nsISupports.
    *
    * @param format the format to add
    * @param data the data to add
    * @throws NS_ERROR_NULL_POINTER if the data is null
    * @throws NS_ERROR_DOM_INDEX_SIZE_ERR if index is greater than itemCount
    * @throws NO_MODIFICATION_ALLOWED_ERR if the item cannot be modified
    */
-  [Throws]
+  [Throws, NeedsSubjectPrincipal]
   void mozSetDataAt(DOMString format, any data, unsigned long index);
 
   /**
    * Retrieve the data associated with the given format for an item at the
    * specified index, or null if it does not exist. The index should be in the
    * range from zero to itemCount - 1.
    *
    * @param format the format of the data to look up
    * @returns the data of the given format, or null if it doesn't exist.
    * @throws NS_ERROR_DOM_INDEX_SIZE_ERR if index is greater or equal than itemCount
    */
-  [Throws]
+  [Throws, NeedsSubjectPrincipal]
   any mozGetDataAt(DOMString format, unsigned long index);
 
   /**
    * Will be true when the user has cancelled the drag (typically by pressing
    * Escape) and when the drag has been cancelled unexpectedly.  This will be
    * false otherwise, including when the drop has been rejected by its target.
    * This property is only relevant for the dragend event.
    */