--- title: XPCNativeWrapper slug: XPCNativeWrapper tags: - DOM - Extensions - Sécurité - XPCNativeWrapper translation_of: Mozilla/Tech/Xray_vision ---
XPCNativeWrapper
permet d'emballer un objet pour qu'il soit sur d'y accéder depuis du code privilègié. Il peut être utilisé dans toutes les versions de Firefox, bien que son comportement ait été légèrement modifié depuis Firefox 1.5 (Gecko 1.8). Consultez les informations sur XPCNativeWrapper
dans la base de connaissance de MozillaZine pour connaître le comportement de XPCNativeWrapper
dans les versions de Firefox antérieures à 1.5. Ce document traite de XPCNativeWrapper
dans Firefox 1.5 et postérieurs.
XPCNativeWrapper
Un XPCNativeWrapper
restreint l'accès aux propriétés et méthodes des objets qu'il enveloppe. Les seules propriétés et méthodes accessibles au travers du XPCNativeWrapper
sont celles définies dans les IDL ou définies par le niveau 0 du DOM (bien que certaines propriétés et méthodes du niveau 0 du DOM ne fonctionnent pas sur un XPCNativeWrapper
). En particulier, les propriétés ajoutées à un objet via JavaScript ne sont pas accessibles à travers un XPCNativeWrapper
, pas plus que les accesseurs et mutateurs définis avec __defineGetter__
et __defineSetter__
. L'objectif est de pouvoir accéder en toute sécurité aux méthodes d'un objet définies dans les IDL .
Assurez-vous de lire la section concernant les bugs connus, en particulier si vous écrivez du code destiné à certaines versions de Firefox 1.5.0.x.
XPCNativeWrapper
Il existe trois types différents de XPCNativeWrapper
dans Firefox 1.5. Chacun enveloppe un objet potentiellement non sur et fournit un accès sécurisé à ses propriétés et méthodes.
Les différences de comportement entre ces trois types sont déterminées par deux caractéristiques du XPCNativeWrapper
. Un XPCNativeWrapper
peut être explicite (ou par opposition, implicite) et peut être profond (ou par opposition, superficiel). Le type de l'emballage créé est déterminé par la façon dont il est créé, de la manière suivante :
Créé par | Explicite/Implicite | Profond/Superficiel |
---|---|---|
Un script protégé accédant à un objet non sécurisé | Implicite | Profond |
Appel du constructeur avec des paramètres | Explicite | Superficiel |
Appel du constructeur sans paramètre | Explicite | Profond |
La différence de comportement entre un XPCNativeWrapper
explicite et un implicite est qu'un accès à une propriété d'un XPCNativeWrapper
implicite depuis un script non protégé N'est PAS sûr. L'accès à la propriété sera transmis à travers l'objet wrappedJSObject
du XPCNativeWrapper
.
Ainsi, les scripts qui ne sont pas protégés n'ont pas à se soucier de bogues dûs au fait qu'un autre bout de code leur passerait un XPCNativeWrapper
implicite. D'un autre côté, de tels scripts doivent se méfier des accès à des objets non sûrs.
Les accès aux propriétés d'un XPCNativeWrapper
explicite sont sûrs, que le script appelant soit ou non protégé.
La différence de comportement entre un XPCNativeWrapper
profond et un superficiel est que, lors de l'accès à une propriété ou de l'appel d'une fonction sur un profond, la valeur renvoyée sera enveloppée dans son propre XPCNativeWrapper
. Le nouvel XPCNativeWrapper
sera également profond et sera explicite si et seulement si le XPCNativeWrapper
dont la propriété est accédée était explicite. En revanche, l'accès à une propriété ou l'appel d'une fonction sur un emballage superficiel renverra une valeur qui peut être un objet non sûr.
Par exemple, admettons que nous ayons trois instances de XPCNativeWrapper
pour le même objet window
. Appelons les deepExplicitWindow
, deepImplicitWindow
et shallowWindow
. Nous avons alors :
var doc1 = deepExplicitWindow.document;
// doc1 est maintenant un XPCNativeWrapper
profond et explicite
// pour l'objet document. L'accès à doc1.open() est sûr.
var doc2 = deepImplicitWindow.document;
// Si le code appelant est paramétré avec xpcnativewrappers=yes, doc2 est
// un XPCNativeWrapper
profond et implicite pour l'objet document.
// Autrement, doc2 est un objet document non sécurisé, puisque les accès
// aux propriétés sont simplement transmises à un objet non sécurisé.
var doc3 = shallowWindow.document; // doc3 est maintenant un objet document non sécurisé.
XPCNativeWrapper
Il existe trois manières différentes de créer un objet XPCNativeWrapper
; une pour chacun des trois types.
À chaque fois qu'un script protégé accède à un objet non sécurisé, il obtient en retour un XPCNativeWrapper
implicite et profond. L'accès aux propriétés de ce XPCNativeWrapper
depuis des scripts protégés est sécurisé.
Un emballage créé de cette façon existera aussi longtemps que l'objet emballé, et accéder à cet objet deux fois de suite donnera le même XPCNativeWrapper
.
Dans les versions de Firefox comprises entre la 1.5 et la 1.5.0.5, un script est protégé ou non selon son URI. Un script est protégé seulement si son URI commence par un préfixe protégé connu ; les scripts qui ne sont pas chargés par une URI (par exemple les composants implémentés en JavaScript) ne sont pas protégés. Les préfixes protégés dans Firefox 1.5 sont déterminés par le registre Chrome.
Par défaut, tous les paquetages de contenu sont protégés. De ce fait, toutes les URI commençant par "<tt>chrome://<nom du paquetage>/content/</tt>" (quel que soit le paquetage) sont protégées. Des paquetages individuels peuvent contourner ce comportement par une option dans leur fichier manifeste chrome.
À partir de Firefox 1.5.0.6, les composants implémentés depuis JavaScript sont des scripts protégés. Par conséquent, un script est protégé s'il est soit chargé depuis une URI débutant par un préfixe protégé, ou est un composant implémenté en JavaScript.
Tous les objets sont soit sécurisés, soit non sécurisés. Un objet est sécurisé si une au moins de ces trois conditions est remplie :
__parent__
en JavaScript) est un objet sécurisé.
window
d'une fenêtre sécurisée.
Puisque tous les objets DOM d'une fenêtre disposent de l'objet window
dans leur chaîne d'objets __parent__
, ils seront sécurisés si et seulement si la fenêtre dans lesquelle ils se trouvent l'est.
Une fenêtre est sécurisée ou pas suivant son conteneur. Une fenêtre est sécurisée si une des conditions suivantes est remplie :
<xul:window>
, <xul:dialog>
, ou une URI quelconque passée en ligne de commande avec l'option <tt>-chrome</tt>).
<xul:iframe>
ou <xul:browser>
.
<xul:iframe>
ou <xul:browser>
ne possédant pas d'attribut « type ».
<xul:iframe>
ou <xul:browser>
dont la valeur de l'attribut « type » n'est pas « content » ni ne débute par « content- ».
Notez que le fait qu'une fenêtre soit sécurisée ne dépend pas de l'URI chargée dans la fenêtre. Par conséquent, les exemples suivants créeront des fenêtres sécurisées s'ils sont utilisés à l'intérieur d'un document dont la fenêtre est déjà sécurisée :
<xul:browser>
<xul:browser type="chrome">
<xul:browser type="rabid_dog">
<xul:iframe type="foofy">
<html:iframe>
<html:iframe type="content">
Ce qui suit ne crée pas de fenêtres sécurisées :
<xul:browser type="content">
<xul:iframe type="content-primary">
Notez de même que toutes les fenêtres filles d'une fenêtre non sécurisée sont automatiquement non sécurisées.
Le tableau ci-dessous décrit ce qui se produit lorsqu'un script accède à un objet et comment l'emballage est impliqué.
Script | Objet | Effets |
---|---|---|
Protégé | Sécurisé | Aucun emballage n'est créé et par conséquent le script obtient un accès complet à l'objet. |
Protégé | Sécurisé | Un XPCNativeWrapper implicite et profond est créé.
|
Non protégé | Sécurisé | Aucun emballage n'est créé, exactement comme dans le cas protégé/sécurisé. |
Non protégé | Non sécurisé | Aucun emballage n'est créé, exactement comme dans le cas protégé/sécurisé. |
XPCNativeWrapper
avec des paramètres Par exemple :
var contentWinWrapper = new XPCNativeWrapper(content, "document");
Cette ligne va créer un XPCNativeWrapper
explicite et superficiel. Cette syntaxe a été conservée pour la compatibilité avec les versions antérieures à Firefox 1.5. Bien que toutes les propriétés de l'objet contentWinWrapper
sont sécurisées, les valeurs renvoyées par ces propriétés NE le sont PAS (comme dans les versions antérieures à Firefox 1.5), puisque XPCNativeWrapper
est superficiel. Donc pour comparer le titre du document courant à la sélection de contenu actuelle, il faut procéder ainsi :
var winWrapper = new XPCNativeWrapper(content, "document", "getSelection()"); var docWrapper = new XPCNativeWrapper(winWrapper.document, "title"); return docWrapper.title == winWrapper.getSelection();
de la même manière qu'avec les versions antérieures à Firefox 1.5. Notez que l'argument "getSelection()"
n'est pas strictement nécessaire ici ; si le code n'est pas destiné à être utilisé avec des versions antérieures à Firefox 1.5, il peut être supprimé. Un seul argument après l'objet emballé est nécessaire à Firefox 1.5 pour créer ce type de XPCNativeWrapper
.
XPCNativeWrapper
sans paramètre Par exemple :
var contentWinWrapper = new XPCNativeWrapper(content);
Cette ligne va créer un XPCNativeWrapper
explicite et profond. L'accès aux propriétés de ce XPCNativeWrapper
est sécurisé, et les valeurs renvoyées seront également emballées dans des objets XPCNativeWrapper
explicites et profonds.
XPCNativeWrapper
Il est possible de définir des propriétés "expando" (des propriétés dont les noms ne correspondent à aucune propriété IDL) sur des objets XPCNativeWrapper
. En procédant ainsi, le chrome sera capable de voir ces propriétés expando, mais le contenu ne pourra pas. Il n'existe pas de manière sécurisée de définir une propriété expando depuis le chrome et de la rendre accessible depuis le contenu.
XPCNativeWrapper
Les objets XPCNativeWrapper
explicites existent tant qu'ils sont référencés. Créé un nouvel XPCNativeWrapper
explicite pour le même objet potentiellement non sécurisé créera un nouvel emballage ; c'est une chose à surveiller lors de la définition de propriétés "expando".
Les objets XPCNativeWrapper
implicites ont la même durée de vie que les objets qu'ils emballent.
Si un accès non sécurisé à une propriété est nécessaire pour une raison précise, il suffit d'employer la propriété wrappedJSObject
de l'emballage. Par exemple, si docWrapper
est l'emballage de doc
, alors
docWrapper.wrappedJSObject.prop
est identique à
doc.prop
Il existe deux bogues de XPCNativeWrapper connus dans les versions 1.5.0.x :
XPCNativeWrapper
Il existe certaines propriétés couramment utilisées et certains styles de programmation qui ne peuvent pas être employés avec XPCNativeWrapper
. En particulier :
on*
sur un XPCNativeWrapper
d'un noeud DOM ou d'un objet Window va générer une exception. (Utilisez plutôt addEventListener
, et utilisez "event.preventDefault();"
dans votre gestionnaire si vous utilisiez "return false;"
auparavant.)
window.frameName
) ne fonctionne pas sur un XPCNativeWrapper
.
document.all
ne fonctionne pas avec le XPCNativeWrapper
d'un document.
XPCNativeWrapper
d'un document HTML. Par exemple, si vous avez <form name="foo">
et que docWrapper
est l'emballage du document HTML doc
, alors doc.foo
sera un HTMLFormElement
tandis que docWrapper.foo
sera undefined
. Vous pouvez utiliser à la place docWrapper.forms.namedItem("foo")
dans votre code.
XPCNativeWrapper
d'un document HTML. getElementById
doit être utilisé à la place.
XPCNativeWrapper
d'un formulaire HTML. Le code requis à la place est le suivant : form.elements.namedItem("inputname")
.
XPCNativeWrapper
d'un HTMLCollection
. Il est nécessaire d'utiliser la méthode namedItem()
. Notez que namedItem
renvoie uniquement le premier élément input
de ce nom, même s'il en existe plusieurs (par exemple pour des boutons radio) au sein du formulaire.
XPCNativeWrapper
pour le nœud correspondant ne fonctionne pas.
XPCNativeWrapper
pour le nœud correspondant ne fonctionne pas.
XPCNativeWrapper
pour ce ce nœud ne fonctionne pas.
XPCNativeWrapper
pour le nœud correspondant ne fonctionne pas.
XPCNativeWrapper
via "for (var p in wrapper)
" ne permet de récupérer les propriétés définies dans les IDL.
XPCNativeWrapper
. Comme résultat, plusieurs propriétés Objet.prototype
sont indéfinies sur un XPCNativeWrapper
(pour être précis, ce sont __proto__
, __parent__
, __count__
, toSource
, toLocaleString
, valueOf
, watch
, unwatch
, hasOwnProperty
, isPrototypeOf
, propertyIsEnumerable
, __defineGetter__
, __defineSetter__
, __lookupGetter__
, et __lookupSetter__
).
importXPCNative
que l'ancienne implémentation XPCNativeWrapper
utilisait n'est plus gérée.
Function
) au travers d'un XPCNativeWrapper ne fonctionnera pas. Pour créer des fonctions et objets avec une fenêtre particulière comme parent, utilisez la fonction eval
de cette fenêtre.
L'article Avoid Common Pitfalls in Greasemonkey propose une explication élaborée de certaines de ces limitations (dans le contexte de scripts Greasemonkey).