Sat, 03 Jan 2015 20:18:00 +0100
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 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | |
michael@0 | 6 | if (typeof assertThrowsInstanceOf === 'undefined') { |
michael@0 | 7 | var assertThrowsInstanceOf = function assertThrowsInstanceOf(f, ctor, msg) { |
michael@0 | 8 | var fullmsg; |
michael@0 | 9 | try { |
michael@0 | 10 | f(); |
michael@0 | 11 | } catch (exc) { |
michael@0 | 12 | if (exc instanceof ctor) |
michael@0 | 13 | return; |
michael@0 | 14 | fullmsg = "Assertion failed: expected exception " + ctor.name + ", got " + exc; |
michael@0 | 15 | } |
michael@0 | 16 | if (fullmsg === undefined) |
michael@0 | 17 | fullmsg = "Assertion failed: expected exception " + ctor.name + ", no exception thrown"; |
michael@0 | 18 | if (msg !== undefined) |
michael@0 | 19 | fullmsg += " - " + msg; |
michael@0 | 20 | throw new Error(fullmsg); |
michael@0 | 21 | }; |
michael@0 | 22 | } |
michael@0 | 23 | |
michael@0 | 24 | if (typeof assertThrowsValue === 'undefined') { |
michael@0 | 25 | var assertThrowsValue = function assertThrowsValue(f, val, msg) { |
michael@0 | 26 | var fullmsg; |
michael@0 | 27 | try { |
michael@0 | 28 | f(); |
michael@0 | 29 | } catch (exc) { |
michael@0 | 30 | if ((exc === val) === (val === val) && (val !== 0 || 1 / exc === 1 / val)) |
michael@0 | 31 | return; |
michael@0 | 32 | fullmsg = "Assertion failed: expected exception " + val + ", got " + exc; |
michael@0 | 33 | } |
michael@0 | 34 | if (fullmsg === undefined) |
michael@0 | 35 | fullmsg = "Assertion failed: expected exception " + val + ", no exception thrown"; |
michael@0 | 36 | if (msg !== undefined) |
michael@0 | 37 | fullmsg += " - " + msg; |
michael@0 | 38 | throw new Error(fullmsg); |
michael@0 | 39 | }; |
michael@0 | 40 | } |
michael@0 | 41 | |
michael@0 | 42 | if (typeof assertDeepEq === 'undefined') { |
michael@0 | 43 | var assertDeepEq = (function(){ |
michael@0 | 44 | var call = Function.prototype.call, |
michael@0 | 45 | Map_ = Map, |
michael@0 | 46 | Error_ = Error, |
michael@0 | 47 | Map_has = call.bind(Map.prototype.has), |
michael@0 | 48 | Map_get = call.bind(Map.prototype.get), |
michael@0 | 49 | Map_set = call.bind(Map.prototype.set), |
michael@0 | 50 | Object_toString = call.bind(Object.prototype.toString), |
michael@0 | 51 | Function_toString = call.bind(Function.prototype.toString), |
michael@0 | 52 | Object_getPrototypeOf = Object.getPrototypeOf, |
michael@0 | 53 | Object_hasOwnProperty = call.bind(Object.prototype.hasOwnProperty), |
michael@0 | 54 | Object_getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, |
michael@0 | 55 | Object_isExtensible = Object.isExtensible, |
michael@0 | 56 | Object_getOwnPropertyNames = Object.getOwnPropertyNames, |
michael@0 | 57 | uneval_ = uneval; |
michael@0 | 58 | |
michael@0 | 59 | // Return true iff ES6 Type(v) isn't Object. |
michael@0 | 60 | // Note that `typeof document.all === "undefined"`. |
michael@0 | 61 | function isPrimitive(v) { |
michael@0 | 62 | return (v === null || |
michael@0 | 63 | v === undefined || |
michael@0 | 64 | typeof v === "boolean" || |
michael@0 | 65 | typeof v === "number" || |
michael@0 | 66 | typeof v === "string" || |
michael@0 | 67 | typeof v === "symbol"); |
michael@0 | 68 | } |
michael@0 | 69 | |
michael@0 | 70 | function assertSameValue(a, b, msg) { |
michael@0 | 71 | try { |
michael@0 | 72 | assertEq(a, b); |
michael@0 | 73 | } catch (exc) { |
michael@0 | 74 | throw new Error(exc.message + (msg ? " " + msg : "")); |
michael@0 | 75 | } |
michael@0 | 76 | } |
michael@0 | 77 | |
michael@0 | 78 | function assertSameClass(a, b, msg) { |
michael@0 | 79 | var ac = Object_toString(a), bc = Object_toString(b); |
michael@0 | 80 | assertSameValue(ac, bc, msg); |
michael@0 | 81 | switch (ac) { |
michael@0 | 82 | case "[object Function]": |
michael@0 | 83 | assertSameValue(Function_toString(a), Function_toString(b), msg); |
michael@0 | 84 | } |
michael@0 | 85 | } |
michael@0 | 86 | |
michael@0 | 87 | function at(prevmsg, segment) { |
michael@0 | 88 | return prevmsg ? prevmsg + segment : "at _" + segment; |
michael@0 | 89 | } |
michael@0 | 90 | |
michael@0 | 91 | // Assert that the arguments a and b are thoroughly structurally equivalent. |
michael@0 | 92 | // |
michael@0 | 93 | // For the sake of speed, we cut a corner: |
michael@0 | 94 | // var x = {}, y = {}, ax = [x]; |
michael@0 | 95 | // assertDeepEq([ax, x], [ax, y]); // passes (?!) |
michael@0 | 96 | // |
michael@0 | 97 | // Technically this should fail, since the two object graphs are different. |
michael@0 | 98 | // (The graph of [ax, y] contains one more object than the graph of [ax, x].) |
michael@0 | 99 | // |
michael@0 | 100 | // To get technically correct behavior, pass {strictEquivalence: true}. |
michael@0 | 101 | // This is slower because we have to walk the entire graph, and Object.prototype |
michael@0 | 102 | // is big. |
michael@0 | 103 | // |
michael@0 | 104 | return function assertDeepEq(a, b, options) { |
michael@0 | 105 | var strictEquivalence = options ? options.strictEquivalence : false; |
michael@0 | 106 | |
michael@0 | 107 | function assertSameProto(a, b, msg) { |
michael@0 | 108 | check(Object_getPrototypeOf(a), Object_getPrototypeOf(b), at(msg, ".__proto__")); |
michael@0 | 109 | } |
michael@0 | 110 | |
michael@0 | 111 | function failPropList(na, nb, msg) { |
michael@0 | 112 | throw Error_("got own properties " + uneval_(na) + ", expected " + uneval_(nb) + |
michael@0 | 113 | (msg ? " " + msg : "")); |
michael@0 | 114 | } |
michael@0 | 115 | |
michael@0 | 116 | function assertSameProps(a, b, msg) { |
michael@0 | 117 | var na = Object_getOwnPropertyNames(a), |
michael@0 | 118 | nb = Object_getOwnPropertyNames(b); |
michael@0 | 119 | if (na.length !== nb.length) |
michael@0 | 120 | failPropList(na, nb, msg); |
michael@0 | 121 | for (var i = 0; i < na.length; i++) { |
michael@0 | 122 | var name = na[i]; |
michael@0 | 123 | if (name !== nb[i]) |
michael@0 | 124 | failPropList(na, nb, msg); |
michael@0 | 125 | var da = Object_getOwnPropertyDescriptor(a, name), |
michael@0 | 126 | db = Object_getOwnPropertyDescriptor(b, name); |
michael@0 | 127 | var pmsg = at(msg, /^[_$A-Za-z0-9]+$/.test(name) |
michael@0 | 128 | ? /0|[1-9][0-9]*/.test(name) ? "[" + name + "]" : "." + name |
michael@0 | 129 | : "[" + uneval_(name) + "]"); |
michael@0 | 130 | assertSameValue(da.configurable, db.configurable, at(pmsg, ".[[Configurable]]")); |
michael@0 | 131 | assertSameValue(da.enumerable, db.enumerable, at(pmsg, ".[[Enumerable]]")); |
michael@0 | 132 | if (Object_hasOwnProperty(da, "value")) { |
michael@0 | 133 | if (!Object_hasOwnProperty(db, "value")) |
michael@0 | 134 | throw Error_("got data property, expected accessor property" + pmsg); |
michael@0 | 135 | check(da.value, db.value, pmsg); |
michael@0 | 136 | } else { |
michael@0 | 137 | if (Object_hasOwnProperty(db, "value")) |
michael@0 | 138 | throw Error_("got accessor property, expected data property" + pmsg); |
michael@0 | 139 | check(da.get, db.get, at(pmsg, ".[[Get]]")); |
michael@0 | 140 | check(da.set, db.set, at(pmsg, ".[[Set]]")); |
michael@0 | 141 | } |
michael@0 | 142 | } |
michael@0 | 143 | }; |
michael@0 | 144 | |
michael@0 | 145 | var ab = Map_(); |
michael@0 | 146 | var bpath = Map_(); |
michael@0 | 147 | |
michael@0 | 148 | function check(a, b, path) { |
michael@0 | 149 | if (isPrimitive(a)) { |
michael@0 | 150 | assertSameValue(a, b, path); |
michael@0 | 151 | } else if (isPrimitive(b)) { |
michael@0 | 152 | throw Error_("got " + Object_toString(a) + ", expected " + uneval_(b) + " " + path); |
michael@0 | 153 | } else if (Map_has(ab, a)) { |
michael@0 | 154 | assertSameValue(Map_get(ab, a), b, path); |
michael@0 | 155 | } else if (Map_has(bpath, b)) { |
michael@0 | 156 | var bPrevPath = Map_get(bpath, b) || "_"; |
michael@0 | 157 | throw Error_("got distinct objects " + at(path, "") + " and " + at(bPrevPath, "") + |
michael@0 | 158 | ", expected the same object both places"); |
michael@0 | 159 | } else { |
michael@0 | 160 | Map_set(ab, a, b); |
michael@0 | 161 | Map_set(bpath, b, path); |
michael@0 | 162 | if (a !== b || strictEquivalence) { |
michael@0 | 163 | assertSameClass(a, b, path); |
michael@0 | 164 | assertSameProto(a, b, path); |
michael@0 | 165 | assertSameProps(a, b, path); |
michael@0 | 166 | assertSameValue(Object_isExtensible(a), |
michael@0 | 167 | Object_isExtensible(b), |
michael@0 | 168 | at(path, ".[[Extensible]]")); |
michael@0 | 169 | } |
michael@0 | 170 | } |
michael@0 | 171 | } |
michael@0 | 172 | |
michael@0 | 173 | check(a, b, ""); |
michael@0 | 174 | }; |
michael@0 | 175 | })(); |
michael@0 | 176 | } |