Bug 1406278: Part 5b - Use subject principal as triggering principal in <source> "src" attribute for <audio>/<video>. r=bz
authorKris Maglione <maglione.k@gmail.com>
Thu, 05 Oct 2017 15:28:22 -0700
changeset 385230 ac4afd1e97b7856b0ff604fb7b867d555cecd40c
parent 385229 e894f7b9168b33eebda126c7b4b431a833807710
child 385231 19b365ebc32cd5895080ab0a572fc0cacdbcaefe
push id95948
push usermaglione.k@gmail.com
push dateTue, 10 Oct 2017 03:38:28 +0000
treeherdermozilla-inbound@ec0c2767cf57 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1406278
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1406278: Part 5b - Use subject principal as triggering principal in <source> "src" attribute for <audio>/<video>. r=bz MozReview-Commit-ID: zZCXpvs719
dom/html/HTMLMediaElement.cpp
dom/html/HTMLSourceElement.cpp
dom/html/HTMLSourceElement.h
dom/webidl/HTMLSourceElement.webidl
toolkit/components/extensions/test/xpcshell/test_ext_contentscript_triggeringPrincipal.js
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -2372,17 +2372,17 @@ void HTMLMediaElement::LoadFromSourceChi
       const char16_t* params[] = { src.get() };
       ReportLoadError("MediaLoadInvalidURI", params, ArrayLength(params));
       DealWithFailedElement(child);
       return;
     }
 
     RemoveMediaElementFromURITable();
     mLoadingSrc = uri;
