[Pkg-mozext-commits] [greasemonkey] 27/43: Repair script installation via nsIContentPolicy for frame scripts.

David Prévot taffit at moszumanska.debian.org
Sun Feb 22 21:56:11 UTC 2015


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository greasemonkey.

commit 734f0db6628517f79e9ba3714109b6906c6d927c
Author: Anthony Lieuallen <arantius at gmail.com>
Date:   Wed Jan 7 14:14:32 2015 -0500

    Repair script installation via nsIContentPolicy for frame scripts.
---
 components/greasemonkey.js         |  12 +++-
 content/framescript.js             |  63 +++++-------------
 modules/installPolicy.js           | 130 +++++++++++++++++++++++++++++++++++++
 modules/util/findMessageManager.js |  24 +++++++
 modules/util/showInstallDialog.js  |   6 +-
 5 files changed, 184 insertions(+), 51 deletions(-)

diff --git a/components/greasemonkey.js b/components/greasemonkey.js
index 716fc7e..2147c9e 100644
--- a/components/greasemonkey.js
+++ b/components/greasemonkey.js
@@ -51,6 +51,8 @@ function startup(aService) {
       'greasemonkey:script-install', aService.scriptInstall.bind(aService));
   messageManager.addMessageListener(
       'greasemonkey:scripts-for-url', aService.getScriptsForUrl.bind(aService));
