browser/components/sessionstore/src/SessionStorage.jsm

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 "use strict";
     7 this.EXPORTED_SYMBOLS = ["SessionStorage"];
     9 const Cu = Components.utils;
    10 const Ci = Components.interfaces;
    12 Cu.import("resource://gre/modules/Services.jsm");
    13 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
    15 XPCOMUtils.defineLazyModuleGetter(this, "console",
    16   "resource://gre/modules/devtools/Console.jsm");
    18 // Returns the principal for a given |frame| contained in a given |docShell|.
    19 function getPrincipalForFrame(docShell, frame) {
    20   let ssm = Services.scriptSecurityManager;
    21   let uri = frame.document.documentURIObject;
    22   return ssm.getDocShellCodebasePrincipal(uri, docShell);
    23 }
    25 this.SessionStorage = Object.freeze({
    26   /**
    27    * Updates all sessionStorage "super cookies"
    28    * @param docShell
    29    *        That tab's docshell (containing the sessionStorage)
    30    * @param frameTree
    31    *        The docShell's FrameTree instance.
    32    * @return Returns a nested object that will have hosts as keys and per-host
    33    *         session storage data as values. For example:
    34    *         {"example.com": {"key": "value", "my_number": 123}}
    35    */
    36   collect: function (docShell, frameTree) {
    37     return SessionStorageInternal.collect(docShell, frameTree);
    38   },
    40   /**
    41    * Restores all sessionStorage "super cookies".
    42    * @param aDocShell
    43    *        A tab's docshell (containing the sessionStorage)
    44    * @param aStorageData
    45    *        A nested object with storage data to be restored that has hosts as
    46    *        keys and per-host session storage data as values. For example:
    47    *        {"example.com": {"key": "value", "my_number": 123}}
    48    */
    49   restore: function (aDocShell, aStorageData) {
    50     SessionStorageInternal.restore(aDocShell, aStorageData);
    51   }
    52 });
    54 let SessionStorageInternal = {
    55   /**
    56    * Reads all session storage data from the given docShell.
    57    * @param docShell
    58    *        A tab's docshell (containing the sessionStorage)
    59    * @param frameTree
    60    *        The docShell's FrameTree instance.
    61    * @return Returns a nested object that will have hosts as keys and per-host
    62    *         session storage data as values. For example:
    63    *         {"example.com": {"key": "value", "my_number": 123}}
    64    */
    65   collect: function (docShell, frameTree) {
    66     let data = {};
    67     let visitedOrigins = new Set();
    69     frameTree.forEach(frame => {
    70       let principal = getPrincipalForFrame(docShell, frame);
    71       if (!principal) {
    72         return;
    73       }
    75       // Get the root domain of the current history entry
    76       // and use that as a key for the per-host storage data.
    77       let origin = principal.jarPrefix + principal.origin;
    78       if (visitedOrigins.has(origin)) {
    79         // Don't read a host twice.
    80         return;
    81       }
    83       // Mark the current origin as visited.
    84       visitedOrigins.add(origin);
    86       let originData = this._readEntry(principal, docShell);
    87       if (Object.keys(originData).length) {
    88         data[origin] = originData;
    89       }
    90     });
    92     return Object.keys(data).length ? data : null;
    93   },
    95   /**
    96    * Writes session storage data to the given tab.
    97    * @param aDocShell
    98    *        A tab's docshell (containing the sessionStorage)
    99    * @param aStorageData
   100    *        A nested object with storage data to be restored that has hosts as
   101    *        keys and per-host session storage data as values. For example:
   102    *        {"example.com": {"key": "value", "my_number": 123}}
   103    */
   104   restore: function (aDocShell, aStorageData) {
   105     for (let host of Object.keys(aStorageData)) {
   106       let data = aStorageData[host];
   107       let uri = Services.io.newURI(host, null, null);
   108       let principal = Services.scriptSecurityManager.getDocShellCodebasePrincipal(uri, aDocShell);
   109       let storageManager = aDocShell.QueryInterface(Ci.nsIDOMStorageManager);
   111       // There is no need to pass documentURI, it's only used to fill documentURI property of
   112       // domstorage event, which in this case has no consumer. Prevention of events in case
   113       // of missing documentURI will be solved in a followup bug to bug 600307.
   114       // TODO: We should call createStorageForFirstParty() here.  See comment
   115       //       inside _readEntry() for details.
   116       let storage = storageManager.createStorage(principal, "", aDocShell.usePrivateBrowsing);
   118       for (let key of Object.keys(data)) {
   119         try {
   120           storage.setItem(key, data[key]);
   121         } catch (e) {
   122           // throws e.g. for URIs that can't have sessionStorage
   123           console.error(e);
   124         }
   125       }
   126     }
   127   },
   129   /**
   130    * Reads an entry in the session storage data contained in a tab's history.
   131    * @param aURI
   132    *        That history entry uri
   133    * @param aDocShell
   134    *        A tab's docshell (containing the sessionStorage)
   135    */
   136   _readEntry: function (aPrincipal, aDocShell) {
   137     let hostData = {};
   138     let storage;
   140     try {
   141       let storageManager = aDocShell.QueryInterface(Ci.nsIDOMStorageManager);
   142       // TODO: We should call getStorageForFirstParty() here, but we need an
   143       //       nsIDocument to call thirdPartyUtil.getFirstPartyURI(), and
   144       //       unfortunately nsIDocument is not exposed to JavaScript.
   145       //       However, this code is not called in TBB because the
   146       //       browser.sessionstore.privacy_level pref. is set to 2.
   147       storage = storageManager.getStorage(aPrincipal);
   148     } catch (e) {
   149       // sessionStorage might throw if it's turned off, see bug 458954
   150     }
   152     if (storage && storage.length) {
   153        for (let i = 0; i < storage.length; i++) {
   154         try {
   155           let key = storage.key(i);
   156           hostData[key] = storage.getItem(key);
   157         } catch (e) {
   158           // This currently throws for secured items (cf. bug 442048).
   159         }
   160       }
   161     }
   163     return hostData;
   164   }
   165 };

mercurial