diff --git a/netwerk/base/src/nsProxyAutoConfig.js b/netwerk/base/src/nsProxyAutoConfig.js index 6a340440925c..c7c8d68e3aa1 100644 --- a/netwerk/base/src/nsProxyAutoConfig.js +++ b/netwerk/base/src/nsProxyAutoConfig.js @@ -52,6 +52,22 @@ const nsISupports = Components.interfaces.nsISupports; const nsIProxyAutoConfig = Components.interfaces.nsIProxyAutoConfig; const nsIDNSService = Components.interfaces.nsIDNSService; +// Loaded once per PAC script, this is a safe way for the supplied functions +// that require chrome privileges to turn a random untrusted object into a +// string. +var safeToString = null; +function myToString(thisp) { + return thisp + ''; +} + +// This is like safeToString, except that it calls a given function with a +// given this and arguments. +var callFunction = null; +function myCall(fun, thisp) { + var args = Array.prototype.slice.call(arguments, 2); + return fun.apply(thisp, args); +} + // implementor of nsIProxyAutoConfig function nsProxyAutoConfig() {}; @@ -81,6 +97,13 @@ nsProxyAutoConfig.prototype = { this._sandBox = new Components.utils.Sandbox(pacURI); Components.utils.evalInSandbox(pacUtils, this._sandBox); + safeToString = + Components.utils.evalInSandbox("(" + myToString.toSource() + ")", + this._sandBox); + callFunction = + Components.utils.evalInSandbox("(" + myCall.toSource() + ")", + this._sandBox); + // add predefined functions to pac this._sandBox.importFunction(myIpAddress); this._sandBox.importFunction(dnsResolve); @@ -96,11 +119,15 @@ nsProxyAutoConfig.prototype = { return null; // Call the original function - return this._findProxyForURL.call(this._sandBox, testURI, testHost); + return callFunction(this._findProxyForURL, this._sandBox, + testURI, testHost); } } function proxyAlert(msg) { + // Ensure that we have a string. + msg = safeToString(msg); + try { // It would appear that the console service is threadsafe. var cns = Components.classes["@mozilla.org/consoleservice;1"] @@ -122,6 +149,8 @@ function myIpAddress() { // wrapper for resolving hostnames called by PAC file function dnsResolve(host) { + host = safeToString(host); + try { return dns.resolve(host, 0).getNextAddrAsString(); } catch (e) {