aboutsummaryrefslogtreecommitdiff
path: root/files/ru/orphaned/xpcnativewrapper/index.html
blob: bd4a4ec19f0b534a9129e99426af07957effe939 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
---
title: XPCNativeWrapper
slug: orphaned/XPCNativeWrapper
tags:
  - DOM
  - XPCNativeWrapper
  - Безопасность
  - Расширения
original_slug: XPCNativeWrapper
---
<p> </p>
<p><code>XPCNativeWrapper</code> позволяет так обернуть объект, чтобы доступ к нему был <a href="/en/Safely_accessing_content_DOM_from_chrome">безопасен для привилегированного кода</a>. Эта обёртка может быть использована во всех версиях, хотя её поведение слегка изменилось начиная с <span>Firefox 1.5</span> (<span>Gecko 1.8</span>). Информацию о поведении <code>XPCNativeWrapper</code> в <span>Firefox</span> версий младше 1.5 можно получить из <a class="external" href="http://kb.mozillazine.org/XPCNativeWrapper">статьи о <code>XPCNativeWrapper</code> в <span>MozillaZine KnowledgeBase</span></a>. Эта же статья посвящена <code>XPCNativeWrapper</code> в <span>Firefox</span> версий 1.5 и выше.</p>
<h3 id=".D0.A7.D1.82.D0.BE_.D0.B4.D0.B5.D0.BB.D0.B0.D0.B5.D1.82_XPCNativeWrapper" name=".D0.A7.D1.82.D0.BE_.D0.B4.D0.B5.D0.BB.D0.B0.D0.B5.D1.82_XPCNativeWrapper">Что делает <code>XPCNativeWrapper</code></h3>
<p>An <code>XPCNativeWrapper</code> limits access to the properties and methods of the object it wraps. The only properties and methods accessible through an <code>XPCNativeWrapper</code> are those that are defined in IDL or defined by DOM Level 0 (though some DOM Level 0 properties and methods <a href="#Limitations_of_XPCNativeWrapper">do not work on an <code>XPCNativeWrapper</code></a>). In particular, properties added to an object via JavaScript are not exposed by an <code>XPCNativeWrapper</code> for this object, and nor are getters and setters defined with <code>__defineGetter__</code> and <code>__defineSetter__</code>. The intent is to allow safe access to the IDL-defined methods of the object.</p>
<p>Please make sure to read the <a href="#Known_Bugs">known bugs</a> section, especially when writing code targeted at a range of 1.5.0.x Firefox releases.</p>
<h3 id=".D0.A2.D0.B8.D0.BF.D1.8B_XPCNativeWrapper" name=".D0.A2.D0.B8.D0.BF.D1.8B_XPCNativeWrapper">Типы <code>XPCNativeWrapper</code></h3>
<p>There are three different types of <code>XPCNativeWrapper</code> in Firefox 1.5. All three types wrap a possibly-unsafe object and <a href="#What_XPCNativeWrapper_does">provide safe access to its properties and methods</a>.</p>
<p>The differences in behavior between the three types of <code>XPCNativeWrapper</code> are determined by two characteristics an <code>XPCNativeWrapper</code> wrapper can have. An <code>XPCNativeWrapper</code> can be <a href="#Explicit_vs._Implicit"><em>explicit</em></a> (or the opposite, <em>implicit</em>) and can be <a href="#Deep_vs._Shallow"><em>deep</em></a> (or the opposite, <em>shallow</em>). The type of wrapper created is determined by <a href="#Creating_XPCNativeWrapper_objects">the way it was created</a> as follows:</p>
<table> <tbody> <tr> <th>Created by</th> <th>Explicit/Implicit</th> <th>Deep/Shallow</th> </tr> <tr> <th><a href="#Protected_script_accessing_an_untrusted_object">Protected script accessing an untrusted object</a></th> <td>Implicit</td> <td>Deep</td> </tr> <tr> <th><a href="#XPCNativeWrapper_constructor_call_with_string_arguments">Constructor called with string arguments</a></th> <td>Explicit</td> <td>Shallow</td> </tr> <tr> <th><a href="#XPCNativeWrapper_constructor_call_with_no_string_arguments">Constructor called with no string arguments</a></th> <td>Explicit</td> <td>Deep</td> </tr> </tbody>
</table>
<h4 id="Explicit_vs._Implicit" name="Explicit_vs._Implicit">Explicit vs. Implicit</h4>
<p>The difference in behavior between explicit and implicit <code>XPCNativeWrapper</code> is that a property access on an implicit <code>XPCNativeWrapper</code> from script that is not <a href="#What_is_a_protected_script.3F">protected</a> is NOT safe. The property access will be forwarded through to the <code>wrappedJSObject</code> of the <code>XPCNativeWrapper</code>.</p>
<p>This means that scripts that are not <a href="#What_is_a_protected_script.3F">protected</a> don't need to worry about bugs arising because other code hands them an implicit <code>XPCNativeWrapper</code>. On the other hand, such scripts do need to watch out for unsafe object access.</p>
<p>Property access on an explicit <code>XPCNativeWrapper</code> is safe no matter whether the caller is <a href="#What_is_a_protected_script.3F">protected</a>.</p>
<h4 id="Deep_vs._Shallow" name="Deep_vs._Shallow">Deep vs. Shallow</h4>
<p>The difference in behavior between deep and shallow <code>XPCNativeWrapper</code> is that when a property is accessed or a function is called on a deep wrapper the return value will be wrapped in a <code>XPCNativeWrapper</code> of its own. The new <code>XPCNativeWrapper</code> will also be deep and it will be <a href="#Explicit_vs._Implicit">explicit</a> if and only if the <code>XPCNativeWrapper</code> 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.</p>
<p>For example, say we are given three instances of <code>XPCNativeWrapper</code> for the same window object. Let us call them <code>deepExplicitWindow</code>, <code>deepImplicitWindow</code> and <code>shallowWindow</code>. Then we have:</p>
<pre class="eval">var doc1 = deepExplicitWindow.document;
// doc1 is now a deep explicit <code>XPCNativeWrapper</code> for
// the document object.  Accessing doc1.open(), say, is safe.
</pre>
<pre class="eval">var doc2 = deepImplicitWindow.document;
// If the caller has xpcnativewrappers=yes set, doc2 is now a deep
// implicit <code>XPCNativeWrapper</code> for the document object.
// Otherwise doc2 is now the unsafe document object, since the
// property access was simply passed along to the unsafe window object.
</pre>
<pre class="eval">var doc3 = shallowWindow.document;
// doc3 is now the unsafe document object.
</pre>
<h3 id=".D0.A1.D0.BE.D0.B7.D0.B4.D0.B0.D0.BD.D0.B8.D0.B5_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2_XPCNativeWrapper" name=".D0.A1.D0.BE.D0.B7.D0.B4.D0.B0.D0.BD.D0.B8.D0.B5_.D0.BE.D0.B1.D1.8A.D0.B5.D0.BA.D1.82.D0.BE.D0.B2_XPCNativeWrapper">Создание объектов <code>XPCNativeWrapper</code></h3>
<p>Существует три различных способа создания объекта <code>XPCNativeWrapper</code>; по одному способу на каждый из трёх типов.</p>
<h4 id="Protected_script_accessing_an_untrusted_object" name="Protected_script_accessing_an_untrusted_object">Protected script accessing an untrusted object</h4>
<p>Any time a <a href="#What_is_a_protected_script.3F">protected script</a> accesses an <a href="#What_is_an_untrusted_object.3F">untrusted object</a> it will get back an <a href="#Explicit_vs._Implicit">implicit</a> <a href="#Deep_vs._Shallow">deep</a> <code>XPCNativeWrapper</code>. Accessing properties of this <code>XPCNativeWrapper</code> is safe from <a href="#What_is_a_protected_script.3F">protected scripts</a>.</p>
<p>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 <code>XPCNativeWrapper</code>.</p>
<h5 id="What_is_a_protected_script.3F" name="What_is_a_protected_script.3F">What is a protected script?</h5>
<p>In Firefox versions 1.5 through 1.5.0.5, a script is protected or not protected based solely on its URI. A script is protected only if its URI starts with a known protected prefix; scripts not loaded by URI (e.g. JavaScript-implemented components) are not protected. The protected prefixes in Firefox 1.5 are determined by the Chrome Registry.</p>
<p>By default, <strong>all content packages are protected</strong>. This means that all URIs that start "<code>chrome://&lt;package name&gt;/content/</code>" (for any package) are protected. Individual packages can <a href="/ru/Chrome_Registration#xpcnativewrappers" title="ru/Chrome_Registration#xpcnativewrappers">override this using a flag</a> in their chrome manifest file.</p>
<p>Starting with Firefox 1.5.0.6, JavaScript-implemented components are protected scripts. So a script is protected if it's either loaded from a URI which starts with a protected prefix or is a JavaScript-implemented component.</p>
<h5 id="What_is_an_untrusted_object.3F" name="What_is_an_untrusted_object.3F">What is an untrusted object?</h5>
<p>All objects are either trusted or untrusted. An object is trusted if any of the following hold:</p>
<ol> <li>Its parent (<code>__parent__</code> property in JavaScript) is a trusted object.</li> <li>It is the root scope object for a JavaScript component.</li> <li>It is the window object for a <a href="#What_is_a_trusted_window.3F">trusted window</a>.</li>
</ol>
<p>Since all DOM objects in a window have the window on their <code>__parent__</code> chain, they will be trusted if and only if their window is trusted.</p>
<h5 id="What_is_a_trusted_window.3F" name="What_is_a_trusted_window.3F">What is a trusted window?</h5>
<p>Whether a window is trusted depends on its container. A window is trusted if any of the following holds:</p>
<ol> <li>It is a top-level window (e.g. <code>&lt;xul:window&gt;</code>, <code>&lt;xul:dialog&gt;</code>, or some URI passed to the <code>-chrome</code> command-line flag).</li> <li>Its parent is trusted, and one of the following three options holds: <ol> <li>It is not loaded in a <code>&lt;xul:iframe&gt;</code> or <code>&lt;xul:browser&gt;</code>.</li> <li>The <code>&lt;xul:iframe&gt;</code> or <code>&lt;xul:browser&gt;</code> loading it doesn't have a "type" attribute.</li> <li>The value of the "type" attribute of the <code>&lt;xul:iframe&gt;</code> or <code>&lt;xul:browser&gt;</code> loading it is not "content" and does not start with "content-".</li> </ol> </li>
</ol>
<p>Note that whether a window is trusted does <strong>not</strong> depend on the URI loaded in the window. So for example, the following would create trusted windows when used inside a document whose window is already trusted:</p>
<ul> <li><code>&lt;xul:browser&gt;</code></li> <li><code>&lt;xul:browser type="chrome"&gt;</code></li> <li><code>&lt;xul:browser type="rabid_dog"&gt;</code></li> <li><code>&lt;xul:iframe type="foofy"&gt;</code></li> <li><code>&lt;html:iframe&gt;</code></li> <li><code>&lt;html:iframe type="content"&gt;</code></li>
</ul>
<p>The following would not create trusted windows:</p>
<ul> <li><code>&lt;xul:browser type="content"&gt;</code></li> <li><code>&lt;xul:iframe type="content-primary"&gt;</code></li>
</ul>
<p>Further note that any child window of an untrusted window is automatically untrusted.</p>
<h5 id="What_happens_when_a_script_accesses_an_object.3F" name="What_happens_when_a_script_accesses_an_object.3F">What happens when a script accesses an object?</h5>
<p>The table below describes what happens when a script accesses an object, and how the wrapper is involved.</p>
<table> <tbody> <tr> <th>Script</th> <th>Object</th> <th>Effects</th> </tr> <tr> <td>Protected</td> <td>Trusted</td> <td>No wrapper is created and therefore the script gets full access to the object.</td> </tr> <tr> <td>Protected</td> <td>Untrusted</td> <td>An <a href="#Explicit_vs._Implicit">implicit</a> <a href="#Deep_vs._Shallow">deep</a> <code>XPCNativeWrapper</code> is created.</td> </tr> <tr> <td>Unprotected</td> <td>Trusted</td> <td>No wrapper is created, just as in the protected/trusted case.</td> </tr> <tr> <td>Unprotected</td> <td>Untrusted</td> <td>No wrapper is created, just as in the protected/trusted case.</td> </tr> </tbody>
</table>
<h4 id="XPCNativeWrapper_constructor_call_with_string_arguments" name="XPCNativeWrapper_constructor_call_with_string_arguments"><code>XPCNativeWrapper</code> constructor call with string arguments</h4>
<p>For example:</p>
<pre class="eval">var contentWinWrapper = new XPCNativeWrapper(content,
                                             "document");
