Bug 1167922 - Handle broken entries in media.peerconnection.default_iceservers more gracefully. r=jib
authorRithesh Shenthar <rshenthar@mozilla.com>
Tue, 23 Jun 2015 16:52:50 -0700
changeset 281037 64cb3eddd1a973d09ef4f7f6c7e0b5b2a535151f
parent 281036 d253bc334796439127e98c6505451e7b70aafc8f
child 281038 7050f4f4197f2029ec03cf9e7575bcb34042c010
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjib
bugs1167922
milestone41.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 1167922 - Handle broken entries in media.peerconnection.default_iceservers more gracefully. r=jib
dom/media/PeerConnection.js
dom/media/tests/mochitest/test_peerConnection_bug825703.html
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -318,35 +318,40 @@ RTCPeerConnection.prototype = {
   contractID: PC_CONTRACT,
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
                                          Ci.nsIDOMGlobalPropertyInitializer]),
   init: function(win) { this._win = win; },
 
   __init: function(rtcConfig) {
     this._winID = this._win.QueryInterface(Ci.nsIInterfaceRequestor)
     .getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID;
-
     if (!rtcConfig.iceServers ||
         !Services.prefs.getBoolPref("media.peerconnection.use_document_iceservers")) {
-      rtcConfig.iceServers =
-        JSON.parse(Services.prefs.getCharPref("media.peerconnection.default_iceservers"));
+      try {
+         rtcConfig.iceServers =
+           JSON.parse(Services.prefs.getCharPref("media.peerconnection.default_iceservers") || "[]");
+      } catch (e) {
+        this.logWarning(
+            "Ignoring invalid media.peerconnection.default_iceservers in about:config",
+             null, 0);
+        rtcConfig.iceServers = [];
+      }
+      try {
+        this._mustValidateRTCConfiguration(rtcConfig,
+            "Ignoring invalid media.peerconnection.default_iceservers in about:config");
+      } catch (e) {
+        this.logWarning(e.message, null, 0);
+        rtcConfig.iceServers = [];
+      }
+    } else {
+      // This gets executed in the typical case when iceServers
+      // are passed in through the web page.
+      this._mustValidateRTCConfiguration(rtcConfig,
+        "RTCPeerConnection constructor passed invalid RTCConfiguration");
     }
-    // Normalize iceServers input
-    rtcConfig.iceServers.forEach(server => {
-      if (typeof server.urls === "string") {
-        server.urls = [server.urls];
-      } else if (!server.urls && server.url) {
-        // TODO: Remove support for legacy iceServer.url eventually (Bug 1116766)
-        server.urls = [server.url];
-        this.logWarning("RTCIceServer.url is deprecated! Use urls instead.", null, 0);
-      }
-    });
-    this._mustValidateRTCConfiguration(rtcConfig,
-        "RTCPeerConnection constructor passed invalid RTCConfiguration");
-
     // Save the appId
     this._appId = Cu.getWebIDLCallerPrincipal().appId;
 
     // Get the offline status for this appId
     let appOffline = false;
     if (this._appId != Ci.nsIScriptSecurityManager.NO_APP_ID &&
         this._appId != Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID) {
       let ios = Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService);
@@ -458,22 +463,33 @@ RTCPeerConnection.prototype = {
   /**
    * An RTCConfiguration may look like this:
    *
    * { "iceServers": [ { urls: "stun:stun.example.org", },
    *                   { url: "stun:stun.example.org", }, // deprecated version
    *                   { urls: ["turn:turn1.x.org", "turn:turn2.x.org"],
    *                     username:"jib", credential:"mypass"} ] }
    *
-   * WebIDL normalizes structure for us, so we test well-formed stun/turn urls,
-   * but not validity of servers themselves, before passing along to C++.
-   *
+   * This function normalizes the structure of the input for rtcConfig.iceServers for us,
+   * so we test well-formed stun/turn urls before passing along to C++.
    *   msg - Error message to detail which array-entry failed, if any.
    */
   _mustValidateRTCConfiguration: function(rtcConfig, msg) {
+
+    // Normalize iceServers input
+    rtcConfig.iceServers.forEach(server => {
+      if (typeof server.urls === "string") {
+        server.urls = [server.urls];
+      } else if (!server.urls && server.url) {
+        // TODO: Remove support for legacy iceServer.url eventually (Bug 1116766)
+        server.urls = [server.url];
+        this.logWarning("RTCIceServer.url is deprecated! Use urls instead.", null, 0);
+      }
+    });
+
     let ios = Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService);
 
     let nicerNewURI = uriStr => {
       try {
         return ios.newURI(uriStr, null, null);
       } catch (e if (e.result == Cr.NS_ERROR_MALFORMED_URI)) {
         throw new this._win.DOMException(msg + " - malformed URI: " + uriStr,
                                          "SyntaxError");
--- a/dom/media/tests/mochitest/test_peerConnection_bug825703.html
+++ b/dom/media/tests/mochitest/test_peerConnection_bug825703.html
@@ -67,14 +67,28 @@ runNetworkTest(() => {
 
   try {
     new mozRTCPeerConnection({ iceServers: [{ url:"http:0.0.0.0" }] }).close();
   } catch (e) {
     ok(e.message.indexOf("http") > 0,
        "mozRTCPeerConnection() constructor has readable exceptions");
   }
 
-  networkTestFinished();
+  // Below tests are setting the about:config User preferences for default
+  // ice servers and checking the outputs when mozRTCPeerConnection() is
+  // invoked. See Bug 1167922 for more information.
+  // Note - We use promises here since the SpecialPowers API will be
+  // performed asynchronously.
+  var push = prefs => new Promise(resolve =>
+      SpecialPowers.pushPrefEnv(prefs, resolve));
+
+  push({ set: [['media.peerconnection.default_iceservers', ""]] })
+      .then(() => makePC())
+      .then(() => push({ set: [['media.peerconnection.default_iceservers', "k"]] }))
+      .then(() => makePC())
+      .then(() => push({ set: [['media.peerconnection.default_iceservers', "[{\"urls\": [\"stun:stun.services.mozilla.com\"]}]"]] }))
+      .then(() => makePC())
+      .then(networkTestFinished);
 });
 </script>
 </pre>
 </body>
 </html>