[tor-commits] [tor-browser/tor-browser-52.1.0esr-7.0-2] Bug 22327: Isolate Page Info media previews to content first party

gk at torproject.org gk at torproject.org
Wed May 31 20:36:42 UTC 2017


commit af4e5af7cfa3cfd73ff53fd6ec1be4e97e43f630
Author: Arthur Edelstein <arthuredelstein at gmail.com>
Date:   Wed May 10 17:10:23 2017 -0700

    Bug 22327: Isolate Page Info media previews to content first party
---
 browser/base/content/pageinfo/pageInfo.js |  9 +++++
 dom/base/nsContentUtils.cpp               | 63 ++++++++++++++++++++++---------
 dom/base/nsContentUtils.h                 |  7 ++++
 dom/html/HTMLMediaElement.cpp             |  2 +
 dom/media/MediaResource.cpp               |  2 +
 5 files changed, 66 insertions(+), 17 deletions(-)

diff --git a/browser/base/content/pageinfo/pageInfo.js b/browser/base/content/pageinfo/pageInfo.js
index 7a6d0a0..fc3e3bb 100644
--- a/browser/base/content/pageinfo/pageInfo.js
+++ b/browser/base/content/pageinfo/pageInfo.js
@@ -4,6 +4,11 @@
 
 Components.utils.import("resource://gre/modules/LoadContextInfo.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyServiceGetter(this, "gSerializationHelper",
+                                   "@mozilla.org/network/serialization-helper;1",
+                                   "nsISerializationHelper");
 
 // define a js object to implement nsITreeView
 function pageInfoTreeView(treeid, copycol)
@@ -881,6 +886,8 @@ function makePreview(row)
 
     var newImage = new Image;
     newImage.id = "thepreviewimage";
+    let loadingPrincipalString = gSerializationHelper.serializeToString(gDocInfo.principal);
+    newImage.setAttribute("loadingprincipal", loadingPrincipalString);
     var physWidth = 0, physHeight = 0;
     var width = 0, height = 0;
 
