js/xpconnect/tests/chrome/test_cows.xul

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 <?xml version="1.0"?>
michael@0 2 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
michael@0 3 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
michael@0 4 type="text/css"?>
michael@0 5 <!--
michael@0 6 https://bugzilla.mozilla.org/show_bug.cgi?id=500931
michael@0 7 -->
michael@0 8 <window title="Mozilla Bug 522764"
michael@0 9 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
michael@0 10 <script type="application/javascript"
michael@0 11 src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
michael@0 12
michael@0 13 <!-- test results are displayed in the html:body -->
michael@0 14 <body xmlns="http://www.w3.org/1999/xhtml">
michael@0 15 <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=522764 "
michael@0 16 target="_blank">Mozilla Bug 522764 </a>
michael@0 17 </body>
michael@0 18
michael@0 19 <!-- test code goes here -->
michael@0 20 <script type="application/javascript"><![CDATA[
michael@0 21 const Ci = Components.interfaces;
michael@0 22 const Cu = Components.utils;
michael@0 23
michael@0 24 var sandbox = new Cu.Sandbox("about:blank");
michael@0 25
michael@0 26 var test_utils = window.QueryInterface(Ci.nsIInterfaceRequestor).
michael@0 27 getInterface(Ci.nsIDOMWindowUtils);
michael@0 28
michael@0 29 function getCOW(x) {
michael@0 30 if (typeof x != 'object' && typeof x != 'function')
michael@0 31 return x;
michael@0 32 var rval = {};
michael@0 33 if (typeof x == "function")
michael@0 34 rval = eval(uneval(x));
michael@0 35 for (var i in x) {
michael@0 36 if (x.__lookupGetter__(i))
michael@0 37 rval.__defineGetter__(i, eval(uneval(x.__lookupGetter__(i))))
michael@0 38 else
michael@0 39 rval[i] = getCOW(x[i]);
michael@0 40 }
michael@0 41 return rval;
michael@0 42 }
michael@0 43
michael@0 44 // Give the sandbox a way to create ChromeObjectWrapped objects.
michael@0 45 sandbox.getCOW = getCOW;
michael@0 46
michael@0 47 // Define test API functions in the sandbox.
michael@0 48 const TEST_API = ['is', 'isnot', 'ok', 'todo_is', 'todo_isnot', 'todo'];
michael@0 49 TEST_API.forEach(function(name) { sandbox[name] = window[name]; });
michael@0 50
michael@0 51 sandbox.alienObject = {
michael@0 52 __exposedProps__: {funProp: 'r'},
michael@0 53 funProp: function foo(x) {
michael@0 54 return x + 1;
michael@0 55 }
michael@0 56 };
michael@0 57
michael@0 58 sandbox.chromeGet = function (obj, prop) { return obj[prop]; };
michael@0 59
michael@0 60 function COWTests() {
michael@0 61 // This function is actually decompiled and run inside a
michael@0 62 // sandbox with content privileges.
michael@0 63
michael@0 64 // TODO: This could use some refactoring; creating helper
michael@0 65 // functions like assertIsWritable(myObj, 'someproperty') might
michael@0 66 // be useful.
michael@0 67
michael@0 68 function isProp(obj, propName, value, desc) {
michael@0 69 try {
michael@0 70 is(obj[propName], value, "getting " + propName + " on " + desc);
michael@0 71 ok(propName in obj,
michael@0 72 propName + " on " + desc + " should exist");
michael@0 73 ok(Object.hasOwnProperty.call(obj, propName),
michael@0 74 propName + " on " + desc + " should exist");
michael@0 75 } catch (e) {
michael@0 76 ok(false, "getting " + propName + " on " + desc + " threw " + e);
michael@0 77 }
michael@0 78 }
michael@0 79 function isPropHidden(obj, propName, desc) {
michael@0 80 try {
michael@0 81 is(obj[propName], undefined,
michael@0 82 "getting " + propName + " on " + desc + " should return undefined");
michael@0 83 ok(!(propName in obj),
michael@0 84 propName + " on " + desc + " should act as if it doesn't exist");
michael@0 85 ok(!Object.hasOwnProperty.call(obj, propName),
michael@0 86 propName + " on " + desc + " should act as if it doesn't exist");
michael@0 87 } catch (e) {
michael@0 88 ok(false, "getting " + propName + " on " + desc + " threw " + e);
michael@0 89 }
michael@0 90 }
michael@0 91
michael@0 92 const PROPS_TO_TEST = ['foo', 'bar', 'prototype'];
michael@0 93
michael@0 94 var empty = {};
michael@0 95 var nonempty = {foo: 42, bar: 33};
michael@0 96 is(getCOW(empty).foo, undefined,
michael@0 97 "shouldn't throw when accessing exposed properties that doesn't exist");
michael@0 98
michael@0 99 PROPS_TO_TEST.forEach(function(name) {
michael@0 100 isPropHidden(getCOW(nonempty), name, "object without exposedProps");
michael@0 101 });
michael@0 102
michael@0 103 // Test function objects without __exposedProps__
michael@0 104 var func = function(x) { return 42; };
michael@0 105 func.foo = "foo property";
michael@0 106 var funcCOW = getCOW(func);
michael@0 107 PROPS_TO_TEST.forEach(function(name) {
michael@0 108 isPropHidden(funcCOW, name, "function without exposedProps");
michael@0 109 });
michael@0 110 is([name for (name in funcCOW)].length, 0,
michael@0 111 "function without exposedProps shouldn't have any properties");
michael@0 112 is(funcCOW(), 42, "COW without exposedProps should still be callable");
michael@0 113
michael@0 114 // Test function objects with __exposedProps__
michael@0 115 var func = function(x) { return 42; };
michael@0 116 func.foo = "foo property";
michael@0 117 func.__exposedProps__ = { foo: "r" };
michael@0 118 var funcCOWr = getCOW(func);
michael@0 119 PROPS_TO_TEST.forEach(function(name) {
michael@0 120 if (name == "foo") {
michael@0 121 isProp(funcCOWr, name, "foo property",
michael@0 122 "function with exposedProps");
michael@0 123 }
michael@0 124 else {
michael@0 125 isPropHidden(funcCOWr, name, "function with exposedProps");
michael@0 126 }
michael@0 127 });
michael@0 128 is([name for (name in funcCOWr)].length, 1,
michael@0 129 "function with exposedProps should only enumerate exposed props");
michael@0 130 is([name for (name in funcCOWr)][0], "foo",
michael@0 131 "function with exposedProps should only enumerate exposed props");
michael@0 132 is(funcCOWr(), 42, "COW with exposedProps should be callable");
michael@0 133
michael@0 134 // Test function objects with __exposedProps__
michael@0 135 var func = function(x) { return 42; };
michael@0 136 func.foo = "foo property";
michael@0 137 func.__exposedProps__ = { foo: "r", bar: "r" };
michael@0 138 var funcCOWr2 = getCOW(func);
michael@0 139 PROPS_TO_TEST.forEach(function(name) {
michael@0 140 if (name == "foo") {
michael@0 141 isProp(funcCOWr2, name, "foo property",
michael@0 142 "function with more exposedProps");
michael@0 143 }
michael@0 144 else {
michael@0 145 isPropHidden(funcCOWr2, name, "function with more exposedProps");
michael@0 146 }
michael@0 147 });
michael@0 148 is([name for (name in funcCOWr2)].length, 1,
michael@0 149 "function with exposedProps should only enumerate exposed props");
michael@0 150 is([name for (name in funcCOWr2)][0], "foo",
michael@0 151 "function with exposedProps should only enumerate exposed props");
michael@0 152
michael@0 153 // Test object with empty exposedProps
michael@0 154 var strict = { __exposedProps__: {}, foo: "foo property" };
michael@0 155 var strictCOW = getCOW(strict);
michael@0 156 PROPS_TO_TEST.forEach(function(name) {
michael@0 157 isPropHidden(strictCOW, name, "object with empty exposedProps");
michael@0 158 });
michael@0 159 is([name for (name in strictCOW)].length, 0,
michael@0 160 "object with empty exposedProps shouldn't have any properties");
michael@0 161
michael@0 162 // Test object with one exposed property
michael@0 163 var strict = { __exposedProps__: { foo: "r" }, foo: "foo property" };
michael@0 164 var strictCOWr = getCOW(strict);
michael@0 165 PROPS_TO_TEST.forEach(function(name) {
michael@0 166 if (name == "foo") {
michael@0 167 isProp(strictCOWr, name, "foo property",
michael@0 168 "object with exposed 'foo'");
michael@0 169 }
michael@0 170 else {
michael@0 171 isPropHidden(strictCOW, name, "object with exposed 'foo'");
michael@0 172 }
michael@0 173 });
michael@0 174 is([name for (name in strictCOWr)].length, 1,
michael@0 175 "object with exposedProps only enumerate exposed props");
michael@0 176 is([name for (name in strictCOWr)][0], "foo",
michael@0 177 "object with exposedProps only enumerate exposed props");
michael@0 178
michael@0 179 // Test writable property
michael@0 180 var writable = getCOW({ __exposedProps__: {foo: 'w'}});
michael@0 181 try {
michael@0 182 ok(!("foo" in writable),
michael@0 183 "non-existing write-only property shouldn't exist");
michael@0 184 writable.foo = 5;
michael@0 185 is(chromeGet(writable, "foo"), 5, "writing to a write-only exposed prop works");
michael@0 186 todo("foo" in writable,
michael@0 187 "existing write-only property should exist");
michael@0 188 } catch (e) {
michael@0 189 ok(false, "writing to a write-only exposed prop shouldn't throw " + e);
michael@0 190 }
michael@0 191 try {
michael@0 192 writable.foo;
michael@0 193 todo(false, "reading from a write-only exposed prop should throw");
michael@0 194 } catch (e) {
michael@0 195 todo(/Permission denied/.test(e),
michael@0 196 "reading from a write-only exposed prop should throw");
michael@0 197 }
michael@0 198 try {
michael@0 199 delete writable.foo;
michael@0 200 is(chromeGet(writable, "foo"), undefined,
michael@0 201 "deleting a write-only exposed prop works");
michael@0 202 } catch (e) {
michael@0 203 ok(false, "deleting a write-only exposed prop shouldn't throw " + e);
michael@0 204 }
michael@0 205
michael@0 206 // Test readable property
michael@0 207 var readable = { __exposedProps__: {foo: 'r'},
michael@0 208 foo: 5,
michael@0 209 bar: 6 };
michael@0 210 try {
michael@0 211 isProp(getCOW(readable), "foo", 5,
michael@0 212 "reading from a readable exposed prop works");
michael@0 213 } catch (e) {
michael@0 214 ok(false, "reading from a readable exposed prop shouldn't throw " + e);
michael@0 215 }
michael@0 216 try {
michael@0 217 getCOW(readable).foo = 1;
michael@0 218 ok(false, "writing to a read-only exposed prop should fail");
michael@0 219 } catch (e) {
michael@0 220 ok(/Permission denied/.test(e),
michael@0 221 "writing to a read-only exposed prop should fail");
michael@0 222 }
michael@0 223 try {
michael@0 224 delete getCOW(readable).foo;
michael@0 225 ok(false, "deleting a read-only exposed prop shouldn't work");
michael@0 226 } catch (e) {
michael@0 227 ok(/Permission denied/.test(e),
michael@0 228 "deleting a read-only exposed prop should throw error");
michael@0 229 }
michael@0 230
michael@0 231 try {
michael@0 232 var props = [name for (name in getCOW(readable))];
michael@0 233 is(props.length, 1, "COW w/ one exposed prop should enumerate once");
michael@0 234 is(props[0], 'foo', "COW w/ one exposed prop should enumerate it");
michael@0 235 } catch (e) {
michael@0 236 ok(false, "COW w/ a readable prop should not raise exc " +
michael@0 237 "on enumeration: " + e);
michael@0 238 }
michael@0 239
michael@0 240 // Test read/write property
michael@0 241 var readwrite = getCOW({ __exposedProps__: {foo: 'rw'}});
michael@0 242 try {
michael@0 243 ok(!("foo" in readwrite),
michael@0 244 "non-existing readwrite property shouldn't exist");
michael@0 245 readwrite.foo = 5;
michael@0 246 is(readwrite.foo, 5, "writing to a readwrite exposed prop looks like it worked");
michael@0 247 is(chromeGet(readwrite, "foo"), 5, "writing to a readwrite exposed prop works");
michael@0 248 ok("foo" in readwrite,
michael@0 249 "existing readwrite property should exist");
michael@0 250 } catch (e) {
michael@0 251 ok(false, "writing to a readwrite exposed prop shouldn't throw " + e);
michael@0 252 }
michael@0 253 try {
michael@0 254 delete readwrite.foo;
michael@0 255 is(readwrite.foo, undefined, "deleting readwrite prop looks like it worked");
michael@0 256 ok(!("foo" in readwrite), "deleting readwrite prop looks like it really worked");
michael@0 257 is(chromeGet(readwrite, "foo"), undefined,
michael@0 258 "deleting a readwrite exposed prop works");
michael@0 259 } catch (e) {
michael@0 260 ok(false, "deleting a readwrite exposed prop shouldn't throw " + e);
michael@0 261 }
michael@0 262
michael@0 263 // Readables and functions
michael@0 264 try {
michael@0 265 var COWFunc = getCOW((function() { return 5; }));
michael@0 266 is(COWFunc(), 5, "COWed functions should be callable");
michael@0 267 } catch (e) {
michael@0 268 todo(false, "COWed functions should not raise " + e);
michael@0 269 }
michael@0 270 try {
michael@0 271 var objWithFunc = {__exposedProps__: {foo: 'r'},
michael@0 272 foo: function foo() { return 5; }};
michael@0 273 is(getCOW((objWithFunc)).foo(), 5,
michael@0 274 "Readable function exposed props should be callable");
michael@0 275 } catch (e) {
michael@0 276 ok(false, "Readable function exposed props should be callable" + e);
michael@0 277 }
michael@0 278
michael@0 279 // Readables with getters
michael@0 280 var obj = {
michael@0 281 get prop() { return { __exposedProps__: {}, test: "FAIL" } },
michael@0 282 __exposedProps__: {prop: 'r'}
michael@0 283 };
michael@0 284 is(getCOW(obj).prop.test, undefined, "getting prop.test shouldn't return anything");
michael@0 285 ok(!("test" in getCOW(obj).prop), "getting prop.test shouldn't return anything");
michael@0 286
michael@0 287 // Alien objects
michael@0 288 try {
michael@0 289 is(alienObject.funProp(1), 2,
michael@0 290 "COWs wrapping objects from different principals should work");
michael@0 291 } catch (e) {
michael@0 292 ok(false, "COWs wrapping objs from different principals " +
michael@0 293 "shouldn't throw " + e);
michael@0 294 }
michael@0 295
michael@0 296 try {
michael@0 297 is(alienObject.funProp(1), 2,
michael@0 298 "COWs wrapping objs from different principals should work twice");
michael@0 299 } catch (e) {
michael@0 300 ok(false, "COWs wrapping objs from different principals " +
michael@0 301 "shouldn't throw on second access but not first: " + e);
michael@0 302 }
michael@0 303 }
michael@0 304
michael@0 305 // Decompile the COW test suite, re-evaluate it in the sandbox and execute it.
michael@0 306 Cu.evalInSandbox('(' + uneval(COWTests) + ')()', sandbox);
michael@0 307
michael@0 308 // Test that COWed objects passing from content to chrome get unwrapped.
michael@0 309 function returnCOW() {
michael@0 310 return getCOW({__exposedProps__: {},
michael@0 311 bar: 6});
michael@0 312 }
michael@0 313
michael@0 314 var unwrapped = Cu.evalInSandbox(
michael@0 315 '(' + uneval(returnCOW) + ')()',
michael@0 316 sandbox
michael@0 317 );
michael@0 318
michael@0 319 try {
michael@0 320 is(unwrapped.bar, 6,
michael@0 321 "COWs should be unwrapped when entering chrome space");
michael@0 322 } catch (e) {
michael@0 323 todo(false, "COWs should be unwrapped when entering chrome space, " +
michael@0 324 "not raise " + e);
michael@0 325 }
michael@0 326 ]]></script>
michael@0 327 </window>

mercurial