1 : #include "tests.h"
2 : #include "jsdbgapi.h"
3 : #include "jsobjinlines.h"
4 :
5 : JSPrincipals *sCurrentGlobalPrincipals = NULL;
6 :
7 : JSPrincipals *
8 25 : ObjectPrincipalsFinder(JSObject *)
9 : {
10 25 : return sCurrentGlobalPrincipals;
11 : }
12 :
13 : static const JSSecurityCallbacks seccb = {
14 : NULL,
15 : NULL,
16 : NULL,
17 : ObjectPrincipalsFinder,
18 : NULL
19 : };
20 :
21 : JSPrincipals *sOriginPrincipalsInErrorReporter = NULL;
22 :
23 : static void
24 4 : ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
25 : {
26 4 : sOriginPrincipalsInErrorReporter = report->originPrincipals;
27 4 : }
28 :
29 : JSPrincipals prin1 = { 1 };
30 : JSPrincipals prin2 = { 1 };
31 :
32 4 : BEGIN_TEST(testOriginPrincipals)
33 : {
34 1 : JS_SetSecurityCallbacks(rt, &seccb);
35 :
36 : /*
37 : * Currently, the only way to set a non-trivial originPrincipal is to use
38 : * JS_EvaluateUCScriptForPrincipalsVersionOrigin. This does not expose the
39 : * compiled script, so we can only test nested scripts.
40 : */
41 :
42 1 : CHECK(testOuter("function f() {return 1}; f;"));
43 1 : CHECK(testOuter("function outer() { return (function () {return 2}); }; outer();"));
44 1 : CHECK(testOuter("eval('(function() {return 3})');"));
45 1 : CHECK(testOuter("(function (){ return eval('(function() {return 4})'); })()"));
46 1 : CHECK(testOuter("(function (){ return eval('(function() { return eval(\"(function(){return 5})\") })()'); })()"));
47 1 : CHECK(testOuter("new Function('return 6')"));
48 1 : CHECK(testOuter("function f() { return new Function('return 7') }; f();"));
49 1 : CHECK(testOuter("eval('new Function(\"return 8\")')"));
50 1 : CHECK(testOuter("(new Function('return eval(\"(function(){return 9})\")'))()"));
51 1 : CHECK(testOuter("(function(){return function(){return 10}}).bind()()"));
52 1 : CHECK(testOuter("var e = eval; (function() { return e('(function(){return 11})') })()"));
53 :
54 1 : JS_SetErrorReporter(cx, ErrorReporter);
55 1 : CHECK(testError("eval(-)"));
56 1 : CHECK(testError("-"));
57 1 : CHECK(testError("new Function('x', '-')"));
58 1 : CHECK(testError("eval('new Function(\"x\", \"-\")')"));
59 :
60 : /*
61 : * NB: uncaught exceptions, when reported, have nothing on the stack so
62 : * both the filename and originPrincipals are null. E.g., this would fail:
63 : *
64 : * CHECK(testError("throw 3"));
65 : */
66 1 : return true;
67 : }
68 :
69 : bool
70 26 : eval(const char *asciiChars, JSPrincipals *principals, JSPrincipals *originPrincipals, jsval *rval)
71 : {
72 26 : size_t len = strlen(asciiChars);
73 26 : jschar *chars = new jschar[len+1];
74 1200 : for (size_t i = 0; i < len; ++i)
75 1174 : chars[i] = asciiChars[i];
76 26 : chars[len] = 0;
77 :
78 : bool ok = JS_EvaluateUCScriptForPrincipalsVersionOrigin(cx, global,
79 : principals,
80 : originPrincipals,
81 : chars, len, "", 0, rval,
82 26 : JSVERSION_DEFAULT);
83 26 : delete[] chars;
84 26 : return ok;
85 : }
86 :
87 : bool
88 11 : testOuter(const char *asciiChars)
89 : {
90 11 : CHECK(testInner(asciiChars, &prin1, &prin1));
91 11 : CHECK(testInner(asciiChars, &prin1, &prin2));
92 11 : return true;
93 : }
94 :
95 : bool
96 22 : testInner(const char *asciiChars, JSPrincipals *principal, JSPrincipals *originPrincipal)
97 : {
98 22 : sCurrentGlobalPrincipals = principal;
99 :
100 : jsval rval;
101 22 : CHECK(eval(asciiChars, principal, originPrincipal, &rval));
102 :
103 22 : JSScript *script = JS_GetFunctionScript(cx, JSVAL_TO_OBJECT(rval)->toFunction());
104 22 : CHECK(JS_GetScriptPrincipals(cx, script) == principal);
105 22 : CHECK(JS_GetScriptOriginPrincipals(cx, script) == originPrincipal);
106 :
107 22 : return true;
108 : }
109 :
110 : bool
111 4 : testError(const char *asciiChars)
112 : {
113 : jsval rval;
114 4 : CHECK(!eval(asciiChars, &prin1, &prin2 /* = originPrincipals */, &rval));
115 4 : CHECK(JS_ReportPendingException(cx));
116 4 : CHECK(sOriginPrincipalsInErrorReporter == &prin2);
117 4 : return true;
118 : }
119 2 : END_TEST(testOriginPrincipals)
|