+  messageManager.addMessageListener(
+    'greasemonkey:url-is-temp-file', aService.urlIsTempFile.bind(aService));
 
   var scriptValHandler = aService.handleScriptValMsg.bind(aService);
   messageManager.addMessageListener(
@@ -179,10 +181,18 @@ service.prototype.handleScriptValMsg = function(aMessage) {
 };
 
 service.prototype.scriptInstall = function(aMessage) {
-  dump('>>> component scriptInstall ... '+aMessage.data+'\n');
   GM_util.showInstallDialog(aMessage.data.url, aMessage.target);
 };
 
+service.prototype.urlIsTempFile = function(aMessage) {
+  try {
+    var file = gFileProtocolHandler.getFileFromURLSpec(aMessage.data.url);
+  } catch (e) {
+    return false;
+  }
+  return gTmpDir.contains(file);
+};
+
 //////////////////////////// Component Registration ////////////////////////////
 
 var NSGetFactory = XPCOMUtils.generateNSGetFactory([service]);
diff --git a/content/framescript.js b/content/framescript.js
index ede7a09..22f4503 100644
--- a/content/framescript.js
+++ b/content/framescript.js
@@ -9,6 +9,7 @@ Cu.import('resource://gre/modules/Services.jsm');
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 
 Cu.import('resource://greasemonkey/GM_setClipboard.js');
+Cu.import('resource://greasemonkey/installPolicy.js');
 Cu.import('resource://greasemonkey/ipcscript.js');
 Cu.import('resource://greasemonkey/miscapis.js');
 Cu.import('resource://greasemonkey/sandbox.js');
@@ -17,7 +18,6 @@ Cu.import('resource://greasemonkey/util.js');
 // \\ // \\ // \\ // \\ // \\ // \\ // \\ // \\ // \\ // \\ // \\ // \\ // \\ //
 
 var gScope = this;
-var gScriptEndingRegexp = new RegExp('\\.user\\.js$');
 var gScriptRunners = {};
 var gStripUserPassRegexp = new RegExp('(://)([^:/]+)(:[^@/]+)?@');
 
@@ -97,7 +97,6 @@ ScriptRunner.prototype.windowIsTop = function(aContentWin) {
 // \\ // \\ // \\ // \\ // \\ // \\ // \\ // \\ // \\ // \\ // \\ // \\ // \\ //
 
 function ContentObserver() {
-  this._ignoreNextScript = false;
 }
 
 
@@ -105,36 +104,6 @@ ContentObserver.prototype.QueryInterface = XPCOMUtils.generateQI([
     Ci.nsIObserver]);
 
 
-ContentObserver.prototype.checkHttpEvent = function(aChannel) {
-  var uri = aChannel.URI;
-
-  if (!GM_util.getEnabled()) return;
-
-  // Don't interrupt the "view-source:" scheme (which is triggered if the link
-  // in the error console is clicked), nor the "greasemonkey-script:" scheme.
-  if ('view-source' == uri.scheme) return;
-  if ('greasemonkey-script' == uri.scheme) return;
-
-  // Do not install scripts when the origin URL "is a script".  See #1875
-  if (aChannel.referer && aChannel.referer.spec.match(gScriptEndingRegexp)) {
-    return;
-  }
-
-  if (uri.spec.match(gScriptEndingRegexp)
-      && !this._ignoreNextScript
-      && !isTempScript(uri)
-  ) {
-    this._ignoreNextScript = true;
-    aChannel.cancel(Components.results.NS_BINDING_ABORTED);
-    dump('TODO SHOW INSTALL DIALOG HERE\n');
-    dump(uri.spec+'\n');
-    sendAsyncMessage('greasemonkey:script-install', {
-      'url': uri.spec,
-    });
-  }
-};
-
-
 ContentObserver.prototype.contentLoad = function(aEvent) {
   var contentWin = aEvent.target.defaultView;
 
@@ -156,6 +125,14 @@ ContentObserver.prototype.createScriptFromObject = function(aObject) {
 };
 
 
+ContentObserver.prototype.loadFailedScript = function(aMessage) {
+  ignoreNextScript();
+  docShell.loadURI(
+      GM_util.uriFromUrl(aMessage.data.url),
+      /* loadInfo */ null, /* aLoadFlags */ null, /* firstParty */ true);
+};
+
+
 ContentObserver.prototype.observe = function(aSubject, aTopic, aData) {
   if (!GM_util.getEnabled()) return;
 
@@ -177,10 +154,6 @@ ContentObserver.prototype.observe = function(aSubject, aTopic, aData) {
 
       this.runScripts('document-start', win);
       break;
-    case 'http-on-modify-request':
-      aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
-      this.checkHttpEvent(aSubject);
-      break;
     default:
       dump('Content frame observed unknown topic: ' + aTopic + '\n');
   }
@@ -295,21 +268,17 @@ addEventListener('pageshow', contentObserver.pageshow.bind(contentObserver));
 
 addMessageListener('greasemonkey:inject-script',
     contentObserver.runDelayedScript.bind(contentObserver));
+addMessageListener('greasemonkey:load-failed-script',
+  contentObserver.loadFailedScript.bind(contentObserver));
 addMessageListener('greasemonkey:menu-command-clicked',
     contentObserver.runMenuCommand.bind(contentObserver));
 
 Services.obs.addObserver(contentObserver, 'document-element-inserted', false);
-try {
-  Services.obs.addObserver(contentObserver, 'http-on-modify-request', false);
-} catch (e) {
-  // Ignore; this will sometimes fail on some weird frames that happen to
-  // be loading about:blank. (WHY?!?!?!?)
-}
 addEventListener('unload', function() {
   Services.obs.removeObserver(contentObserver, 'document-element-inserted');
-  try {
-    Services.obs.removeObserver(contentObserver, 'http-on-modify-request');
-  } catch (e) {
-    // Ignore, in case we ignored failure to add above.
-  }
 }, false);
+
+(function() {
+  var tmpDir = sendSyncMessage('greasemonkey:temp-dir-path');
+  initInstallPolicy(tmpDir[0]);
+})();
diff --git a/modules/installPolicy.js b/modules/installPolicy.js
new file mode 100644
index 0000000..76fdbac
--- /dev/null
+++ b/modules/installPolicy.js
@@ -0,0 +1,130 @@
+// This module is responsible for observing HTTP traffic, detecting when a user
+// script is loaded (e.g. a link to one is clicked), and launching the install
+// dialog instead.
+var EXPORTED_SYMBOLS = ['ignoreNextScript', 'initInstallPolicy'];
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+
+Cu.import('resource://gre/modules/XPCOMUtils.jsm');
+
+Cu.import('resource://greasemonkey/util.js');
+
+var gIgnoreNextScript = false;
+var gScriptEndingRegexp = new RegExp('\\.user\\.js$');
+
+////////////////////////////////////////////////////////////////////////////////
+
+function ignoreNextScript() {
+  gIgnoreNextScript = true;
+}
+
+function initInstallPolicy(aTmpPath) {
+  InstallPolicy.init(aTmpPath);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+var InstallPolicy = {
+  _classDescription: 'Greasemonkey Script Install Policy',
+  _classID: Components.ID('c03c575c-e87e-4a0f-b88d-8be090116a0c'),
+  _contractID: '@greasemonkey.mozdev.org/greasemonkey-install-policy;1',
+
+  init: function(aTmpPath) {
+    try {
+      var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
+      registrar.registerFactory(
+          this._classID, this._classDescription, this._contractID, this);
+    } catch (e) {
+      if ('NS_ERROR_FACTORY_EXISTS' == e.name) {
+        // No-op, ignore these.  But why do they happen!?
+      } else {
+        dump('Error registering InstallPolicy factory:\n' + e + '\n');
+      }
+      return;
+    }
+
+    var catMan = Cc["@mozilla.org/categorymanager;1"]
+        .getService(Ci.nsICategoryManager);
+    catMan.addCategoryEntry(
+        'content-policy', this._contractID, this._contractID, false, true);
+
+    this._tmpPath = aTmpPath;
+  },
+
+  QueryInterface: XPCOMUtils.generateQI([
+      Ci.nsIContentPolicy,
+//      Ci.nsIObserver,
+//      Ci.nsIChannelEventSink,
+      Ci.nsIFactory,
+      Ci.nsISupportsWeakReference
+      ]),
+
+/////////////////////////////// nsIContentPolicy ///////////////////////////////
+
+  shouldLoad: function(aContentType, aContentURI, aOriginURI, aContext) {
+    var ret = Ci.nsIContentPolicy.ACCEPT;
+
+    // Don't intercept anything when GM is not enabled.
+    if (!GM_util.getEnabled()) {
+      return ret;
+    }
+
+    // Don't interrupt the "view-source:" scheme (which is triggered if the link
+    // in the error console is clicked), nor the "greasemonkey-script:" scheme.
+    if ("view-source" == aContentURI.scheme
+        || "greasemonkey-script" == aContentURI.scheme) {
+      return ret;
+    }
+
+    // Do not install scripts when the origin URL "is a script".  See #1875
+    if (aOriginURI && aOriginURI.spec.match(gScriptEndingRegexp)) {
+      return ret;
+    }
+
+    if (aContentType != Ci.nsIContentPolicy.TYPE_DOCUMENT
+        && aContentType != Ci.nsIContentPolicy.TYPE_SUBDOCUMENT) {
+      return ret;
+    }
+
+    if (!aContentURI.spec.match(gScriptEndingRegexp)) {
+      return ret;
+    }
+
+    var messageManager = GM_util.findMessageManager(aContext);
+
+    var tmpResult = messageManager
+        .sendSyncMessage('greasemonkey:url-is-temp-file', {
+          'url': aContentURI.spec,
+        });
+    if (tmpResult.length && tmpResult[0]) {
+      return ret;
+    }
+
+    if (!gIgnoreNextScript) {
+      ret = Ci.nsIContentPolicy.REJECT_REQUEST;
+      messageManager.sendAsyncMessage('greasemonkey:script-install', {
+        'url': aContentURI.spec,
+      });
+    }
+    gIgnoreNextScript = false;
+
+    return ret;
+  },
+
+  shouldProcess: function() {
+    dump('>>> installPolicy shouldProcess() ...\n');
+    return Ci.nsIContentPolicy.ACCEPT;
+  },
+
+////////////////////////////////// nsIFactory //////////////////////////////////
+
+  createInstance: function(outer, iid) {
+    if (outer) {
+      throw Cr.NS_ERROR_NO_AGGREGATION;
+    }
+    return this.QueryInterface(iid);
+  },
+
+};
diff --git a/modules/util/findMessageManager.js b/modules/util/findMessageManager.js
new file mode 100644
index 0000000..7f17f56
--- /dev/null
+++ b/modules/util/findMessageManager.js
@@ -0,0 +1,24 @@
+const EXPORTED_SYMBOLS = ['findMessageManager'];
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+
+function findMessageManager(aContext) {
+  // With e10s off, context is a <browser> with a direct reference to
+  // the docshell loaded therein.
+  var docShell = aContext && aContext.docShell;
+
+  if (!docShell) {
+    // But with e10s on, context is a content window and we have to work hard
+    // to find the docshell, from which we can find the message manager.
+    docShell = aContext
+        .QueryInterface(Ci.nsIInterfaceRequestor)
+        .getInterface(Ci.nsIWebNavigation)
+        .QueryInterface(Ci.nsIDocShellTreeItem).rootTreeItem;
+  }
+
+  return docShell
+      .QueryInterface(Ci.nsIInterfaceRequestor)
+      .getInterface(Ci.nsIContentFrameMessageManager);
+}
diff --git a/modules/util/showInstallDialog.js b/modules/util/showInstallDialog.js
index 2c916a9..71f7971 100644
--- a/modules/util/showInstallDialog.js
+++ b/modules/util/showInstallDialog.js
@@ -39,9 +39,9 @@ function showInstallDialog(aUrlOrRemoteScript, aBrowser) {
 
   rs.download(function(aSuccess, aType) {
     if (!aSuccess && 'script' == aType) {
-      // Failure downloading script; browse to it.
-//      aService.ignoreNextScript();
-      aBrowser.loadURI(rs.url, /* aReferrer */ null, /* aCharset */ null);
+      aBrowser.messageManager.sendAsyncMessage(
+          'greasemonkey:load-failed-script',
+          {'url': rs.url});
     }
   });
 }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/greasemonkey.git



More information about the Pkg-mozext-commits mailing list