dom/xbl/test/file_bug821850.xhtml

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 <html xmlns="http://www.w3.org/1999/xhtml">
     2 <!--
     3 https://bugzilla.mozilla.org/show_bug.cgi?id=821850
     4 -->
     5 <head>
     6   <bindings xmlns="http://www.mozilla.org/xbl">
     7     <binding id="testBinding">
     8       <implementation>
     9         <constructor>
    10           // Store a property as an expando on the bound element.
    11           this._prop = "propVal";
    13           // Wait for both constructors to fire.
    14           window.constructorCount = (window.constructorCount + 1) || 1;
    15           if (window.constructorCount != 2)
    16             return;
    18           // Grab some basic infrastructure off the content window.
    19           var win = XPCNativeWrapper.unwrap(window);
    20           SpecialPowers = win.SpecialPowers;
    21           Cu = SpecialPowers.Cu;
    22           is = win.is;
    23           ok = win.ok;
    24           SimpleTest = win.SimpleTest;
    26           // Stick some expandos on the content window.
    27           window.xrayExpando = 3;
    28           win.primitiveExpando = 11;
    29           win.stringExpando = "stringExpando";
    30           win.objectExpando = { foo: 12 };
    31           win.globalExpando = SpecialPowers.unwrap(Cu.getGlobalForObject({}));
    32           win.functionExpando = function() { return "called" };
    33           win.functionExpando.prop = 2;
    35           // Make sure we're Xraying.
    36           ok(Cu.isXrayWrapper(window), "Window is Xrayed");
    37           ok(Cu.isXrayWrapper(document), "Document is Xrayed");
    39           var bound = document.getElementById('bound');
    40           ok(bound, "bound is non-null");
    41           is(bound.method('baz'), "method:baz", "Xray methods work");
    42           is(bound.prop, "propVal", "Property Xrays work");
    43           is(bound.primitiveField, undefined, "Xrays don't show fields");
    44           is(bound.wrappedJSObject.primitiveField, 2, "Waiving Xrays show fields");
    46           // Check exposure behavior.
    47           is(typeof bound.unexposedMethod, 'function',
    48              "Unexposed method should be visible to XBL");
    49           is(typeof bound.wrappedJSObject.unexposedMethod, 'undefined',
    50              "Unexposed method should not be defined in content");
    51           is(typeof bound.unexposedProperty, 'number',
    52              "Unexposed property should be visible to XBL");
    53           is(typeof bound.wrappedJSObject.unexposedProperty, 'undefined',
    54              "Unexposed property should not be defined in content");
    56           // Check that here HTMLImageElement.QueryInterface works
    57           var img = document.querySelector("img");
    58           ok("QueryInterface" in img,
    59              "Should have a img.QueryInterface here");
    60           is(img.QueryInterface(Components.interfaces.nsIImageLoadingContent),
    61              img, "Should be able to QI the image");
    63           // Make sure standard constructors work right in the presence of
    64           // sandboxPrototype and Xray-resolved constructors.
    65           is(window.Function, XPCNativeWrapper(window.wrappedJSObject.Function),
    66              "window.Function comes from the window, not the global");
    67           ok(Function != window.Function, "Function constructors are distinct");
    68           is(Object.getPrototypeOf(Function.prototype), Object.getPrototypeOf({foo: 42}),
    69              "Function constructor is local");
    71           // This gets invoked by an event handler.
    72           window.finish = function() {
    73             // Content messed with stuff. Make sure we still see the right thing.
    74             is(bound.method('bay'), "method:bay", "Xray methods work");
    75             is(bound.wrappedJSObject.method('bay'), "hah", "Xray waived methods work");
    76             is(bound.prop, "set:someOtherVal", "Xray props work");
    77             is(bound.wrappedJSObject.prop, "redefined", "Xray waived props work");
    78             is(bound.wrappedJSObject.primitiveField, 321, "Can't do anything about redefined fields");
    80             SimpleTest.finish();
    81           }
    83           // Hand things off to content. Content will call us back.
    84           win.go();
    85         </constructor>
    86         <field name="primitiveField">2</field>
    87         <method name="unexposedMethod"><body></body></method>
    88         <property name="unexposedProperty" onget="return 2;" readonly="true"></property>
    89         <method name="method" exposeToUntrustedContent="true">
    90           <parameter name="arg" />
    91           <body>
    92             return "method:" + arg;
    93           </body>
    94         </method>
    95         <method name="passMeAJSObject" exposeToUntrustedContent="true">
    96           <parameter name="arg" />
    97           <body>
    98             is(typeof arg.prop, 'undefined', "No properties");
    99             is(Object.getOwnPropertyNames(arg).length, 0, "Should have no own properties");
   100             try {
   101               arg.foo = 2;
   102               ok(true, "Stuff fails silently");
   103             } catch (e) {
   104               ok(false, "Stuff should fail silently");
   105             }
   106             is(typeof arg.foo, 'undefined', "Shouldn't place props");
   107           </body>
   108         </method>
   109         <property name="prop" exposeToUntrustedContent="true">
   110           <getter>return this._prop;</getter>
   111           <setter>this._prop = "set:" + val;</setter>
   112         </property>
   113       </implementation>
   114       <handlers>
   115         <handler event="testevent" action="ok(true, 'called event handler'); finish();" allowuntrusted="true"/>
   116         <handler event="testtrusted" action="ok(true, 'called trusted handler'); window.wrappedJSObject.triggeredTrustedHandler = true;"/>
   117         <handler event="keyup" action="ok(true, 'called untrusted key handler'); window.wrappedJSObject.triggeredUntrustedKeyHandler = true;" allowuntrusted="true"/>
   118         <handler event="keydown" action="ok(true, 'called trusted key handler'); window.wrappedJSObject.triggeredTrustedKeyHandler = true;"/>
   119       </handlers>
   120     </binding>
   121   </bindings>
   122   <script type="application/javascript">
   123   <![CDATA[
   125   ok = parent.ok;
   126   is = parent.is;
   127   SimpleTest = parent.SimpleTest;
   128   SpecialPowers = parent.SpecialPowers;
   130   // Test the Xray waiving behavior when accessing fields. We should be able to
   131   // see sequential JS-implemented properties, but should regain Xrays when we
   132   // hit a native property.
   133   window.contentVal = { foo: 10, rabbit: { hole: { bar: 100, win: window} } };
   134   ok(true, "Set contentVal");
   136   // Check that we're not exposing QueryInterface to non-XBL code
   137   ok(!("QueryInterface" in document),
   138      "Should not have a document.QueryInterface here");
   140   function go() {
   141     "use strict";
   143     // Test what we can and cannot access in the XBL scope.
   144     is(typeof window.xrayExpando, "undefined", "Xray expandos are private to the caller");
   145     is(window.primitiveExpando, 11, "Can see waived expandos");
   146     is(window.stringExpando, "stringExpando", "Can see waived expandos");
   147     is(typeof window.objectExpando, "object", "object expando exists");
   148     checkThrows(function() window.objectExpando.foo);
   149     is(SpecialPowers.wrap(window.objectExpando).foo, 12, "SpecialPowers sees the right thing");
   150     is(typeof window.globalExpando, "object", "Can see global object");
   151     checkThrows(function() window.globalExpando.win);
   152     is(window.functionExpando(), "called", "XBL functions are callable");
   153     checkThrows(function() window.functionExpando.prop);
   155     // Inspect the bound element.
   156     var bound = document.getElementById('bound');
   157     is(bound.primitiveField, 2, "Can see primitive fields");
   158     is(bound.method("foo"), "method:foo", "Can invoke XBL method from content");
   159     is(bound.prop, "propVal", "Can access properties from content");
   160     bound.prop = "someOtherVal";
   161     is(bound.prop, "set:someOtherVal", "Can set properties from content");
   163     // Make sure we can't pass JS objects to the XBL scope.
   164     var proto = bound.__proto__;
   165     proto.passMeAJSObject({prop: 2});
   167     //
   168     // Try sticking a bunch of stuff on the prototype object.
   169     //
   171     proto.someExpando = 201;
   172     is(bound.someExpando, 201, "Can stick non-XBL properties on the proto");
   174     // Previously, this code checked that content couldn't tamper with its XBL
   175     // prototype. But we decided to allow this to reduce regression risk, so for
   176     // now just check that this works.
   177     function checkMayTamper(obj, propName, desc) {
   178       var accessor = !('value' in Object.getOwnPropertyDescriptor(obj, propName));
   179       if (!accessor)
   180         checkAllowed(function() { obj[propName] = function() {} }, desc + ": assign");
   181       checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true, value: 3}) }, desc + ": define with value");
   182       checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true, writable: true}) }, desc + ": make writable");
   183       checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true}) }, desc + ": make configurable");
   184       checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true, get: function() {}}) }, desc + ": define with getter");
   185       checkAllowed(function() { Object.defineProperty(obj, propName, {configurable: true, set: function() {}}) }, desc + ": define with setter");
   187       // Windows are implemented as proxies, and Proxy::delete_ doesn't currently
   188       // pass strict around. Work around it in the window.binding case by just
   189       // checking if delete returns false.
   190       // manually.
   191       checkAllowed(function() { delete obj[propName]; }, desc + ": delete");
   193       if (!accessor)
   194         checkAllowed(function() { obj[propName] = function() {} }, desc + ": assign (again)");
   195     }
   197     // Make sure content can do whatever it wants with the prototype.
   198     checkMayTamper(proto, 'method', "XBL Proto Method");
   199     checkMayTamper(proto, 'prop', "XBL Proto Prop");
   200     checkMayTamper(proto, 'primitiveField', "XBL Field Accessor");
   202     // Tamper with the derived object. This doesn't affect the XBL scope thanks
   203     // to Xrays.
   204     bound.method = function() { return "heh"; };
   205     Object.defineProperty(bound, 'method', {value: function() { return "hah" }});
   206     Object.defineProperty(bound, 'prop', {value: "redefined"});
   207     bound.primitiveField = 321;
   209     // We need a chrome window to create trusted events. This isn't really doable
   210     // in child processes, so let's just skip if that's the case.
   211     if (SpecialPowers.isMainProcess()) {
   212       var Ci = SpecialPowers.Ci;
   213       var chromeWin = SpecialPowers.wrap(window.top)
   214                                    .QueryInterface(Ci.nsIInterfaceRequestor)
   215                                    .getInterface(Ci.nsIWebNavigation)
   216                                    .QueryInterface(Ci.nsIDocShell)
   217                                    .chromeEventHandler.ownerDocument.defaultView;
   219       // Untrusted events should not trigger event handlers without
   220       // exposeToUntrustedContent=true.
   221       window.triggeredTrustedHandler = false;
   222       var untrustedEvent = new CustomEvent('testtrusted');
   223       ok(!untrustedEvent.isTrusted, "Created an untrusted event");
   224       is(untrustedEvent.type, 'testtrusted', "Constructor should see type");
   225       bound.dispatchEvent(untrustedEvent);
   226       ok(!window.triggeredTrustedHandler, "untrusted events should not trigger trusted handler");
   227       var trustedEvent = new chromeWin.CustomEvent('testtrusted');
   228       ok(trustedEvent.isTrusted, "Created a trusted event");
   229       is(trustedEvent.type, 'testtrusted', "Wrapped constructor should see type");
   230       SpecialPowers.wrap(bound).dispatchEvent(trustedEvent);
   231       ok(window.triggeredTrustedHandler, "trusted events should trigger trusted handler");
   233       //
   234       // We check key events as well, since they're implemented differently.
   235       //
   236       // NB: We don't check isTrusted on the events we create here, because
   237       // according to smaug, old-style event initialization doesn't mark the
   238       // event as trusted until it's dispatched.
   239       //
   241       window.triggeredUntrustedKeyHandler = false;
   242       window.triggeredTrustedKeyHandler = false;
   244       // Untrusted event, permissive handler.
   245       var untrustedKeyEvent = document.createEvent('KeyboardEvent');
   246       untrustedKeyEvent.initEvent('keyup', true, true);
   247       bound.dispatchEvent(untrustedKeyEvent);
   248       ok(window.triggeredUntrustedKeyHandler, "untrusted key events should trigger untrusted handler");
   250       // Untrusted event, strict handler.
   251       var fakeTrustedKeyEvent = document.createEvent('KeyboardEvent');
   252       fakeTrustedKeyEvent.initEvent('keydown', true, true);
   253       bound.dispatchEvent(fakeTrustedKeyEvent);
   254       ok(!window.triggeredTrustedKeyHandler, "untrusted key events should not trigger trusted handler");
   256       // Trusted event, strict handler.
   257       var trustedKeyEvent = chromeWin.document.createEvent('KeyboardEvent');
   258       trustedKeyEvent.initEvent('keydown', true, true);
   259       SpecialPowers.wrap(bound).dispatchEvent(trustedKeyEvent);
   260       ok(window.triggeredTrustedKeyHandler, "trusted key events should trigger trusted handler");
   261     }
   263     // Hand control back to the XBL scope by dispatching an event on the bound element.
   264     bound.dispatchEvent(new CustomEvent('testevent'));
   265   }
   267   function checkThrows(fn) {
   268     try { fn(); ok(false, "Should have thrown"); }
   269     catch (e) { ok(!!/denied|insecure/.exec(e), "Should have thrown security exception: " + e); }
   270   }
   272   function checkAllowed(fn, desc) {
   273     try { fn(); ok(true, desc + ": Didn't throw"); }
   274     catch (e) { ok(false, desc + ": Threw: " + e); }
   275   }
   277   function setup() {
   278     // When the bindings are applied, the constructor will be invoked and the
   279     // test will continue.
   280     document.getElementById('bound').style.MozBinding = 'url(#testBinding)';
   281     document.getElementById('bound2').style.MozBinding = 'url(#testBinding)';
   282   }
   284   ]]>
   285 </script>
   286 </head>
   287 <body onload="setup()">
   288 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=821850">Mozilla Bug 821850</a>
   289 <p id="display"></p>
   290 <div id="content">
   291   <div id="bound">Bound element</div>
   292   <div id="bound2">Bound element</div>
   293   <img/>
   294 </div>
   295 <pre id="test">
   296 </pre>
   297 </body>
   298 </html>

mercurial