Bug 411930 - Crash reporter sends wrong URL when crashing during pageload (r=zpao)
authorDietrich Ayala <dietrich@mozilla.com>
Wed, 28 Oct 2009 11:30:33 -0700
changeset 34256 8a86b4dbd991046315dd55621335924e9fa7d081
parent 34255 1225e71411ad70136bb2c6fa9b2b2beddcda3525
child 34257 d0b7ef28c23a54acf61e723f24dbaaf9cd8631a5
push idunknown
push userunknown
push dateunknown
reviewerszpao
bugs411930
milestone1.9.3a1pre
Bug 411930 - Crash reporter sends wrong URL when crashing during pageload (r=zpao)
browser/components/sessionstore/src/nsSessionStore.js
--- a/browser/components/sessionstore/src/nsSessionStore.js
+++ b/browser/components/sessionstore/src/nsSessionStore.js
@@ -118,16 +118,52 @@ function debug(aMsg) {
 }
 
 __defineGetter__("NetUtil", function() {
   delete this.NetUtil;
   Cu.import("resource://gre/modules/NetUtil.jsm");
   return NetUtil;
 });
 
+// Private Browsing Service
+XPCOMUtils.defineLazyServiceGetter(
+  this, "PBSvc", "@mozilla.org/privatebrowsing;1",
+  "nsIPrivateBrowsingService");
+
+// Directory Service
+XPCOMUtils.defineLazyServiceGetter(
+  this, "DirSvc", "@mozilla.org/file/directory_service;1", "nsIProperties");
+
+// Script Security Manager
+XPCOMUtils.defineLazyServiceGetter(
+  this, "SecSvc", "@mozilla.org/scriptsecuritymanager;1",
+  "Ci.nsIScriptSecurityManager");
+
+// Cookie Manager
+XPCOMUtils.defineLazyServiceGetter(
+  this, "CookieSvc", "@mozilla.org/cookiemanager;1", "nsICookieManager2");
+
+// IO Service
+XPCOMUtils.defineLazyServiceGetter(
+  this, "IOSvc", "@mozilla.org/network/io-service;1", "nsIIOService");
+
+// Window Mediator
+XPCOMUtils.defineLazyServiceGetter(
+  this, "WinMediator", "@mozilla.org/appshell/window-mediator;1",
+  "nsIWindowMediator");
+
+// Window Watcher 
+XPCOMUtils.defineLazyServiceGetter(
+  this, "WinWatcher", "@mozilla.org/embedcomp/window-watcher;1",
+  "nsIWindowWatcher");
+
+// Crash Reporter
+XPCOMUtils.defineLazyServiceGetter(
+  this, "CrashReporter", "@mozilla.org/xre/app-info;1", "nsICrashReporter");
+
 /* :::::::: The Service ::::::::::::::: */
 
 function SessionStoreService() {
 }
 
 SessionStoreService.prototype = {
   classDescription: "Browser Session Store Service",
   contractID: "@mozilla.org/browser/sessionstore;1",
@@ -177,16 +213,17 @@ SessionStoreService.prototype = {
   // whether we clearing history on shutdown
   _clearingOnShutdown: false,
 
 #ifndef XP_MACOSX
   // whether the last window was closed and should be restored
   _restoreLastWindow: false,
 #endif
 
+
 /* ........ Global Event Handlers .............. */
 
   /**
    * Initialize the component
    */
   init: function sss_init(aWindow) {
     if (!aWindow || this._loadState == STATE_RUNNING) {
       // make sure that all browser windows which try to initialize
@@ -202,19 +239,17 @@ SessionStoreService.prototype = {
 
     this._observerService = Cc["@mozilla.org/observer-service;1"].
                             getService(Ci.nsIObserverService);
 
     OBSERVING.forEach(function(aTopic) {
       this._observerService.addObserver(this, aTopic, true);
     }, this);
 
-    var pbs = Cc["@mozilla.org/privatebrowsing;1"].
-              getService(Ci.nsIPrivateBrowsingService);
-    this._inPrivateBrowsing = pbs.privateBrowsingEnabled;
+    this._inPrivateBrowsing = PBSvc.privateBrowsingEnabled;
 
     // get interval from prefs - used often, so caching/observing instead of fetching on-demand
     this._interval = this._prefBranch.getIntPref("sessionstore.interval");
     this._prefBranch.addObserver("sessionstore.interval", this, true);
     
     // get crash recovery state from prefs and allow for proper reaction to state changes
     this._resume_from_crash = this._prefBranch.getBoolPref("sessionstore.resume_from_crash");
     this._prefBranch.addObserver("sessionstore.resume_from_crash", this, true);
@@ -223,19 +258,17 @@ SessionStoreService.prototype = {
     this._prefBranch.addObserver("sessionstore.max_tabs_undo", this, true);
     this._prefBranch.addObserver("sessionstore.max_windows_undo", this, true);
     
     // this pref is only read at startup, so no need to observe it
     this._sessionhistory_max_entries =
       this._prefBranch.getIntPref("sessionhistory.max_entries");
 
     // get file references
-    var dirService = Cc["@mozilla.org/file/directory_service;1"].
-                     getService(Ci.nsIProperties);
-    this._sessionFile = dirService.get("ProfD", Ci.nsILocalFile);
+    this._sessionFile = DirSvc.get("ProfD", Ci.nsILocalFile);
     this._sessionFileBackup = this._sessionFile.clone();
     this._sessionFile.append("sessionstore.js");
     this._sessionFileBackup.append("sessionstore.bak");
 
     // get string containing session state
     var iniString;
     try {
       var ss = Cc["@mozilla.org/browser/sessionstartup;1"].
@@ -736,16 +769,18 @@ SessionStoreService.prototype = {
     aBrowser.addEventListener("change", this, true);
     aBrowser.addEventListener("input", this, true);
     aBrowser.addEventListener("DOMAutoComplete", this, true);
     aBrowser.addEventListener("scroll", this, true);
     
     if (!aNoNotification) {
       this.saveStateDelayed(aWindow);
     }
+
+    this._updateCrashReportURL(aWindow);
   },
 
   /**
    * remove listeners for a tab
    * @param aWindow
    *        Window reference
    * @param aBrowser
    *        Browser reference
@@ -1356,19 +1391,17 @@ SessionStoreService.prototype = {
           domain = uri.prePath;
       }
       catch (ex) { /* this throws for host-less URIs (such as about: or jar:) */ }
       if (storageData[domain] || !(aFullData || this._checkPrivacyLevel(uri.schemeIs("https"))))
         continue;
 
       let storage, storageItemCount = 0;
       try {
-        var principal = Cc["@mozilla.org/scriptsecuritymanager;1"].
-                        getService(Ci.nsIScriptSecurityManager).
-                        getCodebasePrincipal(uri);
+        var principal = SecSvc.getCodebasePrincipal(uri);
 
         // Using getSessionStorageForPrincipal instead of getSessionStorageForURI
         // just to be able to pass aCreate = false, that avoids creation of the
         // sessionStorage object for the page earlier than the page really
         // requires it. It was causing problems while accessing a storage when
         // a page later changed its domain.
         storage = aDocShell.getSessionStorageForPrincipal(principal, false);
         if (storage)
@@ -1608,28 +1641,27 @@ SessionStoreService.prototype = {
       // aHost, aPath, and aName as keys
       if (!aHash[aHost])
         aHash[aHost] = {};
       if (!aHash[aHost][aPath])
         aHash[aHost][aPath] = {};
       aHash[aHost][aPath][aName] = aCookie;
     }
 
-    var cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
     // collect the cookies per window
     for (var i = 0; i < aWindows.length; i++)
       aWindows[i].cookies = [];
 
     var jscookies = {};
     var _this = this;
     // MAX_EXPIRY should be 2^63-1, but JavaScript can't handle that precision
     var MAX_EXPIRY = Math.pow(2, 62);
     aWindows.forEach(function(aWindow) {
       for (var host in aWindow._hosts) {
-        var list = cm.getCookiesFromHost(host);
+        var list = CookieSvc.getCookiesFromHost(host);
         while (list.hasMoreElements()) {
           var cookie = list.getNext().QueryInterface(Ci.nsICookie2);
           if (cookie.isSession && _this._checkPrivacyLevel(cookie.isSecure)) {
             // use the cookie's host, path, and name as keys into a hash,
             // to make sure we serialize each cookie only once
             if (!(cookie.host in jscookies &&
                   cookie.path in jscookies[cookie.host] &&
                   cookie.name in jscookies[cookie.host][cookie.path])) {
@@ -2120,27 +2152,25 @@ SessionStoreService.prototype = {
    * @param aIdMap
    *        Hash for ensuring unique frame IDs
    * @returns nsISHEntry
    */
   _deserializeHistoryEntry: function sss_deserializeHistoryEntry(aEntry, aIdMap) {
     var shEntry = Cc["@mozilla.org/browser/session-history-entry;1"].
                   createInstance(Ci.nsISHEntry);
     
-    var ioService = Cc["@mozilla.org/network/io-service;1"].
-                    getService(Ci.nsIIOService);
-    shEntry.setURI(ioService.newURI(aEntry.url, null, null));
+    shEntry.setURI(IOSvc.newURI(aEntry.url, null, null));
     shEntry.setTitle(aEntry.title || aEntry.url);
     if (aEntry.subframe)
       shEntry.setIsSubFrame(aEntry.subframe || false);
     shEntry.loadType = Ci.nsIDocShellLoadInfo.loadHistory;
     if (aEntry.contentType)
       shEntry.contentType = aEntry.contentType;
     if (aEntry.referrer) 
-      shEntry.referrerURI = ioService.newURI(aEntry.referrer, null, null);
+      shEntry.referrerURI = IOSvc.newURI(aEntry.referrer, null, null);
     
     if (aEntry.cacheKey) {
       var cacheKey = Cc["@mozilla.org/supports-PRUint32;1"].
                      createInstance(Ci.nsISupportsPRUint32);
       cacheKey.data = aEntry.cacheKey;
       shEntry.cacheKey = cacheKey;
     }
 
@@ -2183,20 +2213,18 @@ SessionStoreService.prototype = {
       ownerInput.setData(binaryData, binaryData.length);
       var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].
                          createInstance(Ci.nsIObjectInputStream);
       binaryStream.setInputStream(ownerInput);
       try { // Catch possible deserialization exceptions
         shEntry.owner = binaryStream.readObject(true);
       } catch (ex) { debug(ex); }
     } else if (aEntry.ownerURI) { // Firefox 2
-      var uriObj = ioService.newURI(aEntry.ownerURI, null, null);
-      shEntry.owner = Cc["@mozilla.org/scriptsecuritymanager;1"].
-                      getService(Ci.nsIScriptSecurityManager).
-                      getCodebasePrincipal(uriObj);
+      var uriObj = IOSvc.newURI(aEntry.ownerURI, null, null);
+      shEntry.owner = SecSvc.getCodebasePrincipal(uriObj);
     }
     
     if (aEntry.children && shEntry instanceof Ci.nsISHContainer) {
       for (var i = 0; i < aEntry.children.length; i++) {
         //XXXzpao Wallpaper patch for bug 514751
         if (!aEntry.children[i].url)
           continue;
         shEntry.AddChild(this._deserializeHistoryEntry(aEntry.children[i], aIdMap), i);
@@ -2209,19 +2237,18 @@ SessionStoreService.prototype = {
   /**
    * restores all sessionStorage "super cookies"
    * @param aStorageData
    *        Storage data to be restored
    * @param aDocShell
    *        A tab's docshell (containing the sessionStorage)
    */
   _deserializeSessionStorage: function sss_deserializeSessionStorage(aStorageData, aDocShell) {
-    let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
     for (let url in aStorageData) {
-      let uri = ioService.newURI(url, null, null);
+      let uri = IOSvc.newURI(url, null, null);
       let storage = aDocShell.getSessionStorageForURI(uri);
       for (let key in aStorageData[url]) {
         try {
           storage.setItem(key, aStorageData[url][key]);
         }
         catch (ex) { Cu.reportError(ex); } // throws e.g. for URIs that can't have sessionStorage
       }
     }
@@ -2458,24 +2485,22 @@ SessionStoreService.prototype = {
           converted.push({
             host: RegExp.$1, path: parsed[3], name: parsed[1], value: parsed[2],
             secure: parsed[4], httponly: parsed[5]
           });
       }
       aCookies = converted;
     }
     
-    var cookieManager = Cc["@mozilla.org/cookiemanager;1"].
-                        getService(Ci.nsICookieManager2);
     // MAX_EXPIRY should be 2^63-1, but JavaScript can't handle that precision
     var MAX_EXPIRY = Math.pow(2, 62);
     for (i = 0; i < aCookies.length; i++) {
       var cookie = aCookies[i];
       try {
-        cookieManager.add(cookie.host, cookie.path || "", cookie.name || "", cookie.value, !!cookie.secure, !!cookie.httponly, true, "expiry" in cookie ? cookie.expiry : MAX_EXPIRY);
+        CookieSvc.add(cookie.host, cookie.path || "", cookie.name || "", cookie.value, !!cookie.secure, !!cookie.httponly, true, "expiry" in cookie ? cookie.expiry : MAX_EXPIRY);
       }
       catch (ex) { Cu.reportError(ex); } // don't let a single cookie stop recovering
     }
   },
 
 /* ........ Disk Access .............. */
 
   /**
@@ -2574,54 +2599,49 @@ SessionStoreService.prototype = {
 
   /**
    * call a callback for all currently opened browser windows
    * (might miss the most recent one)
    * @param aFunc
    *        Callback each window is passed to
    */
   _forEachBrowserWindow: function sss_forEachBrowserWindow(aFunc) {
-    var windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
-                         getService(Ci.nsIWindowMediator);
-    var windowsEnum = windowMediator.getEnumerator("navigator:browser");
+    var windowsEnum = WinMediator.getEnumerator("navigator:browser");
     
     while (windowsEnum.hasMoreElements()) {
       var window = windowsEnum.getNext();
       if (window.__SSi) {
         aFunc.call(this, window);
       }
     }
   },
 
   /**
    * Returns most recent window
    * @returns Window reference
    */
   _getMostRecentBrowserWindow: function sss_getMostRecentBrowserWindow() {
-    var windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
-                         getService(Ci.nsIWindowMediator);
-    return windowMediator.getMostRecentWindow("navigator:browser");
+    return WinMediator.getMostRecentWindow("navigator:browser");
   },
 
   /**
    * open a new browser window for a given session state
    * called when restoring a multi-window session
    * @param aState
    *        Object containing session data
    */
   _openWindowWithState: function sss_openWindowWithState(aState) {
     var argString = Cc["@mozilla.org/supports-string;1"].
                     createInstance(Ci.nsISupportsString);
     argString.data = "";
 
     //XXXzeniko shouldn't it be possible to set the window's dimensions here (as feature)?
-    var window = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-                 getService(Ci.nsIWindowWatcher).
-                 openWindow(null, this._prefBranch.getCharPref("chromeURL"), "_blank",
-                            "chrome,dialog=no,all", argString);
+    var window = WinWatcher.openWindow(
+        null, this._prefBranch.getCharPref("chromeURL"), "_blank",
+        "chrome,dialog=no,all", argString);
     
     do {
       var ID = "window" + Math.random();
     } while (ID in this._statesToRestore);
     this._statesToRestore[(window.__SS_restoreID = ID)] = aState;
     
     return window;
   },
@@ -2709,19 +2729,17 @@ SessionStoreService.prototype = {
   },
 
   /**
    * Get nsIURI from string
    * @param string
    * @returns nsIURI
    */
   _getURIFromString: function sss_getURIFromString(aString) {
-    var ioService = Cc["@mozilla.org/network/io-service;1"].
-                    getService(Ci.nsIIOService);
-    return ioService.newURI(aString, null, null);
+    return IOSvc.newURI(aString, null, null);
   },
 
   /**
    * Annotate a breakpad crash report with the currently selected tab's URL.
    */
   _updateCrashReportURL: function sss_updateCrashReportURL(aWindow) {
     if (!Ci.nsICrashReporter) {
       // if breakpad isn't built, don't bother next time at all
@@ -2731,18 +2749,17 @@ SessionStoreService.prototype = {
     try {
       var currentURI = aWindow.gBrowser.currentURI.clone();
       // if the current URI contains a username/password, remove it
       try { 
         currentURI.userPass = ""; 
       } 
       catch (ex) { } // ignore failures on about: URIs
 
-      var cr = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsICrashReporter);
-      cr.annotateCrashReport("URL", currentURI.spec);
+      CrashReporter.annotateCrashReport("URL", currentURI.spec);
     }
     catch (ex) {
       // don't make noise when crashreporter is built but not enabled
       if (ex.result != Components.results.NS_ERROR_NOT_INITIALIZED)
         debug(ex);
     }
   },