[or-cvs] r11723: Rework hooking code to be based off of the toplevel content (in torbutton/trunk/src: . chrome/content components)

mikeperry at seul.org mikeperry at seul.org
Mon Oct 1 01:53:07 UTC 2007


Author: mikeperry
Date: 2007-09-30 21:53:07 -0400 (Sun, 30 Sep 2007)
New Revision: 11723

Added:
   torbutton/trunk/src/components/window-mapper.js
Modified:
   torbutton/trunk/src/CHANGELOG
   torbutton/trunk/src/chrome/content/torbutton.js
   torbutton/trunk/src/components/cssblocker.js
Log:

Rework hooking code to be based off of the toplevel content
window only (ignore the document and subwindows). Also,
implement a component that translates content windows into
browsers. O(tabs) search. Caching will probably be needed.
Modify css content policy and hooking code to use it.



Modified: torbutton/trunk/src/CHANGELOG
===================================================================
--- torbutton/trunk/src/CHANGELOG	2007-09-30 22:00:50 UTC (rev 11722)
+++ torbutton/trunk/src/CHANGELOG	2007-10-01 01:53:07 UTC (rev 11723)
@@ -1,8 +1,10 @@
 1.1.8
-  XX Sep 2007
+  XX Oct 2007
   * bugfix: bug 503: prevent sessionstore from writing Tor tabs to disk
   * bugfix: bug 510: decouple cookie clearing from Clear Private Data settings
   * bugfix: bug 474: decouple password+form saving from history writing
+  * bugfix: bug 460: rework handling of hooking based on global events+window
+    lookup
   * bugfix: cookies are now properly synced before storing into a jar
   * misc: tightened up the alerts a bit more for the javascript hooking
   * misc: changed defaults to be less intrusive to non-tor usage

Modified: torbutton/trunk/src/chrome/content/torbutton.js
===================================================================
--- torbutton/trunk/src/chrome/content/torbutton.js	2007-09-30 22:00:50 UTC (rev 11722)
+++ torbutton/trunk/src/chrome/content/torbutton.js	2007-10-01 01:53:07 UTC (rev 11723)
@@ -1013,32 +1013,25 @@
     return (typeof(obj[flag]) != 'undefined');
 }
 
