[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r11723: Rework hooking code to be based off of the toplevel content (in torbutton/trunk/src: . chrome/content components)
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;
+}