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.
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "jsapi-tests/tests.h"
9 static TestJSPrincipals system_principals(1);
11 static const JSClass global_class = {
12 "global",
13 JSCLASS_IS_GLOBAL | JSCLASS_GLOBAL_FLAGS,
14 JS_PropertyStub,
15 JS_DeletePropertyStub,
16 JS_PropertyStub,
17 JS_StrictPropertyStub,
18 JS_EnumerateStub,
19 JS_ResolveStub,
20 JS_ConvertStub,
21 nullptr,
22 nullptr,
23 nullptr,
24 nullptr,
25 JS_GlobalObjectTraceHook
26 };
28 static JS::Heap<JSObject *> trusted_glob;
29 static JS::Heap<JSObject *> trusted_fun;
31 static bool
32 CallTrusted(JSContext *cx, unsigned argc, jsval *vp)
33 {
34 JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
36 if (!JS_SaveFrameChain(cx))
37 return false;
39 bool ok = false;
40 {
41 JSAutoCompartment ac(cx, trusted_glob);
42 JS::RootedValue funVal(cx, JS::ObjectValue(*trusted_fun));
43 ok = JS_CallFunctionValue(cx, JS::NullPtr(), funVal, JS::HandleValueArray::empty(), args.rval());
44 }
45 JS_RestoreFrameChain(cx);
46 return ok;
47 }
49 BEGIN_TEST(testChromeBuffer)
50 {
51 JS_SetTrustedPrincipals(rt, &system_principals);
53 trusted_glob = JS_NewGlobalObject(cx, &global_class, &system_principals, JS::FireOnNewGlobalHook);
54 CHECK(trusted_glob);
56 if (!JS::AddNamedObjectRoot(cx, &trusted_glob, "trusted-global"))
57 return false;
59 JS::RootedFunction fun(cx);
61 /*
62 * Check that, even after untrusted content has exhausted the stack, code
63 * compiled with "trusted principals" can run using reserved trusted-only
64 * buffer space.
65 */
66 {
67 {
68 JSAutoCompartment ac(cx, trusted_glob);
69 const char *paramName = "x";
70 const char *bytes = "return x ? 1 + trusted(x-1) : 0";
71 JS::HandleObject global = JS::HandleObject::fromMarkedLocation(trusted_glob.unsafeGet());
72 JS::CompileOptions options(cx);
73 options.setFileAndLine("", 0);
74 CHECK(fun = JS_CompileFunction(cx, global, "trusted", 1, ¶mName,
75 bytes, strlen(bytes), options));
76 trusted_fun = JS_GetFunctionObject(fun);
77 if (!JS::AddNamedObjectRoot(cx, &trusted_fun, "trusted-function"))
78 return false;
79 }
81 JS::RootedValue v(cx, JS::ObjectValue(*trusted_fun));
82 CHECK(JS_WrapValue(cx, &v));
84 const char *paramName = "trusted";
85 const char *bytes = "try { "
86 " return untrusted(trusted); "
87 "} catch (e) { "
88 " try { "
89 " return trusted(100); "
90 " } catch(e) { "
91 " return -1; "
92 " } "
93 "} ";
94 JS::CompileOptions options(cx);
95 options.setFileAndLine("", 0);
96 CHECK(fun = JS_CompileFunction(cx, global, "untrusted", 1, ¶mName,
97 bytes, strlen(bytes), options));
99 JS::RootedValue rval(cx);
100 CHECK(JS_CallFunction(cx, JS::NullPtr(), fun, v, &rval));
101 CHECK(JSVAL_TO_INT(rval) == 100);
102 }
104 /*
105 * Check that content called from chrome in the reserved-buffer space
106 * immediately ooms.
107 */
108 {
109 {
110 JSAutoCompartment ac(cx, trusted_glob);
111 const char *paramName = "untrusted";
112 const char *bytes = "try { "
113 " untrusted(); "
114 "} catch (e) { "
115 " return 'From trusted: ' + e; "
116 "} ";
117 JS::HandleObject global = JS::HandleObject::fromMarkedLocation(trusted_glob.unsafeGet());
118 JS::CompileOptions options(cx);
119 options.setFileAndLine("", 0);
120 CHECK(fun = JS_CompileFunction(cx, global, "trusted", 1, ¶mName,
121 bytes, strlen(bytes), options));
122 trusted_fun = JS_GetFunctionObject(fun);
123 }
125 JS::RootedValue v(cx, JS::ObjectValue(*trusted_fun));
126 CHECK(JS_WrapValue(cx, &v));
128 const char *paramName = "trusted";
129 const char *bytes = "try { "
130 " return untrusted(trusted); "
131 "} catch (e) { "
132 " return trusted(untrusted); "
133 "} ";
134 JS::CompileOptions options(cx);
135 options.setFileAndLine("", 0);
136 CHECK(fun = JS_CompileFunction(cx, global, "untrusted", 1, ¶mName,
137 bytes, strlen(bytes), options));
139 JS::RootedValue rval(cx);
140 CHECK(JS_CallFunction(cx, JS::NullPtr(), fun, v, &rval));
141 bool match;
142 CHECK(JS_StringEqualsAscii(cx, JSVAL_TO_STRING(rval), "From trusted: InternalError: too much recursion", &match));
143 CHECK(match);
144 }
146 /*
147 * Check that JS_SaveFrameChain called on the way from content to chrome
148 * (say, as done by XPCJSContextSTack::Push) works.
149 */
150 {
151 {
152 JSAutoCompartment ac(cx, trusted_glob);
153 const char *bytes = "return 42";
154 JS::HandleObject global = JS::HandleObject::fromMarkedLocation(trusted_glob.unsafeGet());
155 JS::CompileOptions options(cx);
156 options.setFileAndLine("", 0);
157 CHECK(fun = JS_CompileFunction(cx, global, "trusted", 0, nullptr,
158 bytes, strlen(bytes), options));
159 trusted_fun = JS_GetFunctionObject(fun);
160 }
162 JS::RootedFunction fun(cx, JS_NewFunction(cx, CallTrusted, 0, 0, global, "callTrusted"));
163 JS::RootedObject callTrusted(cx, JS_GetFunctionObject(fun));
165 const char *paramName = "f";
166 const char *bytes = "try { "
167 " return untrusted(trusted); "
168 "} catch (e) { "
169 " return f(); "
170 "} ";
171 JS::CompileOptions options(cx);
172 options.setFileAndLine("", 0);
173 CHECK(fun = JS_CompileFunction(cx, global, "untrusted", 1, ¶mName,
174 bytes, strlen(bytes), options));
176 JS::RootedValue arg(cx, JS::ObjectValue(*callTrusted));
177 JS::RootedValue rval(cx);
178 CHECK(JS_CallFunction(cx, JS::NullPtr(), fun, arg, &rval));
179 CHECK(JSVAL_TO_INT(rval) == 42);
180 }
182 return true;
183 }
184 virtual void uninit() {
185 trusted_glob = nullptr;
186 trusted_fun = nullptr;
187 JS::RemoveObjectRoot(cx, &trusted_glob);
188 JS::RemoveObjectRoot(cx, &trusted_fun);
189 JSAPITest::uninit();
190 }
191 END_TEST(testChromeBuffer)