js/src/tests/js1_8_5/regress/regress-577648-1.js

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 /*
michael@0 2 * Any copyright is dedicated to the Public Domain.
michael@0 3 * http://creativecommons.org/licenses/publicdomain/
michael@0 4 */
michael@0 5
michael@0 6 var count = 0;
michael@0 7
michael@0 8 function testCaller(obj) {
michael@0 9 switch (++count) {
michael@0 10 case 1:
michael@0 11 case 2:
michael@0 12 /*
michael@0 13 * The first two times, obj is objA. The first time, we reference
michael@0 14 * arguments.callee.caller before obj.go, so the caller getter must
michael@0 15 * force the joined function object in the stack frame to cross the
michael@0 16 * method read barrier. The second time, obj.go has been cloned and
michael@0 17 * it should match the new frame's callee from the get-go.
michael@0 18 */
michael@0 19 assertEq(obj, objA);
michael@0 20 break;
michael@0 21
michael@0 22 case 3: {
michael@0 23 assertEq(obj, objB);
michael@0 24
michael@0 25 /*
michael@0 26 * Store another clone of the joined function object before obj.go has
michael@0 27 * been read, but after it has been invoked via objB.go(objB).
michael@0 28 *
michael@0 29 * In this case, arguments.callee.caller must not lie and return what
michael@0 30 * is currently stored in objB.go, since that function object (objA.go)
michael@0 31 * was cloned earlier, when count was 1, and it is not the function
michael@0 32 * object that was truly invoked.
michael@0 33 *
michael@0 34 * But since the invocation of objB.go(objB) did not clone go, and the
michael@0 35 * following assignment overwrote the invoked value, leaving the only
michael@0 36 * reference to the joined function object for go in the stack frame's
michael@0 37 * callee (argv[-2]) member, the arguments.callee.caller reference must
michael@0 38 * clone a function object for the callee, store it as the callee, and
michael@0 39 * return it here.
michael@0 40 *
michael@0 41 * It won't equal obj.go, but (implementation detail) it should have
michael@0 42 * the same proto as obj.go
michael@0 43 */
michael@0 44 obj.go = objA.go;
michael@0 45
michael@0 46 let caller = arguments.callee.caller;
michael@0 47 let obj_go = obj.go;
michael@0 48 return caller != obj_go && caller.__proto__ == obj_go.__proto__;
michael@0 49 }
michael@0 50
michael@0 51 case 4: {
michael@0 52 assertEq(obj, objC);
michael@0 53
michael@0 54 let save = obj.go;
michael@0 55 delete obj.go;
michael@0 56 return arguments.callee.caller == save;
michael@0 57 }
michael@0 58
michael@0 59 case 5: {
michael@0 60 assertEq(obj, objD);
michael@0 61
michael@0 62 let read = obj.go;
michael@0 63 break;
michael@0 64 }
michael@0 65 }
michael@0 66
michael@0 67 return arguments.callee.caller == obj.go;
michael@0 68 }
michael@0 69
michael@0 70 function make() {
michael@0 71 return {
michael@0 72 go: function(obj) {
michael@0 73 return testCaller(obj);
michael@0 74 }
michael@0 75 };
michael@0 76 }
michael@0 77
michael@0 78 var objA = make(),
michael@0 79 objB = make(),
michael@0 80 objC = make(),
michael@0 81 objD = make();
michael@0 82
michael@0 83 reportCompare(true, objA.go(objA), "1");
michael@0 84 reportCompare(true, objA.go(objA), "2");
michael@0 85 reportCompare(true, objB.go(objB), "3");
michael@0 86 reportCompare(true, objC.go(objC), "4");
michael@0 87 reportCompare(true, objD.go(objD), "5");

mercurial