|
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/. */ |
|
4 |
|
5 #include "js/OldDebugAPI.h" |
|
6 #include "jsapi-tests/tests.h" |
|
7 |
|
8 static JSPrincipals *sOriginPrincipalsInErrorReporter = nullptr; |
|
9 static TestJSPrincipals prin1(1); |
|
10 static TestJSPrincipals prin2(1); |
|
11 |
|
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 */ |
|
19 |
|
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})') })()")); |
|
31 |
|
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\", \"-\")')")); |
|
37 |
|
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 } |
|
46 |
|
47 static void |
|
48 ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report) |
|
49 { |
|
50 sOriginPrincipalsInErrorReporter = report->originPrincipals; |
|
51 } |
|
52 |
|
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; |
|
61 |
|
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)); |
|
66 |
|
67 |
|
68 JS::CompileOptions options(cx); |
|
69 options.setOriginPrincipals(originPrincipals) |
|
70 .setFileAndLine("", 0); |
|
71 |
|
72 bool ok = JS::Evaluate(cx, global, options, chars, len, rval); |
|
73 |
|
74 delete[] chars; |
|
75 return ok; |
|
76 } |
|
77 |
|
78 bool |
|
79 testOuter(const char *asciiChars) |
|
80 { |
|
81 CHECK(testInner(asciiChars, &prin1, &prin1)); |
|
82 CHECK(testInner(asciiChars, &prin1, &prin2)); |
|
83 return true; |
|
84 } |
|
85 |
|
86 bool |
|
87 testInner(const char *asciiChars, JSPrincipals *principal, JSPrincipals *originPrincipal) |
|
88 { |
|
89 JS::RootedValue rval(cx); |
|
90 CHECK(eval(asciiChars, principal, originPrincipal, &rval)); |
|
91 |
|
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); |
|
96 |
|
97 return true; |
|
98 } |
|
99 |
|
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) |