Skip to content
File

Blob: src/workerd/jsg/setup-test.c++

3.9 KB
1// Copyright (c) 2017-2022 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4 
5#include "jsg-test.h"
6 
7namespace workerd::jsg::test {
8namespace {
9 
10V8System v8System;
11 
12struct EvalContext: public Object, public ContextGlobal {
13 JSG_RESOURCE_TYPE(EvalContext) {}
14};
15JSG_DECLARE_ISOLATE_TYPE(EvalIsolate, EvalContext);
16 
17KJ_TEST("eval() is blocked") {
18 Evaluator<EvalContext, EvalIsolate> e(v8System);
19 e.expectEval("eval('123')", "throws",
20 "EvalError: Code generation from strings disallowed for this context");
21 e.expectEval("new Function('a', 'b', 'return a + b;')(123, 321)", "throws",
22 "EvalError: Code generation from strings disallowed for this context");
23 
24 // eval() with no args or a non-string arg is allowed even when eval is blocked
25 // (V8 returns the value as-is per spec since there is no string to compile).
26 e.expectEval("eval()", "undefined", "undefined");
27 e.expectEval("eval(undefined)", "undefined", "undefined");
28 
29 // new Function() with no arguments is allowed even when eval is blocked (the
30 // synthesized source matches the known empty-body, no-parameter pattern).
31 e.expectEval("typeof new Function()", "string", "function");
32 
33 // new Function() with params and an undefined body is blocked (the body becomes
34 // the string "undefined" via ToString, producing a non-empty source).
35 e.expectEval("new Function('a', 'b', undefined)", "throws",
36 "EvalError: Code generation from strings disallowed for this context");
37 
38 // Extending Function with super() and no arguments is also allowed.
39 e.expectEval("class Foo extends Function { constructor() { super(); } }; typeof new Foo()",
40 "string", "function");
41 
42 e.getIsolate().runInLockScope([&](EvalIsolate::Lock& lock) { lock.setAllowEval(true); });
43 
44 e.expectEval("eval('123')", "number", "123");
45 e.expectEval("new Function('a', 'b', 'return a + b;')(123, 321)", "number", "444");
46 
47 e.getIsolate().runInLockScope([&](EvalIsolate::Lock& lock) { lock.setAllowEval(false); });
48 
49 e.expectEval("eval('123')", "throws",
50 "EvalError: Code generation from strings disallowed for this context");
51 e.expectEval("new Function('a', 'b', 'return a + b;')(123, 321)", "throws",
52 "EvalError: Code generation from strings disallowed for this context");
53 
54 // Note: It would be nice to test as well that WebAssembly is blocked, but that requires
55 // setting up an event loop since the WebAssembly calls are all async. We'll test this
56 // elsewhere.
57}
58 
59// ========================================================================================
60 
61struct ConfigContext: public Object, public ContextGlobal {
62 struct Nested: public Object {
63 JSG_RESOURCE_TYPE(Nested, int configuration) {
64 KJ_EXPECT(configuration == 123, configuration);
65 }
66 };
67 struct OtherNested: public Object {
68 JSG_RESOURCE_TYPE(OtherNested) {}
69 };
70 
71 JSG_RESOURCE_TYPE(ConfigContext) {
72 JSG_NESTED_TYPE(Nested);
73 JSG_NESTED_TYPE(OtherNested);
74 }
75};
76JSG_DECLARE_ISOLATE_TYPE(
77 ConfigIsolate, ConfigContext, ConfigContext::Nested, ConfigContext::OtherNested);
78 
79KJ_TEST("configuration values reach nested type declarations") {
80 {
81 ConfigIsolate isolate(
82 v8System, v8::IsolateGroup::GetDefault(), 123, kj::heap<IsolateObserver>());
83 isolate.runInLockScope([&](ConfigIsolate::Lock& lock) {
84 jsg::Lock& js = lock;
85 js.withinHandleScope([&] { lock.newContext<ConfigContext>().getHandle(lock); });
86 });
87 }
88 {
89 KJ_EXPECT_LOG(ERROR, "failed: expected configuration == 123");
90 ConfigIsolate isolate(
91 v8System, v8::IsolateGroup::GetDefault(), 456, kj::heap<IsolateObserver>());
92 isolate.runInLockScope([&](ConfigIsolate::Lock& lock) {
93 jsg::Lock& js = lock;
94 js.withinHandleScope([&] { lock.newContext<ConfigContext>().getHandle(lock); });
95 });
96 }
97}
98 
99} // namespace
100} // namespace workerd::jsg::test