Bug 1506693: PDFJS range-based requests violate FPI r=bdahl
authorpospeselr <richard@torproject.org>
Mon, 13 May 2019 23:41:57 +0000
changeset 532511 b1c78bd9fdc280ce52f84e105321a79a89e2177a
parent 532510 419436973f91a86cee1fb0523be60f5b131847b4
child 532512 96563508f9fed49ddc64469d05c9d3d7be46d547
push id11268
push usercsabou@mozilla.com
push dateTue, 14 May 2019 15:24:22 +0000
treeherdermozilla-beta@5fb7fcd568d6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbdahl
bugs1506693
milestone68.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 1506693: PDFJS range-based requests violate FPI r=bdahl Large pdf files download in parts via range-based requests so that users can begin reading before the entire file has finished downloading. This is implemented using XMLHttpRequests. However, since these requests are created in the chrome, they are given the System Principal and lack the correct firstPartyDomain associated with the parent window. This patch manually sets the XMLHttpRequest's originAttributes to the one provided by the real owning window cached in the RangedChromeActions object. This is done via the chrome-only setOriginAttributes method. The method is called in the xhr_onreadystatechanged() callback rather than directly after construction in getXhr() because the setOriginAttributes implementation requires the internal nsIChannel object to have been created but not used. Fortunately, the XMLHttpRequest object fires the readStateChangedEvent precisely after the channel has been created in the XmlHttpRequest's Open() method. The nsIChannel's nsILoadInfo's OriginAttributes are now overwritten with the known OriginAttributes of the parent window before anything else has had a chance to use it. Differential Revision: https://phabricator.services.mozilla.com/D30689
browser/extensions/pdfjs/content/PdfStreamConverter.jsm
--- a/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
+++ b/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
@@ -218,16 +218,24 @@ class ChromeActions {
       startAt: Date.now(),
     };
   }
 
   isInPrivateBrowsing() {
     return PrivateBrowsingUtils.isContentWindowPrivate(this.domWindow);
   }
 
+  getWindowOriginAttributes() {
+    try {
+      return this.domWindow.document.nodePrincipal.originAttributes;
+    } catch (err) {
+      return {};
+    }
+  }
+
   download(data, sendResponse) {
     var self = this;
     var originalUrl = data.originalUrl;
     var blobUrl = data.blobUrl || originalUrl;
     // The data may not be downloaded so we need just retry getting the pdf with
     // the original url.
     var originalUri = NetUtil.newURI(originalUrl);
     var filename = data.filename;
@@ -577,16 +585,19 @@ class RangedChromeActions extends Chrome
     if (originalRequest.visitRequestHeaders) {
       originalRequest.visitRequestHeaders(httpHeaderVisitor);
     }
 
     var self = this;
     var xhr_onreadystatechange = function xhr_onreadystatechange() {
       if (this.readyState === 1) { // LOADING
         var netChannel = this.channel;
+        // override this XMLHttpRequest's OriginAttributes with our cached parent window's
+        // OriginAttributes, as we are currently running under the SystemPrincipal
+        this.setOriginAttributes(self.getWindowOriginAttributes());
         if ("nsIPrivateBrowsingChannel" in Ci &&
             netChannel instanceof Ci.nsIPrivateBrowsingChannel) {
           var docIsPrivate = self.isInPrivateBrowsing();
           netChannel.setPrivate(docIsPrivate);
         }
       }
     };
     var getXhr = function getXhr() {