</pre>
<p>This creates an <a href="#Explicit_vs._Implicit">explicit</a> <a href="#Deep_vs._Shallow">shallow</a> <code>XPCNativeWrapper</code>. This syntax has been kept for compatibility with versions prior to Firefox 1.5. While all properties of the <code>contentWinWrapper</code> 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 <code>XPCNativeWrapper</code> is <a href="#Deep_vs._Shallow">shallow</a>. So to compare the content document title to the current content selection, one must do:</p>
<pre class="eval">var winWrapper = new XPCNativeWrapper(content, "document",
                                      "getSelection()");
var docWrapper = new XPCNativeWrapper(winWrapper.document,
                                      "title");
return docWrapper.title == winWrapper.getSelection();
</pre>
<p>just like in versions before Firefox 1.5. Note that the <code>"getSelection()"</code> 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 <code>XPCNativeWrapper</code>.</p>
<h4 id="XPCNativeWrapper_constructor_call_with_no_string_arguments" name="XPCNativeWrapper_constructor_call_with_no_string_arguments"><code>XPCNativeWrapper</code> constructor call with no string arguments</h4>
<p>For example:</p>
<pre class="eval">var contentWinWrapper = new XPCNativeWrapper(content);
</pre>
<p>This creates an <a href="#Explicit_vs._Implicit">explicit</a> <a href="#Deep_vs._Shallow">deep</a> <code>XPCNativeWrapper</code>. Accessing properties of this <code>XPCNativeWrapper</code> is safe, and the return values will also be wrapped in <a href="#Explicit_vs._Implicit">explicit</a> <a href="#Deep_vs._Shallow">deep</a> <code>XPCNativeWrapper</code> objects.</p>
<h3 id="Setting_.22expando.22_properties_on_XPCNativeWrapper" name="Setting_.22expando.22_properties_on_XPCNativeWrapper">Setting "expando" properties on <code>XPCNativeWrapper</code></h3>
<p>It is possible to set "expando" properties (properties with names that don't correspond to IDL-defined properties) on <code>XPCNativeWrapper</code> objects. If this is done, then chrome will be able to see these expando properties, but content will not be able to. <strong>There is no safe way to set an expando property from chrome and have it be readable from content.</strong></p>
<h3 id="XPCNativeWrapper_lifetime" name="XPCNativeWrapper_lifetime"><code>XPCNativeWrapper</code> lifetime</h3>
<p>Explicit <code>XPCNativeWrapper</code> objects exist while they are referenced. Creating a new explicit <code>XPCNativeWrapper</code> for the same possibly-unsafe object will create a new wrapper object; something to watch out for when <a href="#Setting_.22expando.22_properties_on_XPCNativeWrapper">setting "expando" properties</a></p>
<p>Implicit <code>XPCNativeWrapper</code> objects have the same lifetime as the object they're wrapping.</p>
<h3 id="Accessing_unsafe_properties" name="Accessing_unsafe_properties">Accessing unsafe properties</h3>
<p>If unsafe access to a property is required for some reason, this can be accomplished via the <code>wrappedJSObject</code> property of the wrapper. For example, if <code>docWrapper</code> is a wrapper for <code>doc</code>, then</p>
<pre class="eval">docWrapper.wrappedJSObject.prop
</pre>
<p>is the same as</p>
<pre class="eval">doc.prop
</pre>
<h3 id=".D0.98.D0.B7.D0.B2.D0.B5.D1.81.D1.82.D0.BD.D1.8B.D0.B5_.D0.BE.D1.88.D0.B8.D0.B1.D0.BA.D0.B8" name=".D0.98.D0.B7.D0.B2.D0.B5.D1.81.D1.82.D0.BD.D1.8B.D0.B5_.D0.BE.D1.88.D0.B8.D0.B1.D0.BA.D0.B8">Известные ошибки</h3>
<p>Известны две ошибки реализации <code>XPCNativeWrapper</code> в версиях 1.5.0.x:</p>
<ol> <li>Firefox с версии 1.5 по версию 1.5.0.4 содержит {{ Bug(337095) }}, в результате чего в некоторых случаях для защищённых скриптов не создаются обёртки. А именно, если из защищённого скрипта происходит обращение к свойству или вызов функции, которые возвращают недоверенный (<span>untrusted</span>) объект, обёртка будет создана. Однако, если функция в защищённом скрипте вызывается из C++, и в качестве аргумента этой функции передаётся недоверенный объект, обёртка <em>не</em> будет создана. Поэтому функции, которые могут быть вызваны подобным образом, <a href="#XPCNativeWrapper_constructor_call_with_no_string_arguments">должны сами производить обёртывание</a>. Эта ошибка исправлена в Firefox версии 1.5.0.5 и выше.</li> <li>Firefox с версии 1.5 по версию 1.5.0.5 содержит {{ Bug(345991) }}, в результате чего компоненты написанные на JavaScript не могут быть защищёнными скриптами. Эта ошибка исправлена в Firefox версии 1.5.0.6 и выше.</li>
</ol>
<h3 id="Limitations_of_XPCNativeWrapper" name="Limitations_of_XPCNativeWrapper">Limitations of <code>XPCNativeWrapper</code></h3>
<p>There are some commonly used properties and coding styles that cannot be used with <code>XPCNativeWrapper</code>. Specifically:</p>
<ol> <li>Assigning to or reading an <code>on*</code> property on an <code>XPCNativeWrapper</code> of a DOM node or Window object will throw an exception. (Use addEventListener instead, and use "event.preventDefault();" in your handler if you used "return false;" before.)</li> <li>Access to frames by window name (e.g. <code>window.frameName</code>) does not work on an <code>XPCNativeWrapper</code></li> <li><code>document.all</code> does not work on an <code>XPCNativeWrapper</code> for a document.</li> <li>Access to named items by name does not work on an <code>XPCNativeWrapper</code> for an HTML document. For example, if you have a <code>&lt;form name="foo"&gt;</code> and <code>docWrapper</code> is a wrapper for the HTML document <code>doc</code> then <code>doc.foo</code> is an <code>HTMLFormElement</code> while <code>docWrapper.foo</code> is <code>undefined</code>. Code that wishes to do this could use <code>docWrapper.forms.namedItem("foo")</code> instead.</li> <li>Access to nodes by id doesn't work on an <code>XPCNativeWrapper</code> for an HTML document. <code>getElementById</code> should be used instead.</li> <li>Access to inputs by name doesn't work on an <code>XPCNativeWrapper</code> for an HTML form. Code that wishes to do this should use <code>form.elements.namedItem("inputname")</code>.</li> <li>Access to elements by name doesn't work on an <code>XPCNativeWrapper</code> for an <code>HTMLCollection</code>. Code that wishes to do this should use the <code>namedItem()</code> method. Note that <code>namedItem</code> only returns the first input element with the name, even if there are multiple elements (e.g. radio buttons) with the same name in the form.</li> <li>Calling methods implemented by NPAPI plugins through the <code>XPCNativeWrapper</code> for the corresponding node does not work.</li> <li>Getting or setting properties implemented by NPAPI plugins though the <code>XPCNativeWrapper</code> for the corresponding node does not work.</li> <li>Calling methods implemented via XBL bindings attached to a node through an <code>XPCNativeWrapper</code> for that node does not work.</li> <li>Getting or setting properties implemented via XBL bindings attached to a node through an <code>XPCNativeWrapper</code> for that node does not work.</li> <li>Enumerating the properties of an <code>XPCNativeWrapper</code> via "<code>for (var p in wrapper)</code>" does not enumerate the IDL-defined properties.</li> <li>Object.prototype is not on the prototype chain of an <code>XPCNativeWrapper</code>. As a result, various <code>Object.prototype</code> properties are undefined on an <code>XPCNativeWrapper</code> (to be precise, these are <code>__proto__</code>, <code>__parent__</code>, <code>__count__</code>, <code>toSource</code>, <code>toLocaleString</code>, <code>valueOf</code>, <code>watch</code>, <code>unwatch</code>, <code>hasOwnProperty</code>, <code>isPrototypeOf</code>, <code>propertyIsEnumerable</code>, <code>__defineGetter__</code>, <code>__defineSetter__</code>, <code>__lookupGetter__</code>, and <code>__lookupSetter__</code>).</li> <li>There is no support for the <code>importXPCNative</code> method the old <code>XPCNativeWrapper</code> implementation used to have.</li> <li>Accessing standard classes (such as <code>Function</code>) through an XPCNativeWrapper will not work. To create functions and objects with a particular window's parent, use that window's <code>eval</code> function.</li>
</ol>
<p><a class="external" href="http://oreillynet.com/pub/a/network/2005/11/01/avoid-common-greasemonkey-pitfalls.html?page=3">Avoid Common Pitfalls in Greasemonkey</a> has an elaborate explanation for some of these limitations (in context of Greasemonkey scripts).</p>
<p>{{ languages( { "en": "en/XPCNativeWrapper", "fr": "fr/XPCNativeWrapper", "it": "it/XPCNativeWrapper" } ) }}</p>