1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sw=4 et tw=99:
3 : */
4 :
5 : #include "tests.h"
6 : #include "jsscript.h"
7 :
8 : static JSScript *
9 18 : CompileScriptForPrincipalsVersionOrigin(JSContext *cx, JSObject *obj,
10 : JSPrincipals *principals, JSPrincipals *originPrincipals,
11 : const char *bytes, size_t nbytes,
12 : const char *filename, unsigned lineno,
13 : JSVersion version)
14 : {
15 : size_t nchars;
16 18 : if (!JS_DecodeBytes(cx, bytes, nbytes, NULL, &nchars))
17 0 : return NULL;
18 18 : jschar *chars = static_cast<jschar *>(JS_malloc(cx, nchars * sizeof(jschar)));
19 18 : if (!chars)
20 0 : return NULL;
21 18 : JS_ALWAYS_TRUE(JS_DecodeBytes(cx, bytes, nbytes, chars, &nchars));
22 : JSScript *script = JS_CompileUCScriptForPrincipalsVersionOrigin(cx, obj,
23 : principals, originPrincipals,
24 : chars, nchars,
25 18 : filename, lineno, version);
26 18 : free(chars);
27 18 : return script;
28 : }
29 :
30 : JSScript *
31 15 : FreezeThaw(JSContext *cx, JSScript *script)
32 : {
33 : // freeze
34 : uint32_t nbytes;
35 15 : void *memory = JS_EncodeScript(cx, script, &nbytes);
36 15 : if (!memory)
37 0 : return NULL;
38 :
39 : // thaw
40 15 : script = JS_DecodeScript(cx, memory, nbytes, script->principals, script->originPrincipals);
41 15 : js_free(memory);
42 15 : return script;
43 : }
44 :
45 : static JSScript *
46 18 : GetScript(JSContext *cx, JSObject *funobj)
47 : {
48 18 : return JS_GetFunctionScript(cx, JS_GetObjectFunction(funobj));
49 : }
50 :
51 : JSObject *
52 6 : FreezeThaw(JSContext *cx, JSObject *funobj)
53 : {
54 : // freeze
55 : uint32_t nbytes;
56 6 : void *memory = JS_EncodeInterpretedFunction(cx, funobj, &nbytes);
57 6 : if (!memory)
58 0 : return NULL;
59 :
60 : // thaw
61 6 : JSScript *script = GetScript(cx, funobj);
62 : funobj = JS_DecodeInterpretedFunction(cx, memory, nbytes,
63 6 : script->principals, script->originPrincipals);
64 6 : js_free(memory);
65 6 : return funobj;
66 : }
67 :
68 : static JSPrincipals testPrincipals[] = {
69 : { 1 },
70 : { 1 },
71 : };
72 :
73 4 : BEGIN_TEST(testXDR_principals)
74 : {
75 : JSScript *script;
76 4 : for (int i = TEST_FIRST; i != TEST_END; ++i) {
77 3 : script = createScriptViaXDR(NULL, NULL, i);
78 3 : CHECK(script);
79 3 : CHECK(!JS_GetScriptPrincipals(script));
80 3 : CHECK(!JS_GetScriptOriginPrincipals(script));
81 :
82 3 : script = createScriptViaXDR(NULL, NULL, i);
83 3 : CHECK(script);
84 3 : CHECK(!JS_GetScriptPrincipals(script));
85 3 : CHECK(!JS_GetScriptOriginPrincipals(script));
86 :
87 3 : script = createScriptViaXDR(&testPrincipals[0], NULL, i);
88 3 : CHECK(script);
89 3 : CHECK(JS_GetScriptPrincipals(script) == &testPrincipals[0]);
90 3 : CHECK(JS_GetScriptOriginPrincipals(script) == &testPrincipals[0]);
91 :
92 3 : script = createScriptViaXDR(&testPrincipals[0], &testPrincipals[0], i);
93 3 : CHECK(script);
94 3 : CHECK(JS_GetScriptPrincipals(script) == &testPrincipals[0]);
95 3 : CHECK(JS_GetScriptOriginPrincipals(script) == &testPrincipals[0]);
96 :
97 3 : script = createScriptViaXDR(&testPrincipals[0], &testPrincipals[1], i);
98 3 : CHECK(script);
99 3 : CHECK(JS_GetScriptPrincipals(script) == &testPrincipals[0]);
100 3 : CHECK(JS_GetScriptOriginPrincipals(script) == &testPrincipals[1]);
101 :
102 3 : script = createScriptViaXDR(NULL, &testPrincipals[1], i);
103 3 : CHECK(script);
104 3 : CHECK(!JS_GetScriptPrincipals(script));
105 3 : CHECK(JS_GetScriptOriginPrincipals(script) == &testPrincipals[1]);
106 : }
107 :
108 1 : return true;
109 : }
110 :
111 : enum TestCase {
112 : TEST_FIRST,
113 : TEST_SCRIPT = TEST_FIRST,
114 : TEST_FUNCTION,
115 : TEST_SERIALIZED_FUNCTION,
116 : TEST_END
117 : };
118 :
119 18 : JSScript *createScriptViaXDR(JSPrincipals *prin, JSPrincipals *orig, int testCase)
120 : {
121 : const char src[] =
122 : "function f() { return 1; }\n"
123 18 : "f;\n";
124 :
125 : JSScript *script = CompileScriptForPrincipalsVersionOrigin(cx, global, prin, orig,
126 : src, strlen(src), "test", 1,
127 18 : JSVERSION_DEFAULT);
128 18 : if (!script)
129 0 : return NULL;
130 :
131 18 : if (testCase == TEST_SCRIPT || testCase == TEST_SERIALIZED_FUNCTION) {
132 12 : script = FreezeThaw(cx, script);
133 12 : if (!script)
134 0 : return NULL;
135 12 : if (testCase == TEST_SCRIPT)
136 6 : return script;
137 : }
138 :
139 : JS::Value v;
140 12 : JSBool ok = JS_ExecuteScript(cx, global, script, &v);
141 12 : if (!ok || !v.isObject())
142 0 : return NULL;
143 12 : JSObject *funobj = &v.toObject();
144 12 : if (testCase == TEST_FUNCTION) {
145 6 : funobj = FreezeThaw(cx, funobj);
146 6 : if (!funobj)
147 0 : return NULL;
148 : }
149 12 : return GetScript(cx, funobj);
150 : }
151 :
152 1 : END_TEST(testXDR_principals)
153 :
154 4 : BEGIN_TEST(testXDR_atline)
155 : {
156 1 : JS_ToggleOptions(cx, JSOPTION_ATLINE);
157 1 : CHECK(JS_GetOptions(cx) & JSOPTION_ATLINE);
158 :
159 : const char src[] =
160 : "//@line 100 \"foo\"\n"
161 : "function nested() { }\n"
162 : "//@line 200 \"bar\"\n"
163 1 : "nested;\n";
164 :
165 1 : JSScript *script = JS_CompileScript(cx, global, src, strlen(src), "internal", 1);
166 1 : CHECK(script);
167 1 : CHECK(script = FreezeThaw(cx, script));
168 1 : CHECK(!strcmp("bar", JS_GetScriptFilename(cx, script)));
169 :
170 : JS::Value v;
171 1 : JSBool ok = JS_ExecuteScript(cx, global, script, &v);
172 1 : CHECK(ok);
173 1 : CHECK(v.isObject());
174 :
175 1 : JSObject *funobj = &v.toObject();
176 1 : script = JS_GetFunctionScript(cx, JS_GetObjectFunction(funobj));
177 1 : CHECK(!strcmp("foo", JS_GetScriptFilename(cx, script)));
178 :
179 1 : return true;
180 : }
181 :
182 1 : END_TEST(testXDR_atline)
183 :
184 4 : BEGIN_TEST(testXDR_bug506491)
185 : {
186 : const char *s =
187 : "function makeClosure(s, name, value) {\n"
188 : " eval(s);\n"
189 : " return let (n = name, v = value) function () { return String(v); };\n"
190 : "}\n"
191 1 : "var f = makeClosure('0;', 'status', 'ok');\n";
192 :
193 : // compile
194 1 : JSScript *script = JS_CompileScript(cx, global, s, strlen(s), __FILE__, __LINE__);
195 1 : CHECK(script);
196 :
197 1 : script = FreezeThaw(cx, script);
198 1 : CHECK(script);
199 :
200 : // execute
201 2 : jsvalRoot v2(cx);
202 1 : CHECK(JS_ExecuteScript(cx, global, script, v2.addr()));
203 :
204 : // try to break the Block object that is the parent of f
205 1 : JS_GC(cx);
206 :
207 : // confirm
208 1 : EVAL("f() === 'ok';\n", v2.addr());
209 2 : jsvalRoot trueval(cx, JSVAL_TRUE);
210 1 : CHECK_SAME(v2, trueval);
211 1 : return true;
212 : }
213 1 : END_TEST(testXDR_bug506491)
214 :
215 4 : BEGIN_TEST(testXDR_bug516827)
216 : {
217 : // compile an empty script
218 1 : JSScript *script = JS_CompileScript(cx, global, "", 0, __FILE__, __LINE__);
219 1 : CHECK(script);
220 :
221 1 : script = FreezeThaw(cx, script);
222 1 : CHECK(script);
223 :
224 : // execute with null result meaning no result wanted
225 1 : CHECK(JS_ExecuteScript(cx, global, script, NULL));
226 1 : return true;
227 : }
228 3 : END_TEST(testXDR_bug516827)
|