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 "jsfriendapi.h"
8 #include "jsscript.h"
9 #include "jsstr.h"
11 #include "jsapi-tests/tests.h"
13 #include "jsscriptinlines.h"
15 static JSScript *
16 CompileScriptForPrincipalsVersionOrigin(JSContext *cx, JS::HandleObject obj,
17 JSPrincipals *originPrincipals,
18 const char *bytes, size_t nbytes,
19 const char *filename, unsigned lineno,
20 JSVersion version)
21 {
22 size_t nchars;
23 if (!JS_DecodeBytes(cx, bytes, nbytes, nullptr, &nchars))
24 return nullptr;
25 jschar *chars = static_cast<jschar *>(JS_malloc(cx, nchars * sizeof(jschar)));
26 if (!chars)
27 return nullptr;
28 JS_ALWAYS_TRUE(JS_DecodeBytes(cx, bytes, nbytes, chars, &nchars));
29 JS::CompileOptions options(cx);
30 options.setOriginPrincipals(originPrincipals)
31 .setFileAndLine(filename, lineno)
32 .setVersion(version);
33 JSScript *script = JS::Compile(cx, obj, options, chars, nchars);
34 free(chars);
35 return script;
36 }
38 static JSScript *
39 FreezeThaw(JSContext *cx, JS::HandleScript script)
40 {
41 // freeze
42 uint32_t nbytes;
43 void *memory = JS_EncodeScript(cx, script, &nbytes);
44 if (!memory)
45 return nullptr;
47 // thaw
48 JSScript *script2 = JS_DecodeScript(cx, memory, nbytes,
49 script->originPrincipals());
50 js_free(memory);
51 return script2;
52 }
54 static JSScript *
55 GetScript(JSContext *cx, JS::HandleObject funobj)
56 {
57 JS::RootedFunction fun(cx, JS_GetObjectFunction(funobj));
58 return JS_GetFunctionScript(cx, fun);
59 }
61 static JSObject *
62 FreezeThaw(JSContext *cx, JS::HandleObject funobj)
63 {
64 // freeze
65 uint32_t nbytes;
66 void *memory = JS_EncodeInterpretedFunction(cx, funobj, &nbytes);
67 if (!memory)
68 return nullptr;
70 // thaw
71 JSScript *script = GetScript(cx, funobj);
72 JSObject *funobj2 = JS_DecodeInterpretedFunction(cx, memory, nbytes,
73 script->originPrincipals());
74 js_free(memory);
75 return funobj2;
76 }
78 static TestJSPrincipals testPrincipal0(1);
79 static TestJSPrincipals testPrincipal1(1);
81 BEGIN_TEST(testXDR_principals)
82 {
83 JSScript *script;
84 JSCompartment *compartment = js::GetContextCompartment(cx);
85 for (int i = TEST_FIRST; i != TEST_END; ++i) {
86 // Appease the new JSAPI assertions. The stuff being tested here is
87 // going away anyway.
88 JS_SetCompartmentPrincipals(compartment, &testPrincipal0);
89 script = createScriptViaXDR(nullptr, i);
90 CHECK(script);
91 CHECK(JS_GetScriptPrincipals(script) == &testPrincipal0);
92 CHECK(JS_GetScriptOriginPrincipals(script) == &testPrincipal0);
94 script = createScriptViaXDR(&testPrincipal0, i);
95 CHECK(script);
96 CHECK(JS_GetScriptPrincipals(script) == &testPrincipal0);
97 CHECK(JS_GetScriptOriginPrincipals(script) == &testPrincipal0);
99 script = createScriptViaXDR(&testPrincipal1, i);
100 CHECK(script);
101 CHECK(JS_GetScriptPrincipals(script) == &testPrincipal0);
102 CHECK(JS_GetScriptOriginPrincipals(script) == &testPrincipal1);
103 }
105 return true;
106 }
108 enum TestCase {
109 TEST_FIRST,
110 TEST_SCRIPT = TEST_FIRST,
111 TEST_FUNCTION,
112 TEST_SERIALIZED_FUNCTION,
113 TEST_END
114 };
116 JSScript *createScriptViaXDR(JSPrincipals *orig, int testCase)
117 {
118 const char src[] =
119 "function f() { return 1; }\n"
120 "f;\n";
122 JS::RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
123 JS::RootedScript script(cx, CompileScriptForPrincipalsVersionOrigin(cx, global, orig,
124 src, strlen(src), "test", 1,
125 JSVERSION_DEFAULT));
126 if (!script)
127 return nullptr;
129 if (testCase == TEST_SCRIPT || testCase == TEST_SERIALIZED_FUNCTION) {
130 script = FreezeThaw(cx, script);
131 if (!script)
132 return nullptr;
133 if (testCase == TEST_SCRIPT)
134 return script;
135 }
137 JS::RootedValue v(cx);
138 bool ok = JS_ExecuteScript(cx, global, script, &v);
139 if (!ok || !v.isObject())
140 return nullptr;
141 JS::RootedObject funobj(cx, &v.toObject());
142 if (testCase == TEST_FUNCTION) {
143 funobj = FreezeThaw(cx, funobj);
144 if (!funobj)
145 return nullptr;
146 }
147 return GetScript(cx, funobj);
148 }
150 END_TEST(testXDR_principals)
152 BEGIN_TEST(testXDR_bug506491)
153 {
154 const char *s =
155 "function makeClosure(s, name, value) {\n"
156 " eval(s);\n"
157 " Math.sin(value);\n"
158 " return let (n = name, v = value) function () { return String(v); };\n"
159 "}\n"
160 "var f = makeClosure('0;', 'status', 'ok');\n";
162 // compile
163 JS::CompileOptions options(cx);
164 options.setFileAndLine(__FILE__, __LINE__);
165 JS::RootedScript script(cx, JS_CompileScript(cx, global, s, strlen(s),
166 options));
167 CHECK(script);
169 script = FreezeThaw(cx, script);
170 CHECK(script);
172 // execute
173 JS::RootedValue v2(cx);
174 CHECK(JS_ExecuteScript(cx, global, script, &v2));
176 // try to break the Block object that is the parent of f
177 JS_GC(rt);
179 // confirm
180 EVAL("f() === 'ok';\n", &v2);
181 JS::RootedValue trueval(cx, JSVAL_TRUE);
182 CHECK_SAME(v2, trueval);
183 return true;
184 }
185 END_TEST(testXDR_bug506491)
187 BEGIN_TEST(testXDR_bug516827)
188 {
189 // compile an empty script
190 JS::CompileOptions options(cx);
191 options.setFileAndLine(__FILE__, __LINE__);
192 JS::RootedScript script(cx, JS_CompileScript(cx, global, "", 0, options));
193 CHECK(script);
195 script = FreezeThaw(cx, script);
196 CHECK(script);
198 // execute with null result meaning no result wanted
199 CHECK(JS_ExecuteScript(cx, global, script));
200 return true;
201 }
202 END_TEST(testXDR_bug516827)
204 BEGIN_TEST(testXDR_source)
205 {
206 const char *samples[] = {
207 // This can't possibly fail to compress well, can it?
208 "function f(x) { return x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x }",
209 "short",
210 nullptr
211 };
212 for (const char **s = samples; *s; s++) {
213 JS::CompileOptions options(cx);
214 options.setFileAndLine(__FILE__, __LINE__);
215 JS::RootedScript script(cx, JS_CompileScript(cx, global, *s, strlen(*s),
216 options));
217 CHECK(script);
218 script = FreezeThaw(cx, script);
219 CHECK(script);
220 JSString *out = JS_DecompileScript(cx, script, "testing", 0);
221 CHECK(out);
222 bool equal;
223 CHECK(JS_StringEqualsAscii(cx, out, *s, &equal));
224 CHECK(equal);
225 }
226 return true;
227 }
228 END_TEST(testXDR_source)
230 BEGIN_TEST(testXDR_sourceMap)
231 {
232 const char *sourceMaps[] = {
233 "http://example.com/source-map.json",
234 "file:///var/source-map.json",
235 nullptr
236 };
237 JS::RootedScript script(cx);
238 for (const char **sm = sourceMaps; *sm; sm++) {
239 JS::CompileOptions options(cx);
240 options.setFileAndLine(__FILE__, __LINE__);
241 script = JS_CompileScript(cx, global, "", 0, options);
242 CHECK(script);
244 size_t len = strlen(*sm);
245 jschar *expected = js::InflateString(cx, *sm, &len);
246 CHECK(expected);
248 // The script source takes responsibility of free'ing |expected|.
249 CHECK(script->scriptSource()->setSourceMapURL(cx, expected));
250 script = FreezeThaw(cx, script);
251 CHECK(script);
252 CHECK(script->scriptSource());
253 CHECK(script->scriptSource()->hasSourceMapURL());
255 const jschar *actual = script->scriptSource()->sourceMapURL();
256 CHECK(actual);
258 while (*expected) {
259 CHECK(*actual);
260 CHECK(*expected == *actual);
261 expected++;
262 actual++;
263 }
264 CHECK(!*actual);
265 }
266 return true;
267 }
268 END_TEST(testXDR_sourceMap)