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.

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

mercurial