@@ -928,6 +935,7 @@ function makePreview(row)
     else if (item.HTMLVideoElement && isProtocolAllowed) {
       newImage = document.createElementNS("http://www.w3.org/1999/xhtml", "video");
       newImage.id = "thepreviewimage";
+      newImage.setAttribute("loadingprincipal", loadingPrincipalString);
       newImage.src = url;
       newImage.controls = true;
       width = physWidth = item.videoWidth;
@@ -939,6 +947,7 @@ function makePreview(row)
     else if (item.HTMLAudioElement && isProtocolAllowed) {
       newImage = new Audio;
       newImage.id = "thepreviewimage";
+      newImage.setAttribute("loadingprincipal", loadingPrincipalString);
       newImage.src = url;
       newImage.controls = true;
       isAudio = true;
diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
index 48f7991..f932742 100644
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -3367,6 +3367,15 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsINode* aContext,
   NS_PRECONDITION(aLoadingPrincipal, "Must have a principal");
   NS_PRECONDITION(aRequest, "Null out param");
 
+  // If the image is in a chrome document and the image node has been assigned a
+  // "loadingprincipal" attribute, we should use that principal instead.
+  if (IsSystemPrincipal(aLoadingPrincipal) && aContext->IsContent()) {
+    nsContentPolicyType contentPolicyType;
+    GetContentPolicyTypeForUIImageLoading(aContext->AsContent(),
+                                          &aLoadingPrincipal, contentPolicyType);
+    aContentPolicyType = (int32_t) contentPolicyType;
+  }
+
   imgLoader* imgLoader = GetImgLoaderForDocument(aLoadingDocument);
   if (!imgLoader) {
     // nothing we can do here
@@ -9879,25 +9888,45 @@ nsContentUtils::GetContentPolicyTypeForUIImageLoading(nsIContent* aLoadingNode,
 {
   // Use the serialized loadingPrincipal from the image element. Fall back
   // to mContent's principal (SystemPrincipal) if not available.
-  aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE;
   nsCOMPtr<nsIPrincipal> loadingPrincipal = aLoadingNode->NodePrincipal();
-  nsAutoString imageLoadingPrincipal;
-  aLoadingNode->GetAttr(kNameSpaceID_None, nsGkAtoms::loadingprincipal,
-                        imageLoadingPrincipal);
-  if (!imageLoadingPrincipal.IsEmpty()) {
-    nsCOMPtr<nsISupports> serializedPrincipal;
-    NS_DeserializeObject(NS_ConvertUTF16toUTF8(imageLoadingPrincipal),
-                         getter_AddRefs(serializedPrincipal));
-    loadingPrincipal = do_QueryInterface(serializedPrincipal);
-
-    if (loadingPrincipal) {
-      // Set the content policy type to TYPE_INTERNAL_IMAGE_FAVICON for
-      // indicating it's a favicon loading.
-      aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON;
-    } else {
-      // Fallback if the deserialization is failed.
-      loadingPrincipal = aLoadingNode->NodePrincipal();
+  if (IsSystemPrincipal(loadingPrincipal)) {
+    aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE;
+    nsAutoString imageLoadingPrincipal;
+    aLoadingNode->GetAttr(kNameSpaceID_None, nsGkAtoms::loadingprincipal,
+                          imageLoadingPrincipal);
+    if (!imageLoadingPrincipal.IsEmpty()) {
+      nsCOMPtr<nsISupports> serializedPrincipal;
+      NS_DeserializeObject(NS_ConvertUTF16toUTF8(imageLoadingPrincipal),
+                           getter_AddRefs(serializedPrincipal));
+      loadingPrincipal = do_QueryInterface(serializedPrincipal);
+
+      if (loadingPrincipal) {
+        // Set the content policy type to TYPE_INTERNAL_IMAGE_FAVICON for
+        // indicating it's a favicon loading.
+        aContentPolicyType = nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON;
+      } else {
+        // Fallback if the deserialization is failed.
+        loadingPrincipal = aLoadingNode->NodePrincipal();
+      }
     }
   }
   loadingPrincipal.forget(aLoadingPrincipal);
 }
+
+/* static */ void
+nsContentUtils::ApplyCustomLoadPrincipalToChannel(Element* aElement, nsIChannel* aChannel)
+{
+    nsCOMPtr<nsIPrincipal> loadingPrincipal = aElement->NodePrincipal();
+    if (loadingPrincipal && nsContentUtils::IsSystemPrincipal(loadingPrincipal)) {
+      nsContentPolicyType dummyContentPolicyType;
+      nsContentUtils::GetContentPolicyTypeForUIImageLoading(
+        aElement, getter_AddRefs(loadingPrincipal), dummyContentPolicyType);
+      NeckoOriginAttributes neckoAttrs;
+      neckoAttrs.InheritFromDocToNecko(
+        BasePrincipal::Cast(loadingPrincipal)->OriginAttributesRef());
+      nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
+      if (loadInfo) {
+        Unused << loadInfo->SetOriginAttributes(neckoAttrs);
+      }
+    }
+}
diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h
index 3c7d9eb..08c5cbf 100644
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -2746,6 +2746,13 @@ public:
                                         nsIPrincipal** aLoadingPrincipal,
                                         nsContentPolicyType& aContentPolicyType);
 
+  /**
+   * If aElement has a "loadprincipal" attribute, apply the origin attributes
+   * to the loadInfo belonging to aChannel.
+   */
+  static void
+  ApplyCustomLoadPrincipalToChannel(Element* aElement, nsIChannel* aChannel);
+
 private:
   static bool InitializeEventTable();
 
diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp
index 2f4f73f..37deffc 100644
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -586,6 +586,8 @@ public:
       return;
     }
 
+    nsContentUtils::ApplyCustomLoadPrincipalToChannel(aElement, channel);
+
     // The listener holds a strong reference to us.  This creates a
     // reference cycle, once we've set mChannel, which is manually broken
     // in the listener's OnStartRequest method after it is finished with
diff --git a/dom/media/MediaResource.cpp b/dom/media/MediaResource.cpp
index d36783b..a8f600f 100644
--- a/dom/media/MediaResource.cpp
+++ b/dom/media/MediaResource.cpp
@@ -833,6 +833,8 @@ ChannelMediaResource::RecreateChannel()
                               loadFlags);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  nsContentUtils::ApplyCustomLoadPrincipalToChannel(element, mChannel);
+
   // We have cached the Content-Type, which should not change. Give a hint to
   // the channel to avoid a sniffing failure, which would be expected because we
   // are probably seeking in the middle of the bitstream, and sniffing relies



More information about the tor-commits mailing list