简体   繁体   中英

Firefox 29, XPCOM and wrappedJSObject

We are using a custom Javascript-only add-on for Firefox, which is used in some of our intranet sites. This add-on is supposed to load a specific text file from a user's PC, and then expose specific variables to some of our intranet pages.

The current implementation works from FF3 up to FF28. In FF29, the behavior of wrappedJSObject has changed.

Here's what I got in the add-on's code:

Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");  

function PrivateClass() {
  this.wrappedJSObject = this;
}

PrivateClass.prototype = {
// Component details
classDescription: "...",
classID:          Components.ID("{...}"),
contractID:       "@foo.bar/PrivateClass;1",
QueryInterface:   XPCOMUtils.generateQI([Ci.nsIClassInfo]),

getInterfaces: function(countRef) {
    var interfaces = [Ci.nsIClassInfo, Ci.nsISupports];
    countRef.value = interfaces.length;
    return interfaces;
},

implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
flags: Ci.nsIClassInfo.DOM_OBJECT,
getHelperForLanguage: function(count) { return null; },

// We use the default _xpcom_factory

// Categories to register
_xpcom_categories: [{
  category: "JavaScript global property",
  entry: "PrivateClass",          // optional, defaults to the object's classDescription. Needed for FF3.
  value: "@foo.bar/PrivateClass;1",  // optional, defaults to the object's contractID. Needed for FF3.
  service: false
}],

// nsISecurityCheckedComponent permissions
// return "AllAccess"; / return "NoAccess";
canCreateWrapper : function canCreateWrapper(aIID) { return "AllAccess"; },
canCallMethod: function canCallMethod(aIID, methodName) { return "AllAccess"; },
canGetProperty: function canGetProperty(aIID, propertyName) { return "AllAccess"; },  // needed to access wrappedJSObject
canSetProperty: function canSetProperty(aIID, propertyName) { return "NoAccess"; },

getFunctionA : function() { return "This is A"; },
getFunctionB : function() { return "This is B"; },

// New functionality, needed for FF 17+
// https://developer.mozilla.org/en-US/docs/XPConnect_wrappers#__exposedProps__
__exposedProps__ : { getFunctionA : "r", getFunctionB : "r" }
}

And in the client page:

if (typeof PrivateClass != "undefined") {
  var obj = PrivateClass.wrappedJSObject;
  var a = obj.getFunctionA()
  var b = obj.getFunctionB();
}

However, now FF returns Error: Attempt to use .wrappedJSObject in untrusted code in this line:

var obj = PrivateClass.wrappedJSObject;

I've read about the upcoming changes to wrappedJSObject in FF30 in this blog post: https://blog.mozilla.org/addons/2014/04/10/changes-to-unsafewindow-for-the-add-on-sdk/

...but the recommended solutions won't work for me

Note that the wrappedJSObject solution is in the official Mozilla developer docs here and here . It can also be found all around the Internet (eg here ), but apparently it has been somehow broken/changed in FF29, so none of these apply.

I've checked the excellent FF add-on jsPrintSetup , and it doesn't use wrappedJSObject (although it has a C++ binary component too, which might explain this). I've read through a lot of forum posts regarding this issue with wrappedJSObject, but I can't find anything regarding this particular change to its behavior. Can anyone shed some light as to what needs to be done in order to get this functionality working under FF29+?

Yes, I added a check against untrusted content inspecting the guts of an XPCOM component, which it really has no business doing. It should still work just fine from privileged code.

Also note that nsISecurityCheckedComponent was removed , so you shouldn't need that part anymore.

In general, the most future-proof way to expose an API to content is to inject it directly into the content scope with exportFunction.

Extra info

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM