Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "js/OldDebugAPI.h"
6 #include "jsapi-tests/tests.h"
8 static JSPrincipals *sOriginPrincipalsInErrorReporter = nullptr;
9 static TestJSPrincipals prin1(1);
10 static TestJSPrincipals prin2(1);
12 BEGIN_TEST(testOriginPrincipals)
13 {
14 /*
15 * Currently, the only way to set a non-trivial originPrincipal is to use
16 * JS_EvaluateUCScriptForPrincipalsVersionOrigin. This does not expose the
17 * compiled script, so we can only test nested scripts.
18 */
20 CHECK(testOuter("function f() {return 1}; f;"));
21 CHECK(testOuter("function outer() { return (function () {return 2}); }; outer();"));
22 CHECK(testOuter("eval('(function() {return 3})');"));
23 CHECK(testOuter("(function (){ return eval('(function() {return 4})'); })()"));
24 CHECK(testOuter("(function (){ return eval('(function() { return eval(\"(function(){return 5})\") })()'); })()"));
25 CHECK(testOuter("new Function('return 6')"));
26 CHECK(testOuter("function f() { return new Function('return 7') }; f();"));
27 CHECK(testOuter("eval('new Function(\"return 8\")')"));
28 CHECK(testOuter("(new Function('return eval(\"(function(){return 9})\")'))()"));
29 CHECK(testOuter("(function(){return function(){return 10}}).bind()()"));
30 CHECK(testOuter("var e = eval; (function() { return e('(function(){return 11})') })()"));
32 JS_SetErrorReporter(cx, ErrorReporter);
33 CHECK(testError("eval(-)"));
34 CHECK(testError("-"));
35 CHECK(testError("new Function('x', '-')"));
36 CHECK(testError("eval('new Function(\"x\", \"-\")')"));
38 /*
39 * NB: uncaught exceptions, when reported, have nothing on the stack so
40 * both the filename and originPrincipals are null. E.g., this would fail:
41 *
42 * CHECK(testError("throw 3"));
43 */
44 return true;
45 }
47 static void
48 ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
49 {
50 sOriginPrincipalsInErrorReporter = report->originPrincipals;
51 }
53 bool
54 eval(const char *asciiChars, JSPrincipals *principals, JSPrincipals *originPrincipals, JS::MutableHandleValue rval)
55 {
56 size_t len = strlen(asciiChars);
57 jschar *chars = new jschar[len+1];
58 for (size_t i = 0; i < len; ++i)
59 chars[i] = asciiChars[i];
60 chars[len] = 0;
62 JS::RootedObject global(cx, JS_NewGlobalObject(cx, getGlobalClass(), principals, JS::FireOnNewGlobalHook));
63 CHECK(global);
64 JSAutoCompartment ac(cx, global);
65 CHECK(JS_InitStandardClasses(cx, global));
68 JS::CompileOptions options(cx);
69 options.setOriginPrincipals(originPrincipals)
70 .setFileAndLine("", 0);
72 bool ok = JS::Evaluate(cx, global, options, chars, len, rval);
74 delete[] chars;
75 return ok;
76 }
78 bool
79 testOuter(const char *asciiChars)
80 {
81 CHECK(testInner(asciiChars, &prin1, &prin1));
82 CHECK(testInner(asciiChars, &prin1, &prin2));
83 return true;
84 }
86 bool
87 testInner(const char *asciiChars, JSPrincipals *principal, JSPrincipals *originPrincipal)
88 {
89 JS::RootedValue rval(cx);
90 CHECK(eval(asciiChars, principal, originPrincipal, &rval));
92 JS::RootedFunction fun(cx, &rval.toObject().as<JSFunction>());
93 JSScript *script = JS_GetFunctionScript(cx, fun);
94 CHECK(JS_GetScriptPrincipals(script) == principal);
95 CHECK(JS_GetScriptOriginPrincipals(script) == originPrincipal);
97 return true;
98 }
100 bool
101 testError(const char *asciiChars)
102 {
103 JS::RootedValue rval(cx);
104 CHECK(!eval(asciiChars, &prin1, &prin2 /* = originPrincipals */, &rval));
105 CHECK(JS_ReportPendingException(cx));
106 CHECK(sOriginPrincipalsInErrorReporter == &prin2);
107 return true;
108 }
109 END_TEST(testOriginPrincipals)