-    mLoadingSrcTriggeringPrincipal = nullptr;
+    mLoadingSrcTriggeringPrincipal = childSrc->GetSrcTriggeringPrincipal();
     mMediaSource = childSrc->GetSrcMediaSource();
     NS_ASSERTION(mNetworkState == nsIDOMHTMLMediaElement::NETWORK_LOADING,
                  "Network state should be loading");
 
     if (mPreloadAction == HTMLMediaElement::PRELOAD_NONE &&
         !IsMediaStreamURI(mLoadingSrc) && !mMediaSource) {
       // preload:none media, suspend the load here before we make any
       // network requests.
--- a/dom/html/HTMLSourceElement.cpp
+++ b/dom/html/HTMLSourceElement.cpp
@@ -126,16 +126,19 @@ HTMLSourceElement::AfterSetAttr(int32_t 
           img->PictureSourceMediaOrTypeChanged(AsContent(), aNotify);
         }
       }
     }
 
   } else if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::media) {
     UpdateMediaList(aValue);
   } else if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::src) {
+    mSrcTriggeringPrincipal = nsContentUtils::GetAttrTriggeringPrincipal(
+        this, aValue ? aValue->GetStringValue() : EmptyString(),
+        aMaybeScriptedPrincipal);
     mSrcMediaSource = nullptr;
     if (aValue) {
       nsString srcStr = aValue->GetStringValue();
       nsCOMPtr<nsIURI> uri;
       NewURIFromString(srcStr, getter_AddRefs(uri));
       if (uri && IsMediaSourceURI(uri)) {
         NS_GetSourceForMediaSourceURI(uri, getter_AddRefs(mSrcMediaSource));
       }
--- a/dom/html/HTMLSourceElement.h
+++ b/dom/html/HTMLSourceElement.h
@@ -54,23 +54,28 @@ public:
   static bool WouldMatchMediaForDocument(const nsAString& aMediaStr,
                                          const nsIDocument *aDocument);
 
   // Return the MediaSource object if any associated with the src attribute
   // when it was set.
   MediaSource* GetSrcMediaSource() { return mSrcMediaSource; };
 
   // WebIDL
-  void GetSrc(nsString& aSrc)
+  void GetSrc(nsString& aSrc, nsIPrincipal&)
   {
     GetURIAttr(nsGkAtoms::src, nullptr, aSrc);
   }
-  void SetSrc(const nsAString& aSrc, mozilla::ErrorResult& rv)
+  void SetSrc(const nsAString& aSrc, nsIPrincipal& aTriggeringPrincipal, mozilla::ErrorResult& rv)
   {
-    SetHTMLAttr(nsGkAtoms::src, aSrc, rv);
+    SetHTMLAttr(nsGkAtoms::src, aSrc, aTriggeringPrincipal, rv);
+  }
+
+  nsIPrincipal* GetSrcTriggeringPrincipal() const
+  {
+    return mSrcTriggeringPrincipal;
   }
 
   void GetType(DOMString& aType)
   {
     GetHTMLAttr(nsGkAtoms::type, aType);
   }
   void SetType(const nsAString& aType, ErrorResult& rv)
   {
@@ -115,16 +120,19 @@ protected:
                                 const nsAttrValue* aOldValue,
                                 nsIPrincipal* aMaybeScriptedPrincipal,
                                 bool aNotify) override;
 
 private:
   RefPtr<MediaList> mMediaList;
   RefPtr<MediaSource> mSrcMediaSource;
 
+  // The triggering principal for the src attribute.
+  nsCOMPtr<nsIPrincipal> mSrcTriggeringPrincipal;
+
   // Generates a new MediaList using the given input
   void UpdateMediaList(const nsAttrValue* aValue);
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_HTMLSourceElement_h
--- a/dom/webidl/HTMLSourceElement.webidl
+++ b/dom/webidl/HTMLSourceElement.webidl
@@ -8,17 +8,17 @@
  *
  * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
  * Opera Software ASA. You are granted a license to use, reproduce
  * and create derivative works of this document.
  */
 
 [HTMLConstructor]
 interface HTMLSourceElement : HTMLElement {
-           [CEReactions, SetterThrows]
+           [CEReactions, NeedsSubjectPrincipal, SetterThrows]
            attribute DOMString src;
            [CEReactions, SetterThrows]
            attribute DOMString type;
 };
 
 partial interface HTMLSourceElement {
            [CEReactions, SetterThrows]
            attribute DOMString srcset;
--- a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_triggeringPrincipal.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_triggeringPrincipal.js
@@ -39,17 +39,17 @@ function registerStaticPage(path, conten
 }
 
 const BASE_URL = `http://localhost:${server.identity.primaryPort}`;
 
 /**
  * A set of tags which are automatically closed in HTML documents, and
  * do not require an explicit closing tag.
  */
-const AUTOCLOSE_TAGS = new Set(["img"]);
+const AUTOCLOSE_TAGS = new Set(["img", "source"]);
 
 /**
  * An object describing the elements to create for a specific test.
  *
  * @typedef {object} ElementTestCase
  * @property {Array} element
  *        A recursive array, describing the element to create, in the
  *        following format:
@@ -432,16 +432,20 @@ add_task(async function test_contentscri
    * A list of tests to run in each context, as understood by
    * {@see getElementData}.
    */
   const TESTS = [
     {
       element: ["audio", {}],
       src: "audio.webm",
     },
+    {
+      element: ["audio", {}, ["source", {}]],
+      src: "audio-source.webm",
+    },
     // TODO: <frame> element, which requires a frameset document.
     {
       element: ["iframe", {}],
       src: "iframe.html",
     },
     {
       element: ["img", {}],
       src: "img.png",
@@ -455,16 +459,20 @@ add_task(async function test_contentscri
       element: ["script", {}],
       src: "script.js",
       liveSrc: false,
     },
     {
       element: ["video", {}],
       src: "video.webm",
     },
+    {
+      element: ["video", {}, ["source", {}]],
+      src: "video-source.webm",
+    },
   ];
 
   /**
    * A set of sources for which each of the above tests is expected to
    * generate one request, if each of the properties in the value object
    * matches the value of the same property in the test object.
    */
   const SOURCES = {