-function torbutton_check_load_state(doc, tor_tag) {
-    var browser = getBrowser();
+function torbutton_hookdoc(win, doc) {
+    if (!m_tb_wasinited) {
+        torbutton_init();
+    }
 
-    // Find proper browser for this document.. ugh.
-    for (var i = 0; i < browser.browsers.length; ++i) {
-        var b = browser.browsers[i];
-        if (b && b.contentDocument == doc) {
-            torbutton_log(1, "Tab states "+tor_tag+" == "+
-                    b.__tb_js_state + " -> " + 
-                    (b.__tb_js_state == tor_tag)); 
-            return b.__tb_js_state == tor_tag;
-        }
+    if(win != win.top) {
+        torbutton_log(3, "Hook for non-toplevel window: "+doc.location);
+        win = win.top;
     }
-}
 
-function torbutton_hookdoc(win, doc) {
-    torbutton_log(1, "Hooking document: "+doc.location);
+    if(typeof(win.wrappedJSObject) == 'undefined') {
+        torbutton_log(3, "No JSObject: "+doc.location);
+        return;
+    }
+
+    torbutton_log(2, "Hooking document: "+doc.location);
     if(doc.doctype) {
         torbutton_log(2, "Hooking document: "+doc.doctype.name);
     }
-    if (!m_tb_wasinited) {
-        torbutton_init();
-    }
-
-    var tor_tag = !m_tb_prefs.getBoolPref("extensions.torbutton.tor_enabled");
-    var js_enabled = m_tb_prefs.getBoolPref("javascript.enabled");
    
     // We can't just tag the document here because it is possible
     // to hit reload at just the right point such that the document
@@ -1047,11 +1040,17 @@
         torbutton_log(2, "Already did hook " 
                 + torbutton_check_flag(win, "__tb_did_hook"));
         /* XXX: Remove this once bug #460 is resolved */
+        var wm = Components.classes["@torproject.org/content-window-mapper;1"]
+            .getService(Components.interfaces.nsISupports)
+            .wrappedJSObject;
+        var browser = wm.getBrowserForContentWindow(win);
+        if(!browser) win.alert("No window found!");
+
         /* hrmm.. would doc.isSupported("javascript") 
          * or doc.implementation.hasFeature() work better? */
         if(doc.contentType.indexOf("text/html") != -1 && 
-                torbutton_check_load_state(doc, false) && 
-                !torbutton_check_flag(win.window.wrappedJSObject, 
+                browser.__tb_js_state == false &&
+                !torbutton_check_flag(win.wrappedJSObject, 
                     "__tb_hooks_ran")) {
             torbutton_log(5, "FALSE WIN HOOKING. Please report bug+website!");
             win.alert("False win hooking. Please report bug+website!");
@@ -1059,40 +1058,28 @@
         return; // Ran already
     }
 
-    // We also can't just tag the window either, because it gets
-    // cleared on back/fwd(!??)
-    if(torbutton_check_flag(doc, "__tb_did_hook")) {
-        /* XXX: Remove this once bug #460 is resolved */
-        torbutton_log(4, "Hrmm.. Partial checked hook: "
-                + torbutton_check_flag(win, "__tb_did_hook"));
-        if(doc.contentType.indexOf("text/html") != -1 && 
-                torbutton_check_load_state(doc, false) && 
-                !torbutton_check_flag(win.window.wrappedJSObject, "__tb_hooks_ran")) {
-            torbutton_log(5, "FALSE DOC HOOKING. Please report bug+website!");
-            win.alert("False doc hooking. Please report bug+website!");
-        } 
-        return; // Ran already
-    }
+    var wm = Components.classes["@torproject.org/content-window-mapper;1"]
+        .getService(Components.interfaces.nsISupports)
+        .wrappedJSObject;
 
-    var browser = getBrowser();
+    var browser = wm.getBrowserForContentWindow(win);
+    if(!browser) win.alert("No window found!");
+    torbutton_log(2, "Got browser "+browser.contentDocument.location+" for: " 
+            + doc.location);
+
+    var tor_tag = !m_tb_prefs.getBoolPref("extensions.torbutton.tor_enabled");
+    var js_enabled = m_tb_prefs.getBoolPref("javascript.enabled");
     var kill_plugins = m_tb_prefs.getBoolPref("extensions.torbutton.no_tor_plugins");
 
-    // TODO: try nsIWindowWatcher.getChromeForWindow()
+    torbutton_log(2, "Tagging browser for: " + doc.location);
+    browser.__tb_js_state = tor_tag;
+    browser.docShell.allowPlugins = tor_tag || !kill_plugins;
+    browser.docShell.allowJavascript = js_enabled;
 
-    // Find proper browser for this document.. ugh.
-    for (var i = 0; i < browser.browsers.length; ++i) {
-        var b = browser.browsers[i];
-        if (b && b.contentDocument == doc) {
-            b.__tb_js_state = tor_tag;
-            b.docShell.allowPlugins = tor_tag || !kill_plugins;
-            b.docShell.allowJavascript = js_enabled;
-        }
-    }
-
     torbutton_log(1, "JS set to: " + js_enabled);
     
     if(!js_enabled) // XXX: bug #460 hack
-        win.window.wrappedJSObject.__tb_hooks_ran = true; 
+        win.wrappedJSObject.__tb_hooks_ran = true; 
 
     // No need to hook js if tor is off
     if(!js_enabled 
@@ -1100,7 +1087,6 @@
             || !m_tb_prefs.getBoolPref('extensions.torbutton.kill_bad_js')) {
         torbutton_log(2, "Finished non-hook of: " + doc.location);
         torbutton_set_flag(win, "__tb_did_hook");
-        torbutton_set_flag(doc, "__tb_did_hook");
         return;
     }
 
@@ -1121,20 +1107,21 @@
     str2 += "window.__tb_productSub=\""+m_tb_prefs.getCharPref('extensions.torbutton.productsub_override')+"\";\r\n";
     str2 += m_tb_jshooks + "}";
 
-    torbutton_log(2, "Document: " + doc.domain);
-
     try {
-        var s = new Components.utils.Sandbox(win.window.wrappedJSObject);
-        s.window = win.window.wrappedJSObject;
+        torbutton_log(2, "Tupe of window: " + typeof(win));
+        torbutton_log(2, "Type of wrapped window: " + typeof(win.wrappedJSObject));
+        var s = new Components.utils.Sandbox(win.wrappedJSObject);
+        s.window = win.wrappedJSObject;
         var result = Components.utils.evalInSandbox(str2, s);
         if(result == 23) { // secret confirmation result code.
             torbutton_set_flag(win, "__tb_did_hook");
-            torbutton_set_flag(doc, "__tb_did_hook");
         } else {
             win.alert("Sandbox evaluation failed. Date hooks not applied!");
+            torbutton_log(4, "Hook evaluation failure at " + doc.location);
         }
     } catch (e) {
-        win.alert("Exception in sandbox evaluation. Date hooks not applied!");
+        win.alert("Exception in sandbox evaluation. Date hooks not applied:\n"+e);
+        torbutton_log(4, "Hook exception at: "+doc.location+", "+e);
     }
 
     torbutton_log(2, "Finished hook: " + doc.location);
@@ -1149,8 +1136,8 @@
         torbutton_log(1, "location progress");
         var doc = aProgress.DOMWindow.document;
         try {
-            if(doc && doc.domain) 
-                torbutton_hookdoc(aProgress.DOMWindow, doc);
+            if(doc && doc.domain)
+                torbutton_hookdoc(aProgress.DOMWindow.window, doc);
             else torbutton_log(2, "No DOM yet at location event");
         } catch(e) {
             torbutton_log(3, "Hit about:plugins? "+doc.location);

Modified: torbutton/trunk/src/components/cssblocker.js
===================================================================
--- torbutton/trunk/src/components/cssblocker.js	2007-09-30 22:00:50 UTC (rev 11722)
+++ torbutton/trunk/src/components/cssblocker.js	2007-10-01 01:53:07 UTC (rev 11723)
@@ -89,6 +89,9 @@
         this._prefs = Components.classes["@mozilla.org/preferences-service;1"]
             .getService(Components.interfaces.nsIPrefBranch);
         this._loglevel = this._prefs.getIntPref("extensions.torbutton.loglevel");
+        this.wm = Components.classes["@torproject.org/content-window-mapper;1"]
+            .getService(Components.interfaces.nsISupports)
+            .wrappedJSObject;
         this.log("init done\n");
         return;
     },
@@ -113,7 +116,6 @@
     // have to continually query prefs
 	// nsIContentPolicy interface implementation
 	shouldLoad: function(contentType, contentLocation, requestOrigin, insecNode, mimeTypeGuess, extra) {
-        this.log("ContentLocation: "+contentLocation.spec+"\n");
        
         /*. Debugging hack. DO NOT UNCOMMENT IN PRODUCTION ENVIRONMENTS
         if(contentLocation.spec.search("venkman") != -1) {
@@ -123,6 +125,7 @@
 
         if(!insecNode) {
             // Happens on startup
+            this.log("Skipping insec: "+contentLocation.spec+"\n");
             return ok;
         }
 
@@ -135,6 +138,7 @@
         var wind = getWindow(wrapNode(insecNode));
 
 		if (this.isLocalScheme(unwrapURL(contentLocation.spec))) {
+            this.log("Skipping local: "+contentLocation.spec+"\n");
 			return ok;
         } 
 
@@ -145,51 +149,39 @@
 		}
 
         if (!wind || !wind.top.location || !wind.top.location.href) {
-            this.log("Location\n");
+            this.log("Skipping no location: "+contentLocation.spec+"\n");
 			return ok;
         }
 
         var doc = wind.top.document;
         if(!doc) {
             // 1st load of a page in a new location
+            this.log("Skipping no doc: "+contentLocation.spec+"\n");
             return ok;
         }
 
-        // TODO: Ugly.. But seems to be no better option..
-        var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
-                     .getService(Components.interfaces.nsIWindowMediator);
-        var mainWindow = wm.getMostRecentWindow("navigator:browser");
-
-        if(!mainWindow) {
-            // 1st window gets this.
-            return ok;
+        var browser = this.wm.getBrowserForContentWindow(wind.top);
+        if(!browser) {
+            // This happens on the first load of a doc
+            // XXX: Other cases?
+            this.log("No window found: "+contentLocation.spec+"\n");
+            return ok; 
         }
 
-        var browser = mainWindow.getBrowser(); 
         var torTag = !this._prefs.getBoolPref("extensions.torbutton.tor_enabled");
-       
-        // Find proper browser for this document.. ugh. this
-        // is gonna be SO fucking slow :(
-        // TODO: try nsIWindowWatcher.getChromeForWindow()
-        for (var i = 0; i < browser.browsers.length; ++i) {
-            var b = browser.browsers[i];
-            if (b && b.contentDocument == doc) {
-                if (typeof(b.__tb_js_state) == 'undefined') {
-                    this.log("UNTAGGED WINDOW2!!!!!!!!!");
-                    return block;
-                }
 
-                if(b.__tb_js_state == torTag) {
-                    return ok;
-                } else {
-                    this.log("block2: "+b.__tb_js_state+"\n");
-                    return block;
-                }
-            }
+        if (typeof(browser.__tb_js_state) == 'undefined') {
+            this.log("UNTAGGED WINDOW2!!!!!!!!! "+contentLocation.spec+"\n");
+            return block;
         }
 
-        // Favicons hit this.. Their document is browser.xml
-        return ok;
+        if(browser.__tb_js_state == torTag)
+            return ok;
+        else {
+            this.log("Blocking: "+contentLocation.spec+"\n");
+            return block;
+        }
+
 	},
 
 	shouldProcess: function(contentType, contentLocation, requestOrigin, insecNode, mimeType, extra) {

Added: torbutton/trunk/src/components/window-mapper.js
===================================================================
--- torbutton/trunk/src/components/window-mapper.js	                        (rev 0)
+++ torbutton/trunk/src/components/window-mapper.js	2007-10-01 01:53:07 UTC (rev 11723)
@@ -0,0 +1,149 @@
+/*************************************************************************
+ * ContentWindowMapper (JavaScript XPCOM component)
+ *
+ * Allows you to find a tabbrowser tab for a top level content window.
+ *
+ * TODO: Implement a local cache+timer expiration so this isn't ass-slow 
+ * with lots of windows open.
+ *
+ *************************************************************************/
+
+// Module specific constants
+const kMODULE_NAME = "Content Window Mapper";
+const kMODULE_CONTRACTID = "@torproject.org/content-window-mapper;1";
+const kMODULE_CID = Components.ID("b985e49c-12cb-4f29-9d14-b62603332ec4");
+
+const Cr = Components.results;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+function ContentWindowMapper() {
+
+    var checkCache = function(topContentWindow) {
+        return null;
+    };
+
+    var addCache = function(topContentWindow, browser) {
+        return null;
+    };
+
+    this.getBrowserForContentWindow = function(topContentWindow) {
+        var cached = checkCache(topContentWindow);
+        if(cached != null) return cached;
+
+        var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+            .getService(Components.interfaces.nsIWindowMediator);
+        var enumerator = wm.getEnumerator("navigator:browser");
+        while(enumerator.hasMoreElements()) {
+            var win = enumerator.getNext();
+            var browser = win.getBrowser(); 
+            for (var i = 0; i < browser.browsers.length; ++i) {
+                var b = browser.browsers[i];
+                if (b && b.contentWindow == topContentWindow) {
+                    addCache(topContentWindow, browser);
+                    return browser;
+                }
+            }
+        }
+
+        dump("No browser found!\n");
+        return null;
+    };
+
+
+  // This JSObject is exported directly to chrome
+  this.wrappedJSObject = this;
+}
+
+/**
+ * JS XPCOM component registration goop:
+ *
+ * Everything below is boring boilerplate and can probably be ignored.
+ */
+
+const nsISupports = Components.interfaces.nsISupports;
+const nsIClassInfo = Components.interfaces.nsIClassInfo;
+const nsIComponentRegistrar = Components.interfaces.nsIComponentRegistrar;
+const nsIObserverService = Components.interfaces.nsIObserverService;
+
+ContentWindowMapper.prototype =
+{
+  QueryInterface: function(iid)
+  {
+    if (!iid.equals(nsIClassInfo) &&
+        !iid.equals(nsISupports)) {
+      Components.returnCode = Cr.NS_ERROR_NO_INTERFACE;
+      return null;
+    }
+    return this;
+  },
+
+  wrappedJSObject: null,  // Initialized by constructor
+
+  // make this an nsIClassInfo object
+  flags: nsIClassInfo.DOM_OBJECT,
+
+  // method of nsIClassInfo
+  classDescription: "ContentWindowMapper",
+
+  // method of nsIClassInfo
+  getInterfaces: function(count) {
+    var interfaceList = [nsIClassInfo];
+    count.value = interfaceList.length;
+    return interfaceList;
+  },
+
+  // method of nsIClassInfo
+  getHelperForLanguage: function(count) { return null; },
+
+}
+
+var ContentWindowMapperFactory = new Object();
+
+ContentWindowMapperFactory.createInstance = function (outer, iid)
+{
+  if (outer != null) {
+    Components.returnCode = Cr.NS_ERROR_NO_AGGREGATION;
+    return null;
+  }
+  if (!iid.equals(nsIClassInfo) &&
+      !iid.equals(nsISupports)) {
+    Components.returnCode = Cr.NS_ERROR_NO_INTERFACE;
+    return null;
+  }
+  return new ContentWindowMapper();
+}
+
+var ContentWindowMapperModule = new Object();
+
+ContentWindowMapperModule.registerSelf = 
+function (compMgr, fileSpec, location, type)
+{
+  compMgr = compMgr.QueryInterface(nsIComponentRegistrar);
+  compMgr.registerFactoryLocation(kMODULE_CID,
+                                  kMODULE_NAME,
+                                  kMODULE_CONTRACTID,
+                                  fileSpec, 
+                                  location, 
+                                  type);
+}
+
+ContentWindowMapperModule.getClassObject = function (compMgr, cid, iid)
+{
+  if (cid.equals(kMODULE_CID))
+    return ContentWindowMapperFactory;
+
+
+  Components.returnCode = Cr.NS_ERROR_NOT_REGISTERED;
+  return null;
+}
+
+ContentWindowMapperModule.canUnload = function (compMgr)
+{
+  return true;
+}
+
+function NSGetModule(compMgr, fileSpec)
+{
+  return ContentWindowMapperModule;
+}



More information about the tor-commits mailing list