XPCNativeWrapper is a way to wrap up an object so that it's safe to access from privileged code. It can be used in all Firefox versions, though the
behavior changed somewhat starting with Firefox 1.5 (or rather Gecko 1.8).
XPCNativeWrapper in Firefox versions prior to 1.5
In Firefox versions prior to 1.5, use of
XPCNativeWrapper requires manually constructing an
XPCNativeWrapper and passing it the object to be wrapped and the names of the methods/properties to be exposed as arguments. The resulting object exposes ONLY the methods/properties whose methods were passed as arguments. This is described in more detail in the the entry for
XPCNativeWrapper at the MozillaZine KnowledgeBase.
XPCNativeWrapper in Firefox versions starting with 1.5
There are three different types of
XPCNativeWrapper in Firefox 1.5. All three types wrap a possibly-unsafe object and provide safe access to all of its properties and methods (unlike
XPCNativeWrapper in versions before 1.5, which only provided safe access to the properties and methods listed in its constructor). If unsafe access to a property is required for some reason, this can be accomplished via the
wrappedJSObject property of the wrapper. For example, if
docWrapper is a wrapper for
is the same as
The differences in behavior between the three types of
XPCNativeWrapper are determined by two characteristics an
XPCNativeWrapper wrapper can have. An
XPCNativeWrapper can be explicit (or the opposite, implicit) and can be deep (or the opposite, shallow). The type of wrapper created is generally determined by the way it was created as follows:
|Constructor called with string arguments||Explicit||Shallow|
|Constructor called with no string arguments||Explicit||Deep|
Explicit vs. Implicit
The difference in behavior between explicit and implicit
XPCNativeWrapper is that a property access on an implicit
XPCNativeWrapper from code that does not have
xpcnativewrappers=yes is NOT safe. The property access will be forwarded through to the
wrappedJSObject of the
This means the code that doesn't use
xpcnativewrappers=yes doesn't need to worry about bugs arising because other code that does hands it an implicit
XPCNativeWrapper. On the other hand, it does need to watch out for unsafe object access.
Property access on an explicit
XPCNativeWrapper is safe no matter whether
xpcnativewrappers=yes is being used.
Deep vs. Shallow
The difference in behavior between deep and shallow
XPCNativeWrapper is that when a property is accessed or a function is called on a deep wrapper the return value will be wrapped in a
XPCNativeWrapper of its own. The new
XPCNativeWrapper will also be deep and it will be explicit if and only if the
XPCNativeWrapper whose property is accessed was explicit. By contrast, when a property is accessed or a function is called on a shallow wrapper, the return value may be an unsafe object.
For example, say we are given three instances of
XPCNativeWrapper for the same window object. Let us call them
shallowWindow. Then we have:
var doc1 = deepExplicitWindow.document; // doc1 is now a deep explicit
XPCNativeWrapperfor // the document object. Accessing doc1.open(), say, is safe.
var doc2 = deepImplicitWindow.document; // If the caller has xpcnativewrappers=yes set, doc2 is now a deep // implicit
XPCNativeWrapperfor the document object. // Otherwise doc2 is now the unsafe document object, since the // property access was simply passed along to the unsafe window object.
var doc3 = shallowWindow.document; // doc3 is now the unsafe document object.
There are three different ways of creating an
XPCNativeWrapper object; one way for each of the three types.
XPCNativeWrapper constructor call with string arguments
var contentWinWrapper = new XPCNativeWrapper(content, "document");
This creates an explicit shallow
XPCNativeWrapper. This syntax has been kept for compatibility with versions prior to Firefox 1.5. While all properties of the
contentWinWrapper object can now be safely accessed, the return values of these properties are NOT safe to access (just like in versions prior to Firefox 1.5), since the
XPCNativeWrapper is shallow. So to compare the content document title to the current content selection, one must do:
var winWrapper = new XPCNativeWrapper(content, "document", "getSelection()"); var docWrapper = new XPCNativeWrapper(winWrapper.document, "title"); return docWrapper.title == winWrapper.getSelection();
just like in versions before Firefox 1.5. Note that the
"getSelection()" argument is not strictly needed here; if the code is not intended for use with Firefox versions before 1.5 it can be removed. A single string argument after the object being wrapped is all that is required for Firefox 1.5 to create this type of
XPCNativeWrapper constructor call with no string arguments
var contentWinWrapper = new XPCNativeWrapper(content);
Code that has
xpcnativewrappers=yes and accesses a content object will get back an implicit deep
XPCNativeWrapper. Accessing properties of this
XPCNativeWrapper is safe from code that uses
xpcnativewrappers=yes, and the return values will also be wrapped in implicit deep
A wrapper created in this way will stick around as long as the object being wrapped does and accessing an object twice in a row will give the same
Setting "expando" properties on
It is possible to set "expando" properties (properties with names that don't correspond to IDL-defined properties) on
XPCNativeWrapper objects. If this is done, then chrome will be able to see these expando properties, but content will not be able to. There is no safe way to set an expando property from chrome and have it be readable from content.
XPCNativeWrapper objects exist while they are referenced. Creating a new explicit
XPCNativeWrapper for the same possibly-unsafe object will create a new wrapper object; something to watch out for when setting "expando" properties
XPCNativeWrapper objects have the same lifetime as the object they're wrapping.
There are some commonly used properties and coding styles that cannot be used with
- Assigning to or reading an
on*property on an
XPCNativeWrapperof a DOM node or Window object will throw an exception.
document.alldoes not work on an
XPCNativeWrapperfor a document.
- Calling methods implemented by NPAPI plugins though the
XPCNativeWrapperfor the corresponding node does not work.
- Getting or setting properties implemented by NPAPI plugins though the
XPCNativeWrapperfor the corresponding node does not work.
- Calling methods implemented via XBL bindings attached to a node through an
XCPNativeWrapper> for that node does not work.
- Getting or setting properties implemented via XBL bindings attached to a node through an <code>XCPNativeWrapper> for that node does not work.
- Enumerating the properties of an <code>XPCNativeWrapper via "
for (var p in wrapper)" does not enumerate the IDL-defined properties.