js/src/jsapi-tests/testXDR.cpp

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

mercurial