Bug 1360285 testing tentative fix for punycode in webrequest/nav draft
authorShane Caraveo <scaraveo@mozilla.com>
Thu, 15 Jun 2017 17:03:39 -0700
changeset 595052 45190fa85b7f7ae83b3b023d8602c1489fd0943d
parent 593475 91134c95d68cbcfe984211fa3cbd28d610361ef1
child 633615 25df0016626acbf7bfab8ae866cd3950193edf49
push id64238
push usermixedpuppy@gmail.com
push dateFri, 16 Jun 2017 00:06:43 +0000
bugs1360285
milestone56.0a1
Bug 1360285 testing tentative fix for punycode in webrequest/nav MozReview-Commit-ID: 5ULVdLFOLGZ
toolkit/components/extensions/test/mochitest/mochitest-common.ini
toolkit/components/extensions/test/mochitest/test_ext_webrequest_punycode.html
toolkit/modules/addons/WebNavigationContent.js
toolkit/modules/addons/WebRequest.jsm
toolkit/modules/addons/WebRequestContent.js
--- a/toolkit/components/extensions/test/mochitest/mochitest-common.ini
+++ b/toolkit/components/extensions/test/mochitest/mochitest-common.ini
@@ -110,14 +110,15 @@ skip-if = os == 'android'
 [test_ext_webrequest_background_events.html]
 [test_ext_webrequest_basic.html]
 [test_ext_webrequest_filter.html]
 [test_ext_webrequest_frameId.html]
 [test_ext_webrequest_suspend.html]
 [test_ext_webrequest_upload.html]
 skip-if = os == 'android' # Currently fails in emulator tests
 [test_ext_webrequest_permission.html]
+[test_ext_webrequest_punycode.html]
 [test_ext_webrequest_websocket.html]
 [test_ext_webnavigation.html]
 [test_ext_webnavigation_filters.html]
 [test_ext_window_postMessage.html]
 [test_ext_subframes_privileges.html]
 [test_ext_xhr_capabilities.html]
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/mochitest/test_ext_webrequest_punycode.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for content script</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
+  <script type="text/javascript" src="head.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<script type="text/javascript">
+"use strict";
+
+add_task(async function test_punycode() {
+  function background() {
+    browser.webRequest.onBeforeRequest.addListener(details => {
+      browser.test.sendMessage("request-url", details.url);
+    }, {urls: ["http://xn--lt-fg4n.example.com/"]}, ["blocking"]);
+  }
+
+  let extensionData = {
+    manifest: {
+      permissions: ["webRequest", "webRequestBlocking", "<all_urls>"],
+    },
+    background,
+  };
+
+  let extension = ExtensionTestUtils.loadExtension(extensionData);
+  await extension.startup();
+
+  let iframe = document.createElement("iframe");
+  iframe.setAttribute("src", "http://Šlt.example.com/");
+  document.body.appendChild(iframe);
+  let url = await extension.awaitMessage("request-url");
+  is("http://xn--lt-fg4n.example.com/", url, "punycode url received");
+
+  await extension.unload();
+  document.body.removeChild(iframe);
+});
+</script>
+
+</body>
+</html>
--- a/toolkit/modules/addons/WebNavigationContent.js
+++ b/toolkit/modules/addons/WebNavigationContent.js
@@ -199,33 +199,33 @@ var WebProgressListener = {
       // where we can detect the "server redirect" transition.
       // (see Bug 1264936 and Bug 125662 for rationale)
       this.sendDocumentChange({webProgress, locationURI, request});
     }
   },
 
   sendStateChange({webProgress, locationURI, stateFlags, status}) {
     let data = {
-      requestURL: locationURI.spec,
+      requestURL: locationURI.asciiSpec,
       frameId: WebNavigationFrames.getFrameId(webProgress.DOMWindow),
       parentFrameId: WebNavigationFrames.getParentFrameId(webProgress.DOMWindow),
       status,
       stateFlags,
     };
 
     sendAsyncMessage("Extension:StateChange", data);
   },
 
   sendDocumentChange({webProgress, locationURI, request}) {
     let {loadType, DOMWindow} = webProgress;
     let frameTransitionData = this.getFrameTransitionData({loadType, request, DOMWindow});
 
     let data = {
       frameTransitionData,
-      location: locationURI ? locationURI.spec : "",
+      location: locationURI ? locationURI.asciiSpec : "",
       frameId: WebNavigationFrames.getFrameId(webProgress.DOMWindow),
       parentFrameId: WebNavigationFrames.getParentFrameId(webProgress.DOMWindow),
     };
 
     sendAsyncMessage("Extension:DocumentChange", data);
   },
 
   sendHistoryChange({webProgress, previousURI, locationURI, request}) {
@@ -253,17 +253,17 @@ var WebProgressListener = {
     }
 
     if (isHistoryStateUpdated || isReferenceFragmentUpdated) {
       let frameTransitionData = this.getFrameTransitionData({loadType, request, DOMWindow});
 
       let data = {
         frameTransitionData,
         isHistoryStateUpdated, isReferenceFragmentUpdated,
-        location: locationURI ? locationURI.spec : "",
+        location: locationURI ? locationURI.asciiSpec : "",
         frameId: WebNavigationFrames.getFrameId(webProgress.DOMWindow),
         parentFrameId: WebNavigationFrames.getParentFrameId(webProgress.DOMWindow),
       };
 
       sendAsyncMessage("Extension:HistoryChange", data);
     }
   },
 
