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 | #include "js/OldDebugAPI.h" |
michael@0 | 6 | #include "jsapi-tests/tests.h" |
michael@0 | 7 | |
michael@0 | 8 | static JSPrincipals *sOriginPrincipalsInErrorReporter = nullptr; |
michael@0 | 9 | static TestJSPrincipals prin1(1); |
michael@0 | 10 | static TestJSPrincipals prin2(1); |
michael@0 | 11 | |
michael@0 | 12 | BEGIN_TEST(testOriginPrincipals) |
michael@0 | 13 | { |
michael@0 | 14 | /* |
michael@0 | 15 | * Currently, the only way to set a non-trivial originPrincipal is to use |
michael@0 | 16 | * JS_EvaluateUCScriptForPrincipalsVersionOrigin. This does not expose the |
michael@0 | 17 | * compiled script, so we can only test nested scripts. |
michael@0 | 18 | */ |
michael@0 | 19 | |
michael@0 | 20 | CHECK(testOuter("function f() {return 1}; f;")); |
michael@0 | 21 | CHECK(testOuter("function outer() { return (function () {return 2}); }; outer();")); |
michael@0 | 22 | CHECK(testOuter("eval('(function() {return 3})');")); |
michael@0 | 23 | CHECK(testOuter("(function (){ return eval('(function() {return 4})'); })()")); |
michael@0 | 24 | CHECK(testOuter("(function (){ return eval('(function() { return eval(\"(function(){return 5})\") })()'); })()")); |
michael@0 | 25 | CHECK(testOuter("new Function('return 6')")); |
michael@0 | 26 | CHECK(testOuter("function f() { return new Function('return 7') }; f();")); |
michael@0 | 27 | CHECK(testOuter("eval('new Function(\"return 8\")')")); |
michael@0 | 28 | CHECK(testOuter("(new Function('return eval(\"(function(){return 9})\")'))()")); |
michael@0 | 29 | CHECK(testOuter("(function(){return function(){return 10}}).bind()()")); |
michael@0 | 30 | CHECK(testOuter("var e = eval; (function() { return e('(function(){return 11})') })()")); |
michael@0 | 31 | |
michael@0 | 32 | JS_SetErrorReporter(cx, ErrorReporter); |
michael@0 | 33 | CHECK(testError("eval(-)")); |
michael@0 | 34 | CHECK(testError("-")); |
michael@0 | 35 | CHECK(testError("new Function('x', '-')")); |
michael@0 | 36 | CHECK(testError("eval('new Function(\"x\", \"-\")')")); |
michael@0 | 37 | |
michael@0 | 38 | /* |
michael@0 | 39 | * NB: uncaught exceptions, when reported, have nothing on the stack so |
michael@0 | 40 | * both the filename and originPrincipals are null. E.g., this would fail: |
michael@0 | 41 | * |
michael@0 | 42 | * CHECK(testError("throw 3")); |
michael@0 | 43 | */ |
michael@0 | 44 | return true; |
michael@0 | 45 | } |
michael@0 | 46 | |
michael@0 | 47 | static void |
michael@0 | 48 | ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report) |
michael@0 | 49 | { |
michael@0 | 50 | sOriginPrincipalsInErrorReporter = report->originPrincipals; |
michael@0 | 51 | } |
michael@0 | 52 | |
michael@0 | 53 | bool |
michael@0 | 54 | eval(const char *asciiChars, JSPrincipals *principals, JSPrincipals *originPrincipals, JS::MutableHandleValue rval) |
michael@0 | 55 | { |
michael@0 | 56 | size_t len = strlen(asciiChars); |
michael@0 | 57 | jschar *chars = new jschar[len+1]; |
michael@0 | 58 | for (size_t i = 0; i < len; ++i) |
michael@0 | 59 | chars[i] = asciiChars[i]; |
michael@0 | 60 | chars[len] = 0; |
michael@0 | 61 | |
michael@0 | 62 | JS::RootedObject global(cx, JS_NewGlobalObject(cx, getGlobalClass(), principals, JS::FireOnNewGlobalHook)); |
michael@0 | 63 | CHECK(global); |
michael@0 | 64 | JSAutoCompartment ac(cx, global); |
michael@0 | 65 | CHECK(JS_InitStandardClasses(cx, global)); |
michael@0 | 66 | |
michael@0 | 67 | |
michael@0 | 68 | JS::CompileOptions options(cx); |
michael@0 | 69 | options.setOriginPrincipals(originPrincipals) |
michael@0 | 70 | .setFileAndLine("", 0); |
michael@0 | 71 | |
michael@0 | 72 | bool ok = JS::Evaluate(cx, global, options, chars, len, rval); |
michael@0 | 73 | |
michael@0 | 74 | delete[] chars; |
michael@0 | 75 | return ok; |
michael@0 | 76 | } |
michael@0 | 77 | |
michael@0 | 78 | bool |
michael@0 | 79 | testOuter(const char *asciiChars) |
michael@0 | 80 | { |
michael@0 | 81 | CHECK(testInner(asciiChars, &prin1, &prin1)); |
michael@0 | 82 | CHECK(testInner(asciiChars, &prin1, &prin2)); |
michael@0 | 83 | return true; |
michael@0 | 84 | } |
michael@0 | 85 | |
michael@0 | 86 | bool |
michael@0 | 87 | testInner(const char *asciiChars, JSPrincipals *principal, JSPrincipals *originPrincipal) |
michael@0 | 88 | { |
michael@0 | 89 | JS::RootedValue rval(cx); |
michael@0 | 90 | CHECK(eval(asciiChars, principal, originPrincipal, &rval)); |
michael@0 | 91 | |
michael@0 | 92 | JS::RootedFunction fun(cx, &rval.toObject().as<JSFunction>()); |
michael@0 | 93 | JSScript *script = JS_GetFunctionScript(cx, fun); |
michael@0 | 94 | CHECK(JS_GetScriptPrincipals(script) == principal); |
michael@0 | 95 | CHECK(JS_GetScriptOriginPrincipals(script) == originPrincipal); |
michael@0 | 96 | |
michael@0 | 97 | return true; |
michael@0 | 98 | } |
michael@0 | 99 | |
michael@0 | 100 | bool |
michael@0 | 101 | testError(const char *asciiChars) |
michael@0 | 102 | { |
michael@0 | 103 | JS::RootedValue rval(cx); |
michael@0 | 104 | CHECK(!eval(asciiChars, &prin1, &prin2 /* = originPrincipals */, &rval)); |
michael@0 | 105 | CHECK(JS_ReportPendingException(cx)); |
michael@0 | 106 | CHECK(sOriginPrincipalsInErrorReporter == &prin2); |
michael@0 | 107 | return true; |
michael@0 | 108 | } |
michael@0 | 109 | END_TEST(testOriginPrincipals) |