--- a/toolkit/modules/addons/WebRequest.jsm
+++ b/toolkit/modules/addons/WebRequest.jsm
@@ -750,17 +750,17 @@ HttpObserverManager = {
     }
   },
 
   getRequestData(channel, loadContext, policyType, extraData) {
     let {loadInfo} = channel;
 
     let data = {
       requestId: RequestId.get(channel),
-      url: channel.URI.spec,
+      url: channel.URI.asciiSpec,
       method: channel.requestMethod,
       browser: loadContext && loadContext.topFrameElement,
       type: WebRequestCommon.typeForPolicyType(policyType),
       fromCache: getData(channel).fromCache,
       // Defaults for a top level request
       windowId: 0,
       parentWindowId: -1,
     };
@@ -768,21 +768,21 @@ HttpObserverManager = {
     // force the protocol to be ws again.
     if (data.type == "websocket" && data.url.startsWith("http")) {
       data.url = `ws${data.url.substring(4)}`;
     }
 
     if (loadInfo) {
       let originPrincipal = loadInfo.triggeringPrincipal;
       if (originPrincipal.URI) {
-        data.originUrl = originPrincipal.URI.spec;
+        data.originUrl = originPrincipal.URI.asciiSpec;
       }
       let docPrincipal = loadInfo.loadingPrincipal;
       if (docPrincipal && docPrincipal.URI) {
-        data.documentUrl = docPrincipal.URI.spec;
+        data.documentUrl = docPrincipal.URI.asciiSpec;
       }
 
       // If there is no loadingPrincipal, check that the request is not going to
       // inherit a system principal.  triggeringPrincipal is the context that
       // initiated the load, but is not necessarily the principal that the
       // request results in, only rely on that if no other principal is available.
       let {isSystemPrincipal} = Services.scriptSecurityManager;
       let isTopLevel = !loadInfo.loadingPrincipal && !!data.browser;
@@ -1051,17 +1051,17 @@ HttpObserverManager = {
     if (!channelData.hasAuthRequestor && this.shouldHookListener(this.listeners.authRequired, channel)) {
       channel.notificationCallbacks = new AuthRequestor(channel, this);
       channelData.hasAuthRequestor = true;
     }
   },
 
   onChannelReplaced(oldChannel, newChannel) {
     this.runChannelListener(oldChannel, this.getLoadContext(oldChannel),
-                            "onRedirect", {redirectUrl: newChannel.URI.spec});
+                            "onRedirect", {redirectUrl: newChannel.URI.asciiSpec});
   },
 
   onStartRequest(channel, loadContext) {
     this.runChannelListener(channel, loadContext, "onStart");
   },
 
   onStopRequest(channel, loadContext) {
     this.runChannelListener(channel, loadContext, "onStop");
--- a/toolkit/modules/addons/WebRequestContent.js
+++ b/toolkit/modules/addons/WebRequestContent.js
@@ -91,17 +91,17 @@ var ContentPolicy = {
         return Ci.nsIContentPolicy.ACCEPT;
       }
     }
 
     if (requestPrincipal &&
         Services.scriptSecurityManager.isSystemPrincipal(requestPrincipal)) {
       return Ci.nsIContentPolicy.ACCEPT;
     }
-    let url = contentLocation.spec;
+    let url = contentLocation.asciiSpec;
     if (IS_HTTP.test(url)) {
       // We'll handle this in our parent process HTTP observer.
       return Ci.nsIContentPolicy.ACCEPT;
     }
 
     let block = false;
     let ids = [];
     for (let [id, {blocking, filter}] of this.contentPolicies.entries()) {
@@ -170,17 +170,17 @@ var ContentPolicy = {
     }
 
     let data = {ids,
                 url,
                 type: WebRequestCommon.typeForPolicyType(policyType),
                 windowId,
                 parentWindowId};
     if (requestOrigin) {
-      data.originUrl = requestOrigin.spec;
+      data.originUrl = requestOrigin.asciiSpec;
     }
     if (block) {
       let rval = mm.sendSyncMessage("WebRequest:ShouldLoad", data);
       if (rval.length == 1 && rval[0].cancel) {
         return Ci.nsIContentPolicy.REJECT;
       }
     } else {
       mm.sendAsyncMessage("WebRequest:ShouldLoad", data);