@nyariv/sandboxjs 0.8.22 → 0.8.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +6 -0
- package/.eslintrc.js +22 -0
- package/.prettierrc +4 -0
- package/.vscode/settings.json +4 -0
- package/build/Sandbox.d.ts +11 -78
- package/build/Sandbox.js +21 -216
- package/build/SandboxExec.d.ts +25 -0
- package/build/SandboxExec.js +169 -0
- package/build/eval.d.ts +18 -0
- package/build/eval.js +43 -0
- package/build/executor.d.ts +56 -95
- package/build/executor.js +739 -815
- package/build/parser.d.ts +112 -74
- package/build/parser.js +504 -542
- package/build/unraw.js +13 -16
- package/build/utils.d.ts +242 -0
- package/build/utils.js +276 -0
- package/dist/Sandbox.d.ts +11 -78
- package/dist/Sandbox.js +106 -1
- package/dist/Sandbox.js.map +1 -1
- package/dist/Sandbox.min.js +1 -1
- package/dist/Sandbox.min.js.map +1 -1
- package/dist/SandboxExec.d.ts +25 -0
- package/dist/SandboxExec.js +173 -0
- package/dist/SandboxExec.js.map +1 -0
- package/dist/SandboxExec.min.js +2 -0
- package/dist/SandboxExec.min.js.map +1 -0
- package/dist/eval.d.ts +18 -0
- package/dist/executor.d.ts +56 -95
- package/dist/executor.js +1270 -0
- package/dist/executor.js.map +1 -0
- package/dist/node/Sandbox.d.ts +11 -78
- package/dist/node/Sandbox.js +37 -3091
- package/dist/node/SandboxExec.d.ts +25 -0
- package/dist/node/SandboxExec.js +176 -0
- package/dist/node/eval.d.ts +18 -0
- package/dist/node/executor.d.ts +56 -95
- package/dist/node/executor.js +1289 -0
- package/dist/node/parser.d.ts +112 -74
- package/dist/node/parser.js +1528 -0
- package/dist/node/utils.d.ts +242 -0
- package/dist/node/utils.js +290 -0
- package/dist/parser.d.ts +112 -74
- package/dist/parser.js +1514 -0
- package/dist/parser.js.map +1 -0
- package/dist/utils.d.ts +242 -0
- package/dist/utils.js +279 -0
- package/dist/utils.js.map +1 -0
- package/package.json +22 -14
- package/.github/workflows/npm-publish.yml +0 -34
package/build/executor.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CodeString, isLisp, LocalScope, Prop, SandboxError, Scope, } from './utils.js';
|
|
2
2
|
export class ExecReturn {
|
|
3
3
|
constructor(auditReport, result, returned, breakLoop = false, continueLoop = false) {
|
|
4
4
|
this.auditReport = auditReport;
|
|
@@ -8,154 +8,7 @@ export class ExecReturn {
|
|
|
8
8
|
this.continueLoop = continueLoop;
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
|
-
export class Prop {
|
|
12
|
-
constructor(context, prop, isConst = false, isGlobal = false, isVariable = false) {
|
|
13
|
-
this.context = context;
|
|
14
|
-
this.prop = prop;
|
|
15
|
-
this.isConst = isConst;
|
|
16
|
-
this.isGlobal = isGlobal;
|
|
17
|
-
this.isVariable = isVariable;
|
|
18
|
-
}
|
|
19
|
-
get(context) {
|
|
20
|
-
if (this.context === undefined)
|
|
21
|
-
throw new ReferenceError(`${this.prop} is not defined`);
|
|
22
|
-
context.getSubscriptions.forEach((cb) => cb(this.context, this.prop));
|
|
23
|
-
return this.context[this.prop];
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
11
|
const optional = {};
|
|
27
|
-
const reservedWords = new Set([
|
|
28
|
-
'instanceof',
|
|
29
|
-
'typeof',
|
|
30
|
-
'return',
|
|
31
|
-
'try',
|
|
32
|
-
'catch',
|
|
33
|
-
'if',
|
|
34
|
-
'finally',
|
|
35
|
-
'else',
|
|
36
|
-
'in',
|
|
37
|
-
'of',
|
|
38
|
-
'var',
|
|
39
|
-
'let',
|
|
40
|
-
'const',
|
|
41
|
-
'for',
|
|
42
|
-
'delete',
|
|
43
|
-
'false',
|
|
44
|
-
'true',
|
|
45
|
-
'while',
|
|
46
|
-
'do',
|
|
47
|
-
'break',
|
|
48
|
-
'continue',
|
|
49
|
-
'new',
|
|
50
|
-
'function',
|
|
51
|
-
'async',
|
|
52
|
-
'await',
|
|
53
|
-
'switch',
|
|
54
|
-
'case'
|
|
55
|
-
]);
|
|
56
|
-
var VarType;
|
|
57
|
-
(function (VarType) {
|
|
58
|
-
VarType["let"] = "let";
|
|
59
|
-
VarType["const"] = "const";
|
|
60
|
-
VarType["var"] = "var";
|
|
61
|
-
})(VarType || (VarType = {}));
|
|
62
|
-
function keysOnly(obj) {
|
|
63
|
-
const ret = Object.assign({}, obj);
|
|
64
|
-
for (let key in ret) {
|
|
65
|
-
ret[key] = true;
|
|
66
|
-
}
|
|
67
|
-
return ret;
|
|
68
|
-
}
|
|
69
|
-
export class Scope {
|
|
70
|
-
constructor(parent, vars = {}, functionThis) {
|
|
71
|
-
this.const = {};
|
|
72
|
-
this.let = {};
|
|
73
|
-
this.var = {};
|
|
74
|
-
const isFuncScope = functionThis !== undefined || parent === null;
|
|
75
|
-
this.parent = parent;
|
|
76
|
-
this.allVars = vars;
|
|
77
|
-
this.let = isFuncScope ? this.let : keysOnly(vars);
|
|
78
|
-
this.var = isFuncScope ? keysOnly(vars) : this.var;
|
|
79
|
-
this.globals = parent === null ? keysOnly(vars) : {};
|
|
80
|
-
this.functionThis = functionThis;
|
|
81
|
-
}
|
|
82
|
-
get(key, functionScope = false) {
|
|
83
|
-
if (key === 'this' && this.functionThis !== undefined) {
|
|
84
|
-
return new Prop({ this: this.functionThis }, key, true, false, true);
|
|
85
|
-
}
|
|
86
|
-
if (reservedWords.has(key))
|
|
87
|
-
throw new SyntaxError("Unexepected token '" + key + "'");
|
|
88
|
-
if (this.parent === null || !functionScope || this.functionThis !== undefined) {
|
|
89
|
-
if (this.globals.hasOwnProperty(key)) {
|
|
90
|
-
return new Prop(this.functionThis, key, false, true, true);
|
|
91
|
-
}
|
|
92
|
-
if (key in this.allVars && (!(key in {}) || this.allVars.hasOwnProperty(key))) {
|
|
93
|
-
return new Prop(this.allVars, key, this.const.hasOwnProperty(key), this.globals.hasOwnProperty(key), true);
|
|
94
|
-
}
|
|
95
|
-
if (this.parent === null) {
|
|
96
|
-
return new Prop(undefined, key);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return this.parent.get(key, functionScope);
|
|
100
|
-
}
|
|
101
|
-
set(key, val) {
|
|
102
|
-
if (key === 'this')
|
|
103
|
-
throw new SyntaxError('"this" cannot be assigned');
|
|
104
|
-
if (reservedWords.has(key))
|
|
105
|
-
throw new SyntaxError("Unexepected token '" + key + "'");
|
|
106
|
-
let prop = this.get(key);
|
|
107
|
-
if (prop.context === undefined) {
|
|
108
|
-
throw new ReferenceError(`Variable '${key}' was not declared.`);
|
|
109
|
-
}
|
|
110
|
-
if (prop.isConst) {
|
|
111
|
-
throw new TypeError(`Cannot assign to const variable '${key}'`);
|
|
112
|
-
}
|
|
113
|
-
if (prop.isGlobal) {
|
|
114
|
-
throw new SandboxError(`Cannot override global variable '${key}'`);
|
|
115
|
-
}
|
|
116
|
-
prop.context[prop.prop] = val;
|
|
117
|
-
return prop;
|
|
118
|
-
}
|
|
119
|
-
declare(key, type = null, value = undefined, isGlobal = false) {
|
|
120
|
-
if (key === 'this')
|
|
121
|
-
throw new SyntaxError('"this" cannot be declared');
|
|
122
|
-
if (reservedWords.has(key))
|
|
123
|
-
throw new SyntaxError("Unexepected token '" + key + "'");
|
|
124
|
-
if (type === 'var' && this.functionThis === undefined && this.parent !== null) {
|
|
125
|
-
return this.parent.declare(key, type, value, isGlobal);
|
|
126
|
-
}
|
|
127
|
-
else if ((this[type].hasOwnProperty(key) && type !== 'const' && !this.globals.hasOwnProperty(key)) || !(key in this.allVars)) {
|
|
128
|
-
if (isGlobal) {
|
|
129
|
-
this.globals[key] = true;
|
|
130
|
-
}
|
|
131
|
-
this[type][key] = true;
|
|
132
|
-
this.allVars[key] = value;
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
throw new SandboxError(`Identifier '${key}' has already been declared`);
|
|
136
|
-
}
|
|
137
|
-
return new Prop(this.allVars, key, this.const.hasOwnProperty(key), isGlobal);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
export class FunctionScope {
|
|
141
|
-
}
|
|
142
|
-
export class LocalScope {
|
|
143
|
-
}
|
|
144
|
-
export class SandboxError extends Error {
|
|
145
|
-
}
|
|
146
|
-
let currentTicks;
|
|
147
|
-
export function sandboxFunction(context, ticks) {
|
|
148
|
-
return SandboxFunction;
|
|
149
|
-
function SandboxFunction(...params) {
|
|
150
|
-
let code = params.pop() || "";
|
|
151
|
-
let parsed = parse(code);
|
|
152
|
-
return createFunction(params, parsed.tree, ticks || currentTicks, {
|
|
153
|
-
...context,
|
|
154
|
-
constants: parsed.constants,
|
|
155
|
-
tree: parsed.tree
|
|
156
|
-
}, undefined, 'anonymous');
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
12
|
function generateArgs(argNames, args) {
|
|
160
13
|
const vars = {};
|
|
161
14
|
argNames.forEach((arg, i) => {
|
|
@@ -168,10 +21,10 @@ function generateArgs(argNames, args) {
|
|
|
168
21
|
});
|
|
169
22
|
return vars;
|
|
170
23
|
}
|
|
171
|
-
const sandboxedFunctions = new WeakSet();
|
|
24
|
+
export const sandboxedFunctions = new WeakSet();
|
|
172
25
|
export function createFunction(argNames, parsed, ticks, context, scope, name) {
|
|
173
26
|
if (context.ctx.options.forbidFunctionCreation) {
|
|
174
|
-
throw new SandboxError(
|
|
27
|
+
throw new SandboxError('Function creation is forbidden');
|
|
175
28
|
}
|
|
176
29
|
let func;
|
|
177
30
|
if (name === undefined) {
|
|
@@ -193,12 +46,11 @@ export function createFunction(argNames, parsed, ticks, context, scope, name) {
|
|
|
193
46
|
return func;
|
|
194
47
|
}
|
|
195
48
|
export function createFunctionAsync(argNames, parsed, ticks, context, scope, name) {
|
|
196
|
-
var _a;
|
|
197
49
|
if (context.ctx.options.forbidFunctionCreation) {
|
|
198
|
-
throw new SandboxError(
|
|
50
|
+
throw new SandboxError('Function creation is forbidden');
|
|
199
51
|
}
|
|
200
|
-
if (!
|
|
201
|
-
throw new SandboxError(
|
|
52
|
+
if (!context.ctx.prototypeWhitelist?.has(Promise.prototype)) {
|
|
53
|
+
throw new SandboxError('Async/await not permitted');
|
|
202
54
|
}
|
|
203
55
|
let func;
|
|
204
56
|
if (name === undefined) {
|
|
@@ -219,28 +71,7 @@ export function createFunctionAsync(argNames, parsed, ticks, context, scope, nam
|
|
|
219
71
|
sandboxedFunctions.add(func);
|
|
220
72
|
return func;
|
|
221
73
|
}
|
|
222
|
-
export function sandboxedEval(func) {
|
|
223
|
-
return sandboxEval;
|
|
224
|
-
function sandboxEval(code) {
|
|
225
|
-
return func(code)();
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
export function sandboxedSetTimeout(func) {
|
|
229
|
-
return function sandboxSetTimeout(handler, ...args) {
|
|
230
|
-
if (typeof handler !== 'string')
|
|
231
|
-
return setTimeout(handler, ...args);
|
|
232
|
-
return setTimeout(func(handler), ...args);
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
export function sandboxedSetInterval(func) {
|
|
236
|
-
return function sandboxSetInterval(handler, ...args) {
|
|
237
|
-
if (typeof handler !== 'string')
|
|
238
|
-
return setInterval(handler, ...args);
|
|
239
|
-
return setInterval(func(handler), ...args);
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
74
|
export function assignCheck(obj, context, op = 'assign') {
|
|
243
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
244
75
|
if (obj.context === undefined) {
|
|
245
76
|
throw new ReferenceError(`Cannot ${op} value to undefined.`);
|
|
246
77
|
}
|
|
@@ -253,26 +84,43 @@ export function assignCheck(obj, context, op = 'assign') {
|
|
|
253
84
|
if (obj.isGlobal) {
|
|
254
85
|
throw new SandboxError(`Cannot ${op} property '${obj.prop}' of a global object`);
|
|
255
86
|
}
|
|
87
|
+
if (obj.context === null) {
|
|
88
|
+
throw new TypeError('Cannot set properties of null');
|
|
89
|
+
}
|
|
256
90
|
if (typeof obj.context[obj.prop] === 'function' && !obj.context.hasOwnProperty(obj.prop)) {
|
|
257
91
|
throw new SandboxError(`Override prototype property '${obj.prop}' not allowed`);
|
|
258
92
|
}
|
|
259
|
-
if (op ===
|
|
93
|
+
if (op === 'delete') {
|
|
260
94
|
if (obj.context.hasOwnProperty(obj.prop)) {
|
|
261
|
-
|
|
262
|
-
|
|
95
|
+
context.changeSubscriptions
|
|
96
|
+
.get(obj.context)
|
|
97
|
+
?.forEach((cb) => cb({ type: 'delete', prop: obj.prop }));
|
|
98
|
+
context.changeSubscriptionsGlobal
|
|
99
|
+
.get(obj.context)
|
|
100
|
+
?.forEach((cb) => cb({ type: 'delete', prop: obj.prop }));
|
|
263
101
|
}
|
|
264
102
|
}
|
|
265
103
|
else if (obj.context.hasOwnProperty(obj.prop)) {
|
|
266
|
-
|
|
267
|
-
|
|
104
|
+
context.setSubscriptions
|
|
105
|
+
.get(obj.context)
|
|
106
|
+
?.get(obj.prop)
|
|
107
|
+
?.forEach((cb) => cb({
|
|
108
|
+
type: 'replace',
|
|
268
109
|
}));
|
|
269
|
-
|
|
270
|
-
|
|
110
|
+
context.setSubscriptionsGlobal
|
|
111
|
+
.get(obj.context)
|
|
112
|
+
?.get(obj.prop)
|
|
113
|
+
?.forEach((cb) => cb({
|
|
114
|
+
type: 'replace',
|
|
271
115
|
}));
|
|
272
116
|
}
|
|
273
117
|
else {
|
|
274
|
-
|
|
275
|
-
|
|
118
|
+
context.changeSubscriptions
|
|
119
|
+
.get(obj.context)
|
|
120
|
+
?.forEach((cb) => cb({ type: 'create', prop: obj.prop }));
|
|
121
|
+
context.changeSubscriptionsGlobal
|
|
122
|
+
.get(obj.context)
|
|
123
|
+
?.forEach((cb) => cb({ type: 'create', prop: obj.prop }));
|
|
276
124
|
}
|
|
277
125
|
}
|
|
278
126
|
const arrayChange = new Set([
|
|
@@ -283,546 +131,552 @@ const arrayChange = new Set([
|
|
|
283
131
|
[].splice,
|
|
284
132
|
[].reverse,
|
|
285
133
|
[].sort,
|
|
286
|
-
[].copyWithin
|
|
134
|
+
[].copyWithin,
|
|
287
135
|
]);
|
|
136
|
+
export class KeyVal {
|
|
137
|
+
constructor(key, val) {
|
|
138
|
+
this.key = key;
|
|
139
|
+
this.val = val;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
export class SpreadObject {
|
|
143
|
+
constructor(item) {
|
|
144
|
+
this.item = item;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
export class SpreadArray {
|
|
148
|
+
constructor(item) {
|
|
149
|
+
this.item = item;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
export class If {
|
|
153
|
+
constructor(t, f) {
|
|
154
|
+
this.t = t;
|
|
155
|
+
this.f = f;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
288
158
|
const literalRegex = /(\$\$)*(\$)?\${(\d+)}/g;
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
done(undefined, rep);
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
159
|
+
export const ops = new Map();
|
|
160
|
+
export function addOps(type, cb) {
|
|
161
|
+
ops.set(type, cb);
|
|
162
|
+
}
|
|
163
|
+
addOps(1 /* LispType.Prop */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
164
|
+
if (a === null) {
|
|
165
|
+
throw new TypeError(`Cannot get property ${b} of null`);
|
|
166
|
+
}
|
|
167
|
+
const type = typeof a;
|
|
168
|
+
if (type === 'undefined' && obj === undefined) {
|
|
169
|
+
const prop = scope.get(b);
|
|
170
|
+
if (prop.context === context.ctx.sandboxGlobal) {
|
|
171
|
+
if (context.ctx.options.audit) {
|
|
172
|
+
context.ctx.auditReport?.globalsAccess.add(b);
|
|
306
173
|
}
|
|
307
|
-
|
|
308
|
-
|
|
174
|
+
const rep = context.ctx.globalsWhitelist.has(context.ctx.sandboxGlobal[b])
|
|
175
|
+
? context.evals.get(context.ctx.sandboxGlobal[b])
|
|
176
|
+
: undefined;
|
|
177
|
+
if (rep) {
|
|
178
|
+
done(undefined, rep);
|
|
309
179
|
return;
|
|
310
180
|
}
|
|
311
|
-
|
|
181
|
+
}
|
|
182
|
+
if (prop.context && prop.context[b] === globalThis) {
|
|
183
|
+
done(undefined, context.ctx.globalScope.get('this'));
|
|
312
184
|
return;
|
|
313
185
|
}
|
|
314
|
-
|
|
315
|
-
|
|
186
|
+
done(undefined, prop);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
else if (a === undefined) {
|
|
190
|
+
throw new SandboxError("Cannot get property '" + b + "' of undefined");
|
|
191
|
+
}
|
|
192
|
+
if (type !== 'object') {
|
|
193
|
+
if (type === 'number') {
|
|
194
|
+
a = new Number(a);
|
|
316
195
|
}
|
|
317
|
-
if (type
|
|
318
|
-
|
|
319
|
-
a = new Number(a);
|
|
320
|
-
}
|
|
321
|
-
else if (type === 'string') {
|
|
322
|
-
a = new String(a);
|
|
323
|
-
}
|
|
324
|
-
else if (type === 'boolean') {
|
|
325
|
-
a = new Boolean(a);
|
|
326
|
-
}
|
|
196
|
+
else if (type === 'string') {
|
|
197
|
+
a = new String(a);
|
|
327
198
|
}
|
|
328
|
-
else if (
|
|
329
|
-
|
|
330
|
-
return;
|
|
199
|
+
else if (type === 'boolean') {
|
|
200
|
+
a = new Boolean(a);
|
|
331
201
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
202
|
+
}
|
|
203
|
+
else if (typeof a.hasOwnProperty === 'undefined') {
|
|
204
|
+
done(undefined, new Prop(undefined, b));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const isFunction = type === 'function';
|
|
208
|
+
const prototypeAccess = isFunction || !(a.hasOwnProperty(b) || typeof b === 'number');
|
|
209
|
+
if (context.ctx.options.audit && prototypeAccess) {
|
|
210
|
+
if (typeof b === 'string') {
|
|
211
|
+
let prot = Object.getPrototypeOf(a);
|
|
212
|
+
do {
|
|
213
|
+
if (prot.hasOwnProperty(b)) {
|
|
214
|
+
if (context.ctx.auditReport &&
|
|
215
|
+
!context.ctx.auditReport.prototypeAccess[prot.constructor.name]) {
|
|
216
|
+
context.ctx.auditReport.prototypeAccess[prot.constructor.name] = new Set();
|
|
343
217
|
}
|
|
344
|
-
|
|
218
|
+
context.ctx.auditReport?.prototypeAccess[prot.constructor.name].add(b);
|
|
219
|
+
}
|
|
220
|
+
} while ((prot = Object.getPrototypeOf(prot)));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (prototypeAccess) {
|
|
224
|
+
if (isFunction) {
|
|
225
|
+
if (!['name', 'length', 'constructor'].includes(b) && (a.hasOwnProperty(b) || b === '__proto__')) {
|
|
226
|
+
const whitelist = context.ctx.prototypeWhitelist.get(a.prototype);
|
|
227
|
+
const replace = context.ctx.options.prototypeReplacements.get(a);
|
|
228
|
+
if (replace) {
|
|
229
|
+
done(undefined, new Prop(replace(a, true), b));
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (!(whitelist && (!whitelist.size || whitelist.has(b)))) {
|
|
233
|
+
throw new SandboxError(`Static method or property access not permitted: ${a.name}.${b}`);
|
|
234
|
+
}
|
|
345
235
|
}
|
|
346
236
|
}
|
|
347
|
-
if (
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
const
|
|
237
|
+
else if (b !== 'constructor') {
|
|
238
|
+
let prot = a;
|
|
239
|
+
while ((prot = Object.getPrototypeOf(prot))) {
|
|
240
|
+
if (prot.hasOwnProperty(b)) {
|
|
241
|
+
const whitelist = context.ctx.prototypeWhitelist.get(prot);
|
|
242
|
+
const replace = context.ctx.options.prototypeReplacements.get(prot.constuctor);
|
|
352
243
|
if (replace) {
|
|
353
|
-
done(undefined, new Prop(replace(a,
|
|
244
|
+
done(undefined, new Prop(replace(a, false), b));
|
|
354
245
|
return;
|
|
355
246
|
}
|
|
356
247
|
if (whitelist && (!whitelist.size || whitelist.has(b))) {
|
|
248
|
+
break;
|
|
357
249
|
}
|
|
358
|
-
|
|
359
|
-
throw new SandboxError(`Static method or property access not permitted: ${a.name}.${b}`);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
else if (b !== 'constructor') {
|
|
364
|
-
let prot = a;
|
|
365
|
-
while (prot = Object.getPrototypeOf(prot)) {
|
|
366
|
-
if (prot.hasOwnProperty(b)) {
|
|
367
|
-
const whitelist = context.ctx.prototypeWhitelist.get(prot);
|
|
368
|
-
const replace = context.ctx.options.prototypeReplacements.get(prot.constuctor);
|
|
369
|
-
if (replace) {
|
|
370
|
-
done(undefined, new Prop(replace(a, false), b));
|
|
371
|
-
return;
|
|
372
|
-
}
|
|
373
|
-
if (whitelist && (!whitelist.size || whitelist.has(b))) {
|
|
374
|
-
break;
|
|
375
|
-
}
|
|
376
|
-
throw new SandboxError(`Method or property access not permitted: ${prot.constructor.name}.${b}`);
|
|
377
|
-
}
|
|
250
|
+
throw new SandboxError(`Method or property access not permitted: ${prot.constructor.name}.${b}`);
|
|
378
251
|
}
|
|
379
|
-
;
|
|
380
252
|
}
|
|
381
253
|
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
254
|
+
}
|
|
255
|
+
if (context.evals.has(a[b])) {
|
|
256
|
+
done(undefined, context.evals.get(a[b]));
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (a[b] === globalThis) {
|
|
260
|
+
done(undefined, context.ctx.globalScope.get('this'));
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
const g = obj.isGlobal ||
|
|
264
|
+
(isFunction && !sandboxedFunctions.has(a)) ||
|
|
265
|
+
context.ctx.globalsWhitelist.has(a);
|
|
266
|
+
done(undefined, new Prop(a, b, false, g));
|
|
267
|
+
});
|
|
268
|
+
addOps(5 /* LispType.Call */, (exec, done, ticks, a, b, obj, context) => {
|
|
269
|
+
if (context.ctx.options.forbidFunctionCalls)
|
|
270
|
+
throw new SandboxError('Function invocations are not allowed');
|
|
271
|
+
if (typeof a !== 'function') {
|
|
272
|
+
throw new TypeError(`${typeof obj.prop === 'symbol' ? 'Symbol' : obj.prop} is not a function`);
|
|
273
|
+
}
|
|
274
|
+
const vals = b
|
|
275
|
+
.map((item) => {
|
|
276
|
+
if (item instanceof SpreadArray) {
|
|
277
|
+
return [...item.item];
|
|
385
278
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
return;
|
|
279
|
+
else {
|
|
280
|
+
return [item];
|
|
389
281
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
const
|
|
400
|
-
if (
|
|
401
|
-
return [...item.item];
|
|
402
|
-
}
|
|
403
|
-
else {
|
|
404
|
-
return [item];
|
|
405
|
-
}
|
|
406
|
-
}).flat();
|
|
407
|
-
execMany(ticks, exec, toLispArray(args), (err, vals) => {
|
|
408
|
-
var _a, _b;
|
|
409
|
-
if (err) {
|
|
410
|
-
done(err);
|
|
411
|
-
return;
|
|
412
|
-
}
|
|
413
|
-
if (typeof obj === 'function') {
|
|
414
|
-
done(undefined, obj(...vals));
|
|
282
|
+
})
|
|
283
|
+
.flat()
|
|
284
|
+
.map((item) => valueOrProp(item, context));
|
|
285
|
+
if (typeof obj === 'function') {
|
|
286
|
+
done(undefined, obj(...vals));
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
if (obj.context[obj.prop] === JSON.stringify && context.getSubscriptions.size) {
|
|
290
|
+
const cache = new Set();
|
|
291
|
+
const recurse = (x) => {
|
|
292
|
+
if (!x || !(typeof x === 'object') || cache.has(x))
|
|
415
293
|
return;
|
|
294
|
+
cache.add(x);
|
|
295
|
+
for (const y of Object.keys(x)) {
|
|
296
|
+
context.getSubscriptions.forEach((cb) => cb(x, y));
|
|
297
|
+
recurse(x[y]);
|
|
416
298
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
changed = !!change.added.length || !!change.removed.length;
|
|
485
|
-
}
|
|
486
|
-
if (changed) {
|
|
487
|
-
(_a = context.changeSubscriptions.get(obj.context)) === null || _a === void 0 ? void 0 : _a.forEach((cb) => cb(change));
|
|
488
|
-
(_b = context.changeSubscriptionsGlobal.get(obj.context)) === null || _b === void 0 ? void 0 : _b.forEach((cb) => cb(change));
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
obj.get(context);
|
|
492
|
-
done(undefined, obj.context[obj.prop](...vals));
|
|
493
|
-
}, scope, context);
|
|
494
|
-
},
|
|
495
|
-
'createObject': (exec, done, ticks, a, b, obj, context, scope) => {
|
|
496
|
-
let res = {};
|
|
497
|
-
for (let item of b) {
|
|
498
|
-
if (item instanceof SpreadObject) {
|
|
499
|
-
res = { ...res, ...item.item };
|
|
500
|
-
}
|
|
501
|
-
else {
|
|
502
|
-
res[item.key] = item.val;
|
|
503
|
-
}
|
|
299
|
+
};
|
|
300
|
+
recurse(vals[0]);
|
|
301
|
+
}
|
|
302
|
+
if (obj.context instanceof Array &&
|
|
303
|
+
arrayChange.has(obj.context[obj.prop]) &&
|
|
304
|
+
(context.changeSubscriptions.get(obj.context) ||
|
|
305
|
+
context.changeSubscriptionsGlobal.get(obj.context))) {
|
|
306
|
+
let change;
|
|
307
|
+
let changed = false;
|
|
308
|
+
if (obj.prop === 'push') {
|
|
309
|
+
change = {
|
|
310
|
+
type: 'push',
|
|
311
|
+
added: vals,
|
|
312
|
+
};
|
|
313
|
+
changed = !!vals.length;
|
|
314
|
+
}
|
|
315
|
+
else if (obj.prop === 'pop') {
|
|
316
|
+
change = {
|
|
317
|
+
type: 'pop',
|
|
318
|
+
removed: obj.context.slice(-1),
|
|
319
|
+
};
|
|
320
|
+
changed = !!change.removed.length;
|
|
321
|
+
}
|
|
322
|
+
else if (obj.prop === 'shift') {
|
|
323
|
+
change = {
|
|
324
|
+
type: 'shift',
|
|
325
|
+
removed: obj.context.slice(0, 1),
|
|
326
|
+
};
|
|
327
|
+
changed = !!change.removed.length;
|
|
328
|
+
}
|
|
329
|
+
else if (obj.prop === 'unshift') {
|
|
330
|
+
change = {
|
|
331
|
+
type: 'unshift',
|
|
332
|
+
added: vals,
|
|
333
|
+
};
|
|
334
|
+
changed = !!vals.length;
|
|
335
|
+
}
|
|
336
|
+
else if (obj.prop === 'splice') {
|
|
337
|
+
change = {
|
|
338
|
+
type: 'splice',
|
|
339
|
+
startIndex: vals[0],
|
|
340
|
+
deleteCount: vals[1] === undefined ? obj.context.length : vals[1],
|
|
341
|
+
added: vals.slice(2),
|
|
342
|
+
removed: obj.context.slice(vals[0], vals[1] === undefined ? undefined : vals[0] + vals[1]),
|
|
343
|
+
};
|
|
344
|
+
changed = !!change.added.length || !!change.removed.length;
|
|
345
|
+
}
|
|
346
|
+
else if (obj.prop === 'reverse' || obj.prop === 'sort') {
|
|
347
|
+
change = { type: obj.prop };
|
|
348
|
+
changed = !!obj.context.length;
|
|
349
|
+
}
|
|
350
|
+
else if (obj.prop === 'copyWithin') {
|
|
351
|
+
const len = vals[2] === undefined
|
|
352
|
+
? obj.context.length - vals[1]
|
|
353
|
+
: Math.min(obj.context.length, vals[2] - vals[1]);
|
|
354
|
+
change = {
|
|
355
|
+
type: 'copyWithin',
|
|
356
|
+
startIndex: vals[0],
|
|
357
|
+
endIndex: vals[0] + len,
|
|
358
|
+
added: obj.context.slice(vals[1], vals[1] + len),
|
|
359
|
+
removed: obj.context.slice(vals[0], vals[0] + len),
|
|
360
|
+
};
|
|
361
|
+
changed = !!change.added.length || !!change.removed.length;
|
|
362
|
+
}
|
|
363
|
+
if (changed) {
|
|
364
|
+
context.changeSubscriptions.get(obj.context)?.forEach((cb) => cb(change));
|
|
365
|
+
context.changeSubscriptionsGlobal.get(obj.context)?.forEach((cb) => cb(change));
|
|
504
366
|
}
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
return [item];
|
|
515
|
-
}
|
|
516
|
-
}).flat();
|
|
517
|
-
execMany(ticks, exec, toLispArray(items), done, scope, context);
|
|
518
|
-
},
|
|
519
|
-
'group': (exec, done, ticks, a, b) => done(undefined, b),
|
|
520
|
-
'string': (exec, done, ticks, a, b, obj, context) => done(undefined, context.constants.strings[b]),
|
|
521
|
-
'regex': (exec, done, ticks, a, b, obj, context) => {
|
|
522
|
-
const reg = context.constants.regexes[b];
|
|
523
|
-
if (!context.ctx.globalsWhitelist.has(RegExp)) {
|
|
524
|
-
throw new SandboxError("Regex not permitted");
|
|
367
|
+
}
|
|
368
|
+
obj.get(context);
|
|
369
|
+
done(undefined, obj.context[obj.prop](...vals));
|
|
370
|
+
});
|
|
371
|
+
addOps(22 /* LispType.CreateObject */, (exec, done, ticks, a, b) => {
|
|
372
|
+
let res = {};
|
|
373
|
+
for (const item of b) {
|
|
374
|
+
if (item.key instanceof SpreadObject) {
|
|
375
|
+
res = { ...res, ...item.key.item };
|
|
525
376
|
}
|
|
526
377
|
else {
|
|
527
|
-
|
|
528
|
-
}
|
|
529
|
-
},
|
|
530
|
-
'literal': (exec, done, ticks, a, b, obj, context, scope) => {
|
|
531
|
-
let name = context.constants.literals[b].a;
|
|
532
|
-
let found = toLispArray([]);
|
|
533
|
-
let f;
|
|
534
|
-
let resnums = [];
|
|
535
|
-
while (f = literalRegex.exec(name)) {
|
|
536
|
-
if (!f[2]) {
|
|
537
|
-
found.push(context.constants.literals[b].b[parseInt(f[3], 10)]);
|
|
538
|
-
resnums.push(f[3]);
|
|
539
|
-
}
|
|
378
|
+
res[item.key] = item.val;
|
|
540
379
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
done(undefined,
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
'+=': (exec, done, ticks, a, b, obj, context) => {
|
|
600
|
-
assignCheck(obj, context);
|
|
601
|
-
done(undefined, obj.context[obj.prop] += b);
|
|
602
|
-
},
|
|
603
|
-
'-=': (exec, done, ticks, a, b, obj, context) => {
|
|
604
|
-
assignCheck(obj, context);
|
|
605
|
-
done(undefined, obj.context[obj.prop] -= b);
|
|
606
|
-
},
|
|
607
|
-
'/=': (exec, done, ticks, a, b, obj, context) => {
|
|
608
|
-
assignCheck(obj, context);
|
|
609
|
-
done(undefined, obj.context[obj.prop] /= b);
|
|
610
|
-
},
|
|
611
|
-
'*=': (exec, done, ticks, a, b, obj, context) => {
|
|
612
|
-
assignCheck(obj, context);
|
|
613
|
-
done(undefined, obj.context[obj.prop] *= b);
|
|
614
|
-
},
|
|
615
|
-
'**=': (exec, done, ticks, a, b, obj, context) => {
|
|
616
|
-
assignCheck(obj, context);
|
|
617
|
-
done(undefined, obj.context[obj.prop] **= b);
|
|
618
|
-
},
|
|
619
|
-
'%=': (exec, done, ticks, a, b, obj, context) => {
|
|
620
|
-
assignCheck(obj, context);
|
|
621
|
-
done(undefined, obj.context[obj.prop] %= b);
|
|
622
|
-
},
|
|
623
|
-
'^=': (exec, done, ticks, a, b, obj, context) => {
|
|
624
|
-
assignCheck(obj, context);
|
|
625
|
-
done(undefined, obj.context[obj.prop] ^= b);
|
|
626
|
-
},
|
|
627
|
-
'&=': (exec, done, ticks, a, b, obj, context) => {
|
|
628
|
-
assignCheck(obj, context);
|
|
629
|
-
done(undefined, obj.context[obj.prop] &= b);
|
|
630
|
-
},
|
|
631
|
-
'|=': (exec, done, ticks, a, b, obj, context) => {
|
|
632
|
-
assignCheck(obj, context);
|
|
633
|
-
done(undefined, obj.context[obj.prop] |= b);
|
|
634
|
-
},
|
|
635
|
-
'<<=': (exec, done, ticks, a, b, obj, context) => {
|
|
636
|
-
assignCheck(obj, context);
|
|
637
|
-
done(undefined, obj.context[obj.prop] <<= b);
|
|
638
|
-
},
|
|
639
|
-
'>>=': (exec, done, ticks, a, b, obj, context) => {
|
|
640
|
-
assignCheck(obj, context);
|
|
641
|
-
done(undefined, obj.context[obj.prop] >>= b);
|
|
642
|
-
},
|
|
643
|
-
'>>>=': (exec, done, ticks, a, b, obj, context) => {
|
|
644
|
-
assignCheck(obj, context);
|
|
645
|
-
done(undefined, obj.context[obj.prop] >>= b);
|
|
646
|
-
},
|
|
647
|
-
'?': (exec, done, ticks, a, b, obj, context, scope) => {
|
|
648
|
-
if (!(b instanceof If)) {
|
|
649
|
-
throw new SyntaxError('Invalid inline if');
|
|
650
|
-
}
|
|
651
|
-
exec(ticks, a, scope, context, (err, res) => {
|
|
652
|
-
if (err) {
|
|
653
|
-
done(err);
|
|
654
|
-
}
|
|
655
|
-
else {
|
|
656
|
-
exec(ticks, valueOrProp(res, context) ? b.t : b.f, scope, context, done);
|
|
657
|
-
}
|
|
658
|
-
});
|
|
659
|
-
},
|
|
660
|
-
'>': (exec, done, ticks, a, b) => done(undefined, a > b),
|
|
661
|
-
'<': (exec, done, ticks, a, b) => done(undefined, a < b),
|
|
662
|
-
'>=': (exec, done, ticks, a, b) => done(undefined, a >= b),
|
|
663
|
-
'<=': (exec, done, ticks, a, b) => done(undefined, a <= b),
|
|
664
|
-
'==': (exec, done, ticks, a, b) => done(undefined, a == b),
|
|
665
|
-
'===': (exec, done, ticks, a, b) => done(undefined, a === b),
|
|
666
|
-
'!=': (exec, done, ticks, a, b) => done(undefined, a != b),
|
|
667
|
-
'!==': (exec, done, ticks, a, b) => done(undefined, a !== b),
|
|
668
|
-
'&&': (exec, done, ticks, a, b) => done(undefined, a && b),
|
|
669
|
-
'||': (exec, done, ticks, a, b) => done(undefined, a || b),
|
|
670
|
-
'&': (exec, done, ticks, a, b) => done(undefined, a & b),
|
|
671
|
-
'|': (exec, done, ticks, a, b) => done(undefined, a | b),
|
|
672
|
-
':': (exec, done, ticks, a, b) => done(undefined, new If(a, b)),
|
|
673
|
-
'+': (exec, done, ticks, a, b) => done(undefined, a + b),
|
|
674
|
-
'-': (exec, done, ticks, a, b) => done(undefined, a - b),
|
|
675
|
-
'$+': (exec, done, ticks, a, b) => done(undefined, +b),
|
|
676
|
-
'$-': (exec, done, ticks, a, b) => done(undefined, -b),
|
|
677
|
-
'/': (exec, done, ticks, a, b) => done(undefined, a / b),
|
|
678
|
-
'^': (exec, done, ticks, a, b) => done(undefined, a ^ b),
|
|
679
|
-
'*': (exec, done, ticks, a, b) => done(undefined, a * b),
|
|
680
|
-
'%': (exec, done, ticks, a, b) => done(undefined, a % b),
|
|
681
|
-
'<<': (exec, done, ticks, a, b) => done(undefined, a << b),
|
|
682
|
-
'>>': (exec, done, ticks, a, b) => done(undefined, a >> b),
|
|
683
|
-
'>>>': (exec, done, ticks, a, b) => done(undefined, a >>> b),
|
|
684
|
-
'typeof': (exec, done, ticks, a, b, obj, context, scope) => {
|
|
685
|
-
exec(ticks, b, scope, context, (e, prop) => {
|
|
686
|
-
done(undefined, typeof valueOrProp(prop, context));
|
|
687
|
-
});
|
|
688
|
-
},
|
|
689
|
-
'instanceof': (exec, done, ticks, a, b) => done(undefined, a instanceof b),
|
|
690
|
-
'in': (exec, done, ticks, a, b) => done(undefined, a in b),
|
|
691
|
-
'delete': (exec, done, ticks, a, b, obj, context, scope, bobj) => {
|
|
692
|
-
if (bobj.context === undefined) {
|
|
693
|
-
done(undefined, true);
|
|
694
|
-
return;
|
|
380
|
+
}
|
|
381
|
+
done(undefined, res);
|
|
382
|
+
});
|
|
383
|
+
addOps(6 /* LispType.KeyVal */, (exec, done, ticks, a, b) => done(undefined, new KeyVal(a, b)));
|
|
384
|
+
addOps(12 /* LispType.CreateArray */, (exec, done, ticks, a, b, obj, context) => {
|
|
385
|
+
const items = b
|
|
386
|
+
.map((item) => {
|
|
387
|
+
if (item instanceof SpreadArray) {
|
|
388
|
+
return [...item.item];
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
return [item];
|
|
392
|
+
}
|
|
393
|
+
})
|
|
394
|
+
.flat()
|
|
395
|
+
.map((item) => valueOrProp(item, context));
|
|
396
|
+
done(undefined, items);
|
|
397
|
+
});
|
|
398
|
+
addOps(23 /* LispType.Group */, (exec, done, ticks, a, b) => done(undefined, b));
|
|
399
|
+
addOps(35 /* LispType.GlobalSymbol */, (exec, done, ticks, a, b) => {
|
|
400
|
+
switch (b) {
|
|
401
|
+
case 'true':
|
|
402
|
+
return done(undefined, true);
|
|
403
|
+
case 'false':
|
|
404
|
+
return done(undefined, false);
|
|
405
|
+
case 'null':
|
|
406
|
+
return done(undefined, null);
|
|
407
|
+
case 'undefined':
|
|
408
|
+
return done(undefined, undefined);
|
|
409
|
+
case 'NaN':
|
|
410
|
+
return done(undefined, NaN);
|
|
411
|
+
case 'Infinity':
|
|
412
|
+
return done(undefined, Infinity);
|
|
413
|
+
}
|
|
414
|
+
done(new Error('Unknown symbol: ' + b));
|
|
415
|
+
});
|
|
416
|
+
addOps(7 /* LispType.Number */, (exec, done, ticks, a, b) => done(undefined, Number(b)));
|
|
417
|
+
addOps(83 /* LispType.BigInt */, (exec, done, ticks, a, b) => done(undefined, BigInt(b)));
|
|
418
|
+
addOps(2 /* LispType.StringIndex */, (exec, done, ticks, a, b, obj, context) => done(undefined, context.constants.strings[parseInt(b)]));
|
|
419
|
+
addOps(85 /* LispType.RegexIndex */, (exec, done, ticks, a, b, obj, context) => {
|
|
420
|
+
const reg = context.constants.regexes[parseInt(b)];
|
|
421
|
+
if (!context.ctx.globalsWhitelist.has(RegExp)) {
|
|
422
|
+
throw new SandboxError('Regex not permitted');
|
|
423
|
+
}
|
|
424
|
+
else {
|
|
425
|
+
done(undefined, new RegExp(reg.regex, reg.flags));
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
addOps(84 /* LispType.LiteralIndex */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
429
|
+
const item = context.constants.literals[parseInt(b)];
|
|
430
|
+
const [, name, js] = item;
|
|
431
|
+
const found = [];
|
|
432
|
+
let f;
|
|
433
|
+
const resnums = [];
|
|
434
|
+
while ((f = literalRegex.exec(name))) {
|
|
435
|
+
if (!f[2]) {
|
|
436
|
+
found.push(js[parseInt(f[3], 10)]);
|
|
437
|
+
resnums.push(f[3]);
|
|
695
438
|
}
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
439
|
+
}
|
|
440
|
+
exec(ticks, found, scope, context, (err, processed) => {
|
|
441
|
+
const reses = {};
|
|
442
|
+
if (err) {
|
|
443
|
+
done(err);
|
|
699
444
|
return;
|
|
700
445
|
}
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
'var': (exec, done, ticks, a, b, obj, context, scope, bobj) => {
|
|
705
|
-
exec(ticks, b, scope, context, (err, res) => {
|
|
706
|
-
if (err) {
|
|
707
|
-
done(err);
|
|
708
|
-
return;
|
|
709
|
-
}
|
|
710
|
-
done(undefined, scope.declare(a, VarType.var, res));
|
|
711
|
-
});
|
|
712
|
-
},
|
|
713
|
-
'let': (exec, done, ticks, a, b, obj, context, scope, bobj) => {
|
|
714
|
-
exec(ticks, b, scope, context, (err, res) => {
|
|
715
|
-
if (err) {
|
|
716
|
-
done(err);
|
|
717
|
-
return;
|
|
718
|
-
}
|
|
719
|
-
done(undefined, scope.declare(a, VarType.let, res, bobj && bobj.isGlobal));
|
|
720
|
-
});
|
|
721
|
-
},
|
|
722
|
-
'const': (exec, done, ticks, a, b, obj, context, scope, bobj) => {
|
|
723
|
-
exec(ticks, b, scope, context, (err, res) => {
|
|
724
|
-
if (err) {
|
|
725
|
-
done(err);
|
|
726
|
-
return;
|
|
727
|
-
}
|
|
728
|
-
done(undefined, scope.declare(a, VarType.const, res));
|
|
729
|
-
});
|
|
730
|
-
},
|
|
731
|
-
'arrowFunc': (exec, done, ticks, a, b, obj, context, scope) => {
|
|
732
|
-
a = [...a];
|
|
733
|
-
if (typeof obj.b === "string" || obj.b instanceof CodeString) {
|
|
734
|
-
obj.b = b = lispifyFunction(new CodeString(obj.b), context.constants);
|
|
446
|
+
for (const i of Object.keys(processed)) {
|
|
447
|
+
const num = resnums[i];
|
|
448
|
+
reses[num] = processed[i];
|
|
735
449
|
}
|
|
736
|
-
|
|
737
|
-
|
|
450
|
+
done(undefined, name.replace(/(\\\\)*(\\)?\${(\d+)}/g, (match, $$, $, num) => {
|
|
451
|
+
if ($)
|
|
452
|
+
return match;
|
|
453
|
+
const res = reses[num];
|
|
454
|
+
return ($$ ? $$ : '') + `${valueOrProp(res, context)}`;
|
|
455
|
+
}));
|
|
456
|
+
});
|
|
457
|
+
});
|
|
458
|
+
addOps(18 /* LispType.SpreadArray */, (exec, done, ticks, a, b) => {
|
|
459
|
+
done(undefined, new SpreadArray(b));
|
|
460
|
+
});
|
|
461
|
+
addOps(17 /* LispType.SpreadObject */, (exec, done, ticks, a, b) => {
|
|
462
|
+
done(undefined, new SpreadObject(b));
|
|
463
|
+
});
|
|
464
|
+
addOps(24 /* LispType.Not */, (exec, done, ticks, a, b) => done(undefined, !b));
|
|
465
|
+
addOps(64 /* LispType.Inverse */, (exec, done, ticks, a, b) => done(undefined, ~b));
|
|
466
|
+
addOps(25 /* LispType.IncrementBefore */, (exec, done, ticks, a, b, obj, context) => {
|
|
467
|
+
assignCheck(obj, context);
|
|
468
|
+
done(undefined, ++obj.context[obj.prop]);
|
|
469
|
+
});
|
|
470
|
+
addOps(26 /* LispType.IncrementAfter */, (exec, done, ticks, a, b, obj, context) => {
|
|
471
|
+
assignCheck(obj, context);
|
|
472
|
+
done(undefined, obj.context[obj.prop]++);
|
|
473
|
+
});
|
|
474
|
+
addOps(27 /* LispType.DecrementBefore */, (exec, done, ticks, a, b, obj, context) => {
|
|
475
|
+
assignCheck(obj, context);
|
|
476
|
+
done(undefined, --obj.context[obj.prop]);
|
|
477
|
+
});
|
|
478
|
+
addOps(28 /* LispType.DecrementAfter */, (exec, done, ticks, a, b, obj, context) => {
|
|
479
|
+
assignCheck(obj, context);
|
|
480
|
+
done(undefined, obj.context[obj.prop]--);
|
|
481
|
+
});
|
|
482
|
+
addOps(9 /* LispType.Assign */, (exec, done, ticks, a, b, obj, context) => {
|
|
483
|
+
assignCheck(obj, context);
|
|
484
|
+
done(undefined, (obj.context[obj.prop] = b));
|
|
485
|
+
});
|
|
486
|
+
addOps(66 /* LispType.AddEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
487
|
+
assignCheck(obj, context);
|
|
488
|
+
done(undefined, (obj.context[obj.prop] += b));
|
|
489
|
+
});
|
|
490
|
+
addOps(65 /* LispType.SubractEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
491
|
+
assignCheck(obj, context);
|
|
492
|
+
done(undefined, (obj.context[obj.prop] -= b));
|
|
493
|
+
});
|
|
494
|
+
addOps(67 /* LispType.DivideEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
495
|
+
assignCheck(obj, context);
|
|
496
|
+
done(undefined, (obj.context[obj.prop] /= b));
|
|
497
|
+
});
|
|
498
|
+
addOps(69 /* LispType.MultiplyEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
499
|
+
assignCheck(obj, context);
|
|
500
|
+
done(undefined, (obj.context[obj.prop] *= b));
|
|
501
|
+
});
|
|
502
|
+
addOps(68 /* LispType.PowerEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
503
|
+
assignCheck(obj, context);
|
|
504
|
+
done(undefined, (obj.context[obj.prop] **= b));
|
|
505
|
+
});
|
|
506
|
+
addOps(70 /* LispType.ModulusEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
507
|
+
assignCheck(obj, context);
|
|
508
|
+
done(undefined, (obj.context[obj.prop] %= b));
|
|
509
|
+
});
|
|
510
|
+
addOps(71 /* LispType.BitNegateEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
511
|
+
assignCheck(obj, context);
|
|
512
|
+
done(undefined, (obj.context[obj.prop] ^= b));
|
|
513
|
+
});
|
|
514
|
+
addOps(72 /* LispType.BitAndEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
515
|
+
assignCheck(obj, context);
|
|
516
|
+
done(undefined, (obj.context[obj.prop] &= b));
|
|
517
|
+
});
|
|
518
|
+
addOps(73 /* LispType.BitOrEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
519
|
+
assignCheck(obj, context);
|
|
520
|
+
done(undefined, (obj.context[obj.prop] |= b));
|
|
521
|
+
});
|
|
522
|
+
addOps(76 /* LispType.ShiftLeftEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
523
|
+
assignCheck(obj, context);
|
|
524
|
+
done(undefined, (obj.context[obj.prop] <<= b));
|
|
525
|
+
});
|
|
526
|
+
addOps(75 /* LispType.ShiftRightEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
527
|
+
assignCheck(obj, context);
|
|
528
|
+
done(undefined, (obj.context[obj.prop] >>= b));
|
|
529
|
+
});
|
|
530
|
+
addOps(74 /* LispType.UnsignedShiftRightEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
531
|
+
assignCheck(obj, context);
|
|
532
|
+
done(undefined, (obj.context[obj.prop] >>= b));
|
|
533
|
+
});
|
|
534
|
+
addOps(57 /* LispType.LargerThan */, (exec, done, ticks, a, b) => done(undefined, a > b));
|
|
535
|
+
addOps(56 /* LispType.SmallerThan */, (exec, done, ticks, a, b) => done(undefined, a < b));
|
|
536
|
+
addOps(55 /* LispType.LargerEqualThan */, (exec, done, ticks, a, b) => done(undefined, a >= b));
|
|
537
|
+
addOps(54 /* LispType.SmallerEqualThan */, (exec, done, ticks, a, b) => done(undefined, a <= b));
|
|
538
|
+
addOps(52 /* LispType.Equal */, (exec, done, ticks, a, b) => done(undefined, a == b));
|
|
539
|
+
addOps(32 /* LispType.StrictEqual */, (exec, done, ticks, a, b) => done(undefined, a === b));
|
|
540
|
+
addOps(53 /* LispType.NotEqual */, (exec, done, ticks, a, b) => done(undefined, a != b));
|
|
541
|
+
addOps(31 /* LispType.StrictNotEqual */, (exec, done, ticks, a, b) => done(undefined, a !== b));
|
|
542
|
+
addOps(29 /* LispType.And */, (exec, done, ticks, a, b) => done(undefined, a && b));
|
|
543
|
+
addOps(30 /* LispType.Or */, (exec, done, ticks, a, b) => done(undefined, a || b));
|
|
544
|
+
addOps(77 /* LispType.BitAnd */, (exec, done, ticks, a, b) => done(undefined, a & b));
|
|
545
|
+
addOps(78 /* LispType.BitOr */, (exec, done, ticks, a, b) => done(undefined, a | b));
|
|
546
|
+
addOps(33 /* LispType.Plus */, (exec, done, ticks, a, b) => done(undefined, a + b));
|
|
547
|
+
addOps(47 /* LispType.Minus */, (exec, done, ticks, a, b) => done(undefined, a - b));
|
|
548
|
+
addOps(59 /* LispType.Positive */, (exec, done, ticks, a, b) => done(undefined, +b));
|
|
549
|
+
addOps(58 /* LispType.Negative */, (exec, done, ticks, a, b) => done(undefined, -b));
|
|
550
|
+
addOps(48 /* LispType.Divide */, (exec, done, ticks, a, b) => done(undefined, a / b));
|
|
551
|
+
addOps(79 /* LispType.BitNegate */, (exec, done, ticks, a, b) => done(undefined, a ^ b));
|
|
552
|
+
addOps(50 /* LispType.Multiply */, (exec, done, ticks, a, b) => done(undefined, a * b));
|
|
553
|
+
addOps(51 /* LispType.Modulus */, (exec, done, ticks, a, b) => done(undefined, a % b));
|
|
554
|
+
addOps(80 /* LispType.BitShiftLeft */, (exec, done, ticks, a, b) => done(undefined, a << b));
|
|
555
|
+
addOps(81 /* LispType.BitShiftRight */, (exec, done, ticks, a, b) => done(undefined, a >> b));
|
|
556
|
+
addOps(82 /* LispType.BitUnsignedShiftRight */, (exec, done, ticks, a, b) => done(undefined, a >>> b));
|
|
557
|
+
addOps(60 /* LispType.Typeof */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
558
|
+
exec(ticks, b, scope, context, (e, prop) => {
|
|
559
|
+
done(undefined, typeof valueOrProp(prop, context));
|
|
560
|
+
});
|
|
561
|
+
});
|
|
562
|
+
addOps(62 /* LispType.Instanceof */, (exec, done, ticks, a, b) => done(undefined, a instanceof b));
|
|
563
|
+
addOps(63 /* LispType.In */, (exec, done, ticks, a, b) => done(undefined, a in b));
|
|
564
|
+
addOps(61 /* LispType.Delete */, (exec, done, ticks, a, b, obj, context, scope, bobj) => {
|
|
565
|
+
if (bobj.context === undefined) {
|
|
566
|
+
done(undefined, true);
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
assignCheck(bobj, context, 'delete');
|
|
570
|
+
if (bobj.isVariable) {
|
|
571
|
+
done(undefined, false);
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
done(undefined, delete bobj.context?.[bobj.prop]);
|
|
575
|
+
});
|
|
576
|
+
addOps(8 /* LispType.Return */, (exec, done, ticks, a, b) => done(undefined, b));
|
|
577
|
+
addOps(34 /* LispType.Var */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
578
|
+
done(undefined, scope.declare(a, "var" /* VarType.var */, b));
|
|
579
|
+
});
|
|
580
|
+
addOps(3 /* LispType.Let */, (exec, done, ticks, a, b, obj, context, scope, bobj) => {
|
|
581
|
+
done(undefined, scope.declare(a, "let" /* VarType.let */, b, bobj && bobj.isGlobal));
|
|
582
|
+
});
|
|
583
|
+
addOps(4 /* LispType.Const */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
584
|
+
done(undefined, scope.declare(a, "const" /* VarType.const */, b));
|
|
585
|
+
});
|
|
586
|
+
addOps(11 /* LispType.ArrowFunction */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
587
|
+
a = [...a];
|
|
588
|
+
if (typeof obj[2] === 'string' || obj[2] instanceof CodeString) {
|
|
589
|
+
if (context.allowJit && context.evalContext) {
|
|
590
|
+
obj[2] = b = context.evalContext.lispifyFunction(new CodeString(obj[2]), context.constants);
|
|
738
591
|
}
|
|
739
592
|
else {
|
|
740
|
-
|
|
593
|
+
throw new SandboxError('Unevaluated code detected, JIT not allowed');
|
|
741
594
|
}
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
595
|
+
}
|
|
596
|
+
if (a.shift()) {
|
|
597
|
+
done(undefined, createFunctionAsync(a, b, ticks, context, scope));
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
done(undefined, createFunction(a, b, ticks, context, scope));
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
addOps(37 /* LispType.Function */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
604
|
+
if (typeof obj[2] === 'string' || obj[2] instanceof CodeString) {
|
|
605
|
+
if (context.allowJit && context.evalContext) {
|
|
606
|
+
obj[2] = b = context.evalContext.lispifyFunction(new CodeString(obj[2]), context.constants);
|
|
752
607
|
}
|
|
753
608
|
else {
|
|
754
|
-
|
|
755
|
-
}
|
|
756
|
-
if (name) {
|
|
757
|
-
scope.declare(name, VarType.var, func);
|
|
758
|
-
}
|
|
759
|
-
done(undefined, func);
|
|
760
|
-
},
|
|
761
|
-
'inlineFunction': (exec, done, ticks, a, b, obj, context, scope) => {
|
|
762
|
-
if (typeof obj.b === "string" || obj.b instanceof CodeString) {
|
|
763
|
-
obj.b = b = lispifyFunction(new CodeString(obj.b), context.constants);
|
|
764
|
-
}
|
|
765
|
-
let isAsync = a.shift();
|
|
766
|
-
let name = a.shift();
|
|
767
|
-
if (name) {
|
|
768
|
-
scope = new Scope(scope, {});
|
|
609
|
+
throw new SandboxError('Unevaluated code detected, JIT not allowed');
|
|
769
610
|
}
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
611
|
+
}
|
|
612
|
+
const isAsync = a.shift();
|
|
613
|
+
const name = a.shift();
|
|
614
|
+
let func;
|
|
615
|
+
if (isAsync === 88 /* LispType.True */) {
|
|
616
|
+
func = createFunctionAsync(a, b, ticks, context, scope, name);
|
|
617
|
+
}
|
|
618
|
+
else {
|
|
619
|
+
func = createFunction(a, b, ticks, context, scope, name);
|
|
620
|
+
}
|
|
621
|
+
if (name) {
|
|
622
|
+
scope.declare(name, "var" /* VarType.var */, func);
|
|
623
|
+
}
|
|
624
|
+
done(undefined, func);
|
|
625
|
+
});
|
|
626
|
+
addOps(10 /* LispType.InlineFunction */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
627
|
+
if (typeof obj[2] === 'string' || obj[2] instanceof CodeString) {
|
|
628
|
+
if (context.allowJit && context.evalContext) {
|
|
629
|
+
obj[2] = b = context.evalContext.lispifyFunction(new CodeString(obj[2]), context.constants);
|
|
773
630
|
}
|
|
774
631
|
else {
|
|
775
|
-
|
|
776
|
-
}
|
|
777
|
-
if (name) {
|
|
778
|
-
scope.declare(name, VarType.let, func);
|
|
779
|
-
}
|
|
780
|
-
done(undefined, func);
|
|
781
|
-
},
|
|
782
|
-
'loop': (exec, done, ticks, a, b, obj, context, scope) => {
|
|
783
|
-
const [checkFirst, startInternal, getIterator, startStep, step, condition, beforeStep] = a;
|
|
784
|
-
let loop = true;
|
|
785
|
-
const loopScope = new Scope(scope, {});
|
|
786
|
-
let internalVars = {
|
|
787
|
-
'$$obj': undefined
|
|
788
|
-
};
|
|
789
|
-
const interalScope = new Scope(loopScope, internalVars);
|
|
790
|
-
if (exec === execAsync) {
|
|
791
|
-
(async () => {
|
|
792
|
-
let ad;
|
|
793
|
-
ad = asyncDone((d) => exec(ticks, startStep, loopScope, context, d));
|
|
794
|
-
internalVars['$$obj'] = (ad = asyncDone((d) => exec(ticks, getIterator, loopScope, context, d))).isInstant === true ? ad.instant : (await ad.p).result;
|
|
795
|
-
ad = asyncDone((d) => exec(ticks, startInternal, interalScope, context, d));
|
|
796
|
-
if (checkFirst)
|
|
797
|
-
loop = (ad = asyncDone((d) => exec(ticks, condition, interalScope, context, d))).isInstant === true ? ad.instant : (await ad.p).result;
|
|
798
|
-
while (loop) {
|
|
799
|
-
let innerLoopVars = {};
|
|
800
|
-
ad = asyncDone((d) => exec(ticks, beforeStep, new Scope(interalScope, innerLoopVars), context, d));
|
|
801
|
-
ad.isInstant === true ? ad.instant : (await ad.p).result;
|
|
802
|
-
let res = await executeTreeAsync(ticks, context, b, [new Scope(loopScope, innerLoopVars)], "loop");
|
|
803
|
-
if (res instanceof ExecReturn && res.returned) {
|
|
804
|
-
done(undefined, res);
|
|
805
|
-
return;
|
|
806
|
-
}
|
|
807
|
-
if (res instanceof ExecReturn && res.breakLoop) {
|
|
808
|
-
break;
|
|
809
|
-
}
|
|
810
|
-
ad = asyncDone((d) => exec(ticks, step, interalScope, context, d));
|
|
811
|
-
loop = (ad = asyncDone((d) => exec(ticks, condition, interalScope, context, d))).isInstant === true ? ad.instant : (await ad.p).result;
|
|
812
|
-
}
|
|
813
|
-
done();
|
|
814
|
-
})().catch(done);
|
|
632
|
+
throw new SandboxError('Unevaluated code detected, JIT not allowed');
|
|
815
633
|
}
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
634
|
+
}
|
|
635
|
+
const isAsync = a.shift();
|
|
636
|
+
const name = a.shift();
|
|
637
|
+
if (name) {
|
|
638
|
+
scope = new Scope(scope, {});
|
|
639
|
+
}
|
|
640
|
+
let func;
|
|
641
|
+
if (isAsync === 88 /* LispType.True */) {
|
|
642
|
+
func = createFunctionAsync(a, b, ticks, context, scope, name);
|
|
643
|
+
}
|
|
644
|
+
else {
|
|
645
|
+
func = createFunction(a, b, ticks, context, scope, name);
|
|
646
|
+
}
|
|
647
|
+
if (name) {
|
|
648
|
+
scope.declare(name, "let" /* VarType.let */, func);
|
|
649
|
+
}
|
|
650
|
+
done(undefined, func);
|
|
651
|
+
});
|
|
652
|
+
addOps(38 /* LispType.Loop */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
653
|
+
const [checkFirst, startInternal, getIterator, startStep, step, condition, beforeStep] = a;
|
|
654
|
+
let loop = true;
|
|
655
|
+
const loopScope = new Scope(scope, {});
|
|
656
|
+
const internalVars = {
|
|
657
|
+
$$obj: undefined,
|
|
658
|
+
};
|
|
659
|
+
const interalScope = new Scope(loopScope, internalVars);
|
|
660
|
+
if (exec === execAsync) {
|
|
661
|
+
(async () => {
|
|
662
|
+
let ad;
|
|
663
|
+
ad = asyncDone((d) => exec(ticks, startStep, loopScope, context, d));
|
|
664
|
+
internalVars['$$obj'] =
|
|
665
|
+
(ad = asyncDone((d) => exec(ticks, getIterator, loopScope, context, d))).isInstant === true
|
|
666
|
+
? ad.instant
|
|
667
|
+
: (await ad.p).result;
|
|
668
|
+
ad = asyncDone((d) => exec(ticks, startInternal, interalScope, context, d));
|
|
820
669
|
if (checkFirst)
|
|
821
|
-
loop =
|
|
670
|
+
loop =
|
|
671
|
+
(ad = asyncDone((d) => exec(ticks, condition, interalScope, context, d))).isInstant ===
|
|
672
|
+
true
|
|
673
|
+
? ad.instant
|
|
674
|
+
: (await ad.p).result;
|
|
822
675
|
while (loop) {
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
676
|
+
const innerLoopVars = {};
|
|
677
|
+
ad = asyncDone((d) => exec(ticks, beforeStep, new Scope(interalScope, innerLoopVars), context, d));
|
|
678
|
+
ad.isInstant === true ? ad.instant : (await ad.p).result;
|
|
679
|
+
const res = await executeTreeAsync(ticks, context, b, [new Scope(loopScope, innerLoopVars)], 'loop');
|
|
826
680
|
if (res instanceof ExecReturn && res.returned) {
|
|
827
681
|
done(undefined, res);
|
|
828
682
|
return;
|
|
@@ -830,116 +684,152 @@ let ops2 = {
|
|
|
830
684
|
if (res instanceof ExecReturn && res.breakLoop) {
|
|
831
685
|
break;
|
|
832
686
|
}
|
|
833
|
-
|
|
834
|
-
loop =
|
|
687
|
+
ad = asyncDone((d) => exec(ticks, step, interalScope, context, d));
|
|
688
|
+
loop =
|
|
689
|
+
(ad = asyncDone((d) => exec(ticks, condition, interalScope, context, d))).isInstant ===
|
|
690
|
+
true
|
|
691
|
+
? ad.instant
|
|
692
|
+
: (await ad.p).result;
|
|
835
693
|
}
|
|
836
694
|
done();
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
done(err);
|
|
695
|
+
})().catch(done);
|
|
696
|
+
}
|
|
697
|
+
else {
|
|
698
|
+
syncDone((d) => exec(ticks, startStep, loopScope, context, d));
|
|
699
|
+
internalVars['$$obj'] = syncDone((d) => exec(ticks, getIterator, loopScope, context, d)).result;
|
|
700
|
+
syncDone((d) => exec(ticks, startInternal, interalScope, context, d));
|
|
701
|
+
if (checkFirst)
|
|
702
|
+
loop = syncDone((d) => exec(ticks, condition, interalScope, context, d)).result;
|
|
703
|
+
while (loop) {
|
|
704
|
+
const innerLoopVars = {};
|
|
705
|
+
syncDone((d) => exec(ticks, beforeStep, new Scope(interalScope, innerLoopVars), context, d));
|
|
706
|
+
const res = executeTree(ticks, context, b, [new Scope(loopScope, innerLoopVars)], 'loop');
|
|
707
|
+
if (res instanceof ExecReturn && res.returned) {
|
|
708
|
+
done(undefined, res);
|
|
852
709
|
return;
|
|
853
710
|
}
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
},
|
|
857
|
-
'switch': (exec, done, ticks, a, b, obj, context, scope) => {
|
|
858
|
-
exec(ticks, a, scope, context, (err, toTest) => {
|
|
859
|
-
if (err) {
|
|
860
|
-
done(err);
|
|
861
|
-
return;
|
|
711
|
+
if (res instanceof ExecReturn && res.breakLoop) {
|
|
712
|
+
break;
|
|
862
713
|
}
|
|
863
|
-
|
|
864
|
-
|
|
714
|
+
syncDone((d) => exec(ticks, step, interalScope, context, d));
|
|
715
|
+
loop = syncDone((d) => exec(ticks, condition, interalScope, context, d)).result;
|
|
716
|
+
}
|
|
717
|
+
done();
|
|
718
|
+
}
|
|
719
|
+
});
|
|
720
|
+
addOps(86 /* LispType.LoopAction */, (exec, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch) => {
|
|
721
|
+
if ((inLoopOrSwitch === 'switch' && a === 'continue') || !inLoopOrSwitch) {
|
|
722
|
+
throw new SandboxError('Illegal ' + a + ' statement');
|
|
723
|
+
}
|
|
724
|
+
done(undefined, new ExecReturn(context.ctx.auditReport, undefined, false, a === 'break', a === 'continue'));
|
|
725
|
+
});
|
|
726
|
+
addOps(13 /* LispType.If */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
727
|
+
exec(ticks, valueOrProp(a, context) ? b.t : b.f, scope, context, done);
|
|
728
|
+
});
|
|
729
|
+
addOps(15 /* LispType.InlineIf */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
730
|
+
exec(ticks, valueOrProp(a, context) ? b.t : b.f, scope, context, done);
|
|
731
|
+
});
|
|
732
|
+
addOps(16 /* LispType.InlineIfCase */, (exec, done, ticks, a, b) => done(undefined, new If(a, b)));
|
|
733
|
+
addOps(14 /* LispType.IfCase */, (exec, done, ticks, a, b) => done(undefined, new If(a, b)));
|
|
734
|
+
addOps(40 /* LispType.Switch */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
735
|
+
exec(ticks, a, scope, context, (err, toTest) => {
|
|
736
|
+
if (err) {
|
|
737
|
+
done(err);
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
toTest = valueOrProp(toTest, context);
|
|
741
|
+
if (exec === execSync) {
|
|
742
|
+
let res;
|
|
743
|
+
let isTrue = false;
|
|
744
|
+
for (const caseItem of b) {
|
|
745
|
+
if (isTrue ||
|
|
746
|
+
(isTrue =
|
|
747
|
+
!caseItem[1] ||
|
|
748
|
+
toTest ===
|
|
749
|
+
valueOrProp(syncDone((d) => exec(ticks, caseItem[1], scope, context, d)).result, context))) {
|
|
750
|
+
if (!caseItem[2])
|
|
751
|
+
continue;
|
|
752
|
+
res = executeTree(ticks, context, caseItem[2], [scope], 'switch');
|
|
753
|
+
if (res.breakLoop)
|
|
754
|
+
break;
|
|
755
|
+
if (res.returned) {
|
|
756
|
+
done(undefined, res);
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
759
|
+
if (!caseItem[1]) {
|
|
760
|
+
// default case
|
|
761
|
+
break;
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
done();
|
|
766
|
+
}
|
|
767
|
+
else {
|
|
768
|
+
(async () => {
|
|
865
769
|
let res;
|
|
866
770
|
let isTrue = false;
|
|
867
|
-
for (
|
|
868
|
-
|
|
869
|
-
|
|
771
|
+
for (const caseItem of b) {
|
|
772
|
+
let ad;
|
|
773
|
+
if (isTrue ||
|
|
774
|
+
(isTrue =
|
|
775
|
+
!caseItem[1] ||
|
|
776
|
+
toTest ===
|
|
777
|
+
valueOrProp((ad = asyncDone((d) => exec(ticks, caseItem[1], scope, context, d))).isInstant ===
|
|
778
|
+
true
|
|
779
|
+
? ad.instant
|
|
780
|
+
: (await ad.p).result, context))) {
|
|
781
|
+
if (!caseItem[2])
|
|
870
782
|
continue;
|
|
871
|
-
res =
|
|
783
|
+
res = await executeTreeAsync(ticks, context, caseItem[2], [scope], 'switch');
|
|
872
784
|
if (res.breakLoop)
|
|
873
785
|
break;
|
|
874
786
|
if (res.returned) {
|
|
875
787
|
done(undefined, res);
|
|
876
788
|
return;
|
|
877
789
|
}
|
|
878
|
-
if (!caseItem
|
|
790
|
+
if (!caseItem[1]) {
|
|
791
|
+
// default case
|
|
879
792
|
break;
|
|
880
793
|
}
|
|
881
794
|
}
|
|
882
795
|
}
|
|
883
796
|
done();
|
|
797
|
+
})().catch(done);
|
|
798
|
+
}
|
|
799
|
+
});
|
|
800
|
+
});
|
|
801
|
+
addOps(39 /* LispType.Try */, (exec, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch) => {
|
|
802
|
+
const [exception, catchBody, finallyBody] = b;
|
|
803
|
+
executeTreeWithDone(exec, (err, res) => {
|
|
804
|
+
executeTreeWithDone(exec, (e) => {
|
|
805
|
+
if (e)
|
|
806
|
+
done(e);
|
|
807
|
+
else if (err) {
|
|
808
|
+
const sc = {};
|
|
809
|
+
if (exception)
|
|
810
|
+
sc[exception] = err;
|
|
811
|
+
executeTreeWithDone(exec, done, ticks, context, catchBody, [new Scope(scope)], inLoopOrSwitch);
|
|
884
812
|
}
|
|
885
813
|
else {
|
|
886
|
-
(
|
|
887
|
-
let res;
|
|
888
|
-
let isTrue = false;
|
|
889
|
-
for (let caseItem of b) {
|
|
890
|
-
let ad;
|
|
891
|
-
if (isTrue || (isTrue = !caseItem.a || toTest === valueOrProp((ad = asyncDone((d) => exec(ticks, caseItem.a, scope, context, d))).isInstant === true ? ad.instant : (await ad.p).result, context))) {
|
|
892
|
-
if (!caseItem.b)
|
|
893
|
-
continue;
|
|
894
|
-
res = await executeTreeAsync(ticks, context, caseItem.b, [scope], "switch");
|
|
895
|
-
if (res.breakLoop)
|
|
896
|
-
break;
|
|
897
|
-
if (res.returned) {
|
|
898
|
-
done(undefined, res);
|
|
899
|
-
return;
|
|
900
|
-
}
|
|
901
|
-
if (!caseItem.a) { // default case
|
|
902
|
-
break;
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
}
|
|
906
|
-
done();
|
|
907
|
-
})().catch(done);
|
|
814
|
+
done(undefined, res);
|
|
908
815
|
}
|
|
909
|
-
});
|
|
910
|
-
},
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
}, ticks, context, finallyBody, [new Scope(scope, {})]);
|
|
927
|
-
}, ticks, context, a, [new Scope(scope)], inLoopOrSwitch);
|
|
928
|
-
},
|
|
929
|
-
'void': (exec, done, ticks, a) => { done(); },
|
|
930
|
-
'new': (exec, done, ticks, a, b, obj, context) => {
|
|
931
|
-
if (!context.ctx.globalsWhitelist.has(a) && !sandboxedFunctions.has(a)) {
|
|
932
|
-
throw new SandboxError(`Object construction not allowed: ${a.constructor.name}`);
|
|
933
|
-
}
|
|
934
|
-
done(undefined, new a(...b));
|
|
935
|
-
},
|
|
936
|
-
'throw': (exec, done, ticks, a, b) => { done(b); },
|
|
937
|
-
'multi': (exec, done, ticks, a) => done(undefined, a.pop())
|
|
938
|
-
};
|
|
939
|
-
export let ops = new Map();
|
|
940
|
-
for (let op in ops2) {
|
|
941
|
-
ops.set(op, ops2[op]);
|
|
942
|
-
}
|
|
816
|
+
}, ticks, context, finallyBody, [new Scope(scope, {})]);
|
|
817
|
+
}, ticks, context, a, [new Scope(scope)], inLoopOrSwitch);
|
|
818
|
+
});
|
|
819
|
+
addOps(87 /* LispType.Void */, (exec, done) => {
|
|
820
|
+
done();
|
|
821
|
+
});
|
|
822
|
+
addOps(45 /* LispType.New */, (exec, done, ticks, a, b, obj, context) => {
|
|
823
|
+
if (!context.ctx.globalsWhitelist.has(a) && !sandboxedFunctions.has(a)) {
|
|
824
|
+
throw new SandboxError(`Object construction not allowed: ${a.constructor.name}`);
|
|
825
|
+
}
|
|
826
|
+
done(undefined, new a(...b));
|
|
827
|
+
});
|
|
828
|
+
addOps(46 /* LispType.Throw */, (exec, done, ticks, a, b) => {
|
|
829
|
+
done(b);
|
|
830
|
+
});
|
|
831
|
+
addOps(43 /* LispType.Expression */, (exec, done, ticks, a) => done(undefined, a.pop()));
|
|
832
|
+
addOps(0 /* LispType.None */, (exec, done) => done());
|
|
943
833
|
function valueOrProp(a, context) {
|
|
944
834
|
if (a instanceof Prop)
|
|
945
835
|
return a.get(context);
|
|
@@ -956,7 +846,7 @@ export function execMany(ticks, exec, tree, done, scope, context, inLoopOrSwitch
|
|
|
956
846
|
}
|
|
957
847
|
}
|
|
958
848
|
function _execManySync(ticks, tree, done, scope, context, inLoopOrSwitch) {
|
|
959
|
-
|
|
849
|
+
const ret = [];
|
|
960
850
|
for (let i = 0; i < tree.length; i++) {
|
|
961
851
|
let res;
|
|
962
852
|
try {
|
|
@@ -970,17 +860,25 @@ function _execManySync(ticks, tree, done, scope, context, inLoopOrSwitch) {
|
|
|
970
860
|
done(undefined, res);
|
|
971
861
|
return;
|
|
972
862
|
}
|
|
863
|
+
if (isLisp(tree[i]) && tree[i][0] === 8 /* LispType.Return */) {
|
|
864
|
+
done(undefined, new ExecReturn(context.ctx.auditReport, res, true));
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
973
867
|
ret.push(res);
|
|
974
868
|
}
|
|
975
869
|
done(undefined, ret);
|
|
976
870
|
}
|
|
977
871
|
async function _execManyAsync(ticks, tree, done, scope, context, inLoopOrSwitch) {
|
|
978
|
-
|
|
872
|
+
const ret = [];
|
|
979
873
|
for (let i = 0; i < tree.length; i++) {
|
|
980
874
|
let res;
|
|
981
875
|
try {
|
|
982
876
|
let ad;
|
|
983
|
-
res =
|
|
877
|
+
res =
|
|
878
|
+
(ad = asyncDone((d) => execAsync(ticks, tree[i], scope, context, d, inLoopOrSwitch)))
|
|
879
|
+
.isInstant === true
|
|
880
|
+
? ad.instant
|
|
881
|
+
: (await ad.p).result;
|
|
984
882
|
}
|
|
985
883
|
catch (e) {
|
|
986
884
|
done(e);
|
|
@@ -990,6 +888,10 @@ async function _execManyAsync(ticks, tree, done, scope, context, inLoopOrSwitch)
|
|
|
990
888
|
done(undefined, res);
|
|
991
889
|
return;
|
|
992
890
|
}
|
|
891
|
+
if (isLisp(tree[i]) && tree[i][0] === 8 /* LispType.Return */) {
|
|
892
|
+
done(undefined, new ExecReturn(context.ctx.auditReport, res, true));
|
|
893
|
+
return;
|
|
894
|
+
}
|
|
993
895
|
ret.push(res);
|
|
994
896
|
}
|
|
995
897
|
done(undefined, ret);
|
|
@@ -1006,13 +908,12 @@ export function asyncDone(callback) {
|
|
|
1006
908
|
instant = result;
|
|
1007
909
|
resolve({ result });
|
|
1008
910
|
}
|
|
1009
|
-
;
|
|
1010
911
|
});
|
|
1011
912
|
});
|
|
1012
913
|
return {
|
|
1013
914
|
isInstant,
|
|
1014
915
|
instant,
|
|
1015
|
-
p
|
|
916
|
+
p,
|
|
1016
917
|
};
|
|
1017
918
|
}
|
|
1018
919
|
export function syncDone(callback) {
|
|
@@ -1034,13 +935,16 @@ export async function execAsync(ticks, tree, scope, context, doneOriginal, inLoo
|
|
|
1034
935
|
resolve();
|
|
1035
936
|
};
|
|
1036
937
|
});
|
|
1037
|
-
if (_execNoneRecurse(ticks, tree, scope, context, done, true, inLoopOrSwitch)) {
|
|
1038
|
-
|
|
1039
|
-
else if (tree instanceof Lisp) {
|
|
938
|
+
if (!_execNoneRecurse(ticks, tree, scope, context, done, true, inLoopOrSwitch) && isLisp(tree)) {
|
|
939
|
+
let op = tree[0];
|
|
1040
940
|
let obj;
|
|
1041
941
|
try {
|
|
1042
942
|
let ad;
|
|
1043
|
-
obj =
|
|
943
|
+
obj =
|
|
944
|
+
(ad = asyncDone((d) => execAsync(ticks, tree[1], scope, context, d, inLoopOrSwitch)))
|
|
945
|
+
.isInstant === true
|
|
946
|
+
? ad.instant
|
|
947
|
+
: (await ad.p).result;
|
|
1044
948
|
}
|
|
1045
949
|
catch (e) {
|
|
1046
950
|
done(e);
|
|
@@ -1054,16 +958,15 @@ export async function execAsync(ticks, tree, scope, context, doneOriginal, inLoo
|
|
|
1054
958
|
done(e);
|
|
1055
959
|
return;
|
|
1056
960
|
}
|
|
1057
|
-
|
|
1058
|
-
if (op === '?prop' || op === '?call') {
|
|
961
|
+
if (op === 20 /* LispType.PropOptional */ || op === 21 /* LispType.CallOptional */) {
|
|
1059
962
|
if (a === undefined || a === null) {
|
|
1060
963
|
done(undefined, optional);
|
|
1061
964
|
return;
|
|
1062
965
|
}
|
|
1063
|
-
op = op.
|
|
966
|
+
op = op === 20 /* LispType.PropOptional */ ? 1 /* LispType.Prop */ : 5 /* LispType.Call */;
|
|
1064
967
|
}
|
|
1065
968
|
if (a === optional) {
|
|
1066
|
-
if (op ===
|
|
969
|
+
if (op === 1 /* LispType.Prop */ || op === 5 /* LispType.Call */) {
|
|
1067
970
|
done(undefined, a);
|
|
1068
971
|
return;
|
|
1069
972
|
}
|
|
@@ -1074,7 +977,11 @@ export async function execAsync(ticks, tree, scope, context, doneOriginal, inLoo
|
|
|
1074
977
|
let bobj;
|
|
1075
978
|
try {
|
|
1076
979
|
let ad;
|
|
1077
|
-
bobj =
|
|
980
|
+
bobj =
|
|
981
|
+
(ad = asyncDone((d) => execAsync(ticks, tree[2], scope, context, d, inLoopOrSwitch)))
|
|
982
|
+
.isInstant === true
|
|
983
|
+
? ad.instant
|
|
984
|
+
: (await ad.p).result;
|
|
1078
985
|
}
|
|
1079
986
|
catch (e) {
|
|
1080
987
|
done(e);
|
|
@@ -1093,7 +1000,7 @@ export async function execAsync(ticks, tree, scope, context, doneOriginal, inLoo
|
|
|
1093
1000
|
}
|
|
1094
1001
|
if (ops.has(op)) {
|
|
1095
1002
|
try {
|
|
1096
|
-
ops.get(op)(execAsync, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch);
|
|
1003
|
+
ops.get(op)?.(execAsync, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch);
|
|
1097
1004
|
}
|
|
1098
1005
|
catch (err) {
|
|
1099
1006
|
done(err);
|
|
@@ -1106,12 +1013,11 @@ export async function execAsync(ticks, tree, scope, context, doneOriginal, inLoo
|
|
|
1106
1013
|
await p;
|
|
1107
1014
|
}
|
|
1108
1015
|
export function execSync(ticks, tree, scope, context, done, inLoopOrSwitch) {
|
|
1109
|
-
if (_execNoneRecurse(ticks, tree, scope, context, done, false, inLoopOrSwitch)) {
|
|
1110
|
-
|
|
1111
|
-
else if (tree instanceof Lisp) {
|
|
1016
|
+
if (!_execNoneRecurse(ticks, tree, scope, context, done, false, inLoopOrSwitch) && isLisp(tree)) {
|
|
1017
|
+
let op = tree[0];
|
|
1112
1018
|
let obj;
|
|
1113
1019
|
try {
|
|
1114
|
-
obj = syncDone((d) => execSync(ticks, tree
|
|
1020
|
+
obj = syncDone((d) => execSync(ticks, tree[1], scope, context, d, inLoopOrSwitch)).result;
|
|
1115
1021
|
}
|
|
1116
1022
|
catch (e) {
|
|
1117
1023
|
done(e);
|
|
@@ -1125,16 +1031,15 @@ export function execSync(ticks, tree, scope, context, done, inLoopOrSwitch) {
|
|
|
1125
1031
|
done(e);
|
|
1126
1032
|
return;
|
|
1127
1033
|
}
|
|
1128
|
-
|
|
1129
|
-
if (op === '?prop' || op === '?call') {
|
|
1034
|
+
if (op === 20 /* LispType.PropOptional */ || op === 21 /* LispType.CallOptional */) {
|
|
1130
1035
|
if (a === undefined || a === null) {
|
|
1131
1036
|
done(undefined, optional);
|
|
1132
1037
|
return;
|
|
1133
1038
|
}
|
|
1134
|
-
op = op.
|
|
1039
|
+
op = op === 20 /* LispType.PropOptional */ ? 1 /* LispType.Prop */ : 5 /* LispType.Call */;
|
|
1135
1040
|
}
|
|
1136
1041
|
if (a === optional) {
|
|
1137
|
-
if (op ===
|
|
1042
|
+
if (op === 1 /* LispType.Prop */ || op === 5 /* LispType.Call */) {
|
|
1138
1043
|
done(undefined, a);
|
|
1139
1044
|
return;
|
|
1140
1045
|
}
|
|
@@ -1144,7 +1049,7 @@ export function execSync(ticks, tree, scope, context, done, inLoopOrSwitch) {
|
|
|
1144
1049
|
}
|
|
1145
1050
|
let bobj;
|
|
1146
1051
|
try {
|
|
1147
|
-
bobj = syncDone((d) => execSync(ticks, tree
|
|
1052
|
+
bobj = syncDone((d) => execSync(ticks, tree[2], scope, context, d, inLoopOrSwitch)).result;
|
|
1148
1053
|
}
|
|
1149
1054
|
catch (e) {
|
|
1150
1055
|
done(e);
|
|
@@ -1163,7 +1068,7 @@ export function execSync(ticks, tree, scope, context, done, inLoopOrSwitch) {
|
|
|
1163
1068
|
}
|
|
1164
1069
|
if (ops.has(op)) {
|
|
1165
1070
|
try {
|
|
1166
|
-
ops.get(op)(execSync, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch);
|
|
1071
|
+
ops.get(op)?.(execSync, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch);
|
|
1167
1072
|
}
|
|
1168
1073
|
catch (err) {
|
|
1169
1074
|
done(err);
|
|
@@ -1174,20 +1079,29 @@ export function execSync(ticks, tree, scope, context, done, inLoopOrSwitch) {
|
|
|
1174
1079
|
}
|
|
1175
1080
|
}
|
|
1176
1081
|
}
|
|
1177
|
-
const unexecTypes = new Set([
|
|
1082
|
+
const unexecTypes = new Set([
|
|
1083
|
+
11 /* LispType.ArrowFunction */,
|
|
1084
|
+
37 /* LispType.Function */,
|
|
1085
|
+
10 /* LispType.InlineFunction */,
|
|
1086
|
+
38 /* LispType.Loop */,
|
|
1087
|
+
39 /* LispType.Try */,
|
|
1088
|
+
40 /* LispType.Switch */,
|
|
1089
|
+
14 /* LispType.IfCase */,
|
|
1090
|
+
16 /* LispType.InlineIfCase */,
|
|
1091
|
+
60 /* LispType.Typeof */,
|
|
1092
|
+
]);
|
|
1093
|
+
export const currentTicks = { current: { ticks: BigInt(0) } };
|
|
1178
1094
|
function _execNoneRecurse(ticks, tree, scope, context, done, isAsync, inLoopOrSwitch) {
|
|
1179
|
-
var _a;
|
|
1180
1095
|
const exec = isAsync ? execAsync : execSync;
|
|
1181
|
-
if (context.ctx.options.executionQuota <= ticks.ticks) {
|
|
1182
|
-
if (typeof context.ctx.options.onExecutionQuotaReached === 'function' &&
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
return;
|
|
1096
|
+
if (context.ctx.options.executionQuota && context.ctx.options.executionQuota <= ticks.ticks) {
|
|
1097
|
+
if (!(typeof context.ctx.options.onExecutionQuotaReached === 'function' &&
|
|
1098
|
+
context.ctx.options.onExecutionQuotaReached(ticks, scope, context, tree))) {
|
|
1099
|
+
done(new SandboxError('Execution quota exceeded'));
|
|
1100
|
+
return true;
|
|
1187
1101
|
}
|
|
1188
1102
|
}
|
|
1189
1103
|
ticks.ticks++;
|
|
1190
|
-
currentTicks = ticks;
|
|
1104
|
+
currentTicks.current = ticks;
|
|
1191
1105
|
if (tree instanceof Prop) {
|
|
1192
1106
|
try {
|
|
1193
1107
|
done(undefined, tree.get(context));
|
|
@@ -1199,18 +1113,26 @@ function _execNoneRecurse(ticks, tree, scope, context, done, isAsync, inLoopOrSw
|
|
|
1199
1113
|
else if (tree === optional) {
|
|
1200
1114
|
done();
|
|
1201
1115
|
}
|
|
1202
|
-
else if (Array.isArray(tree) && tree
|
|
1203
|
-
|
|
1116
|
+
else if (Array.isArray(tree) && !isLisp(tree)) {
|
|
1117
|
+
if (tree[0] === 0 /* LispType.None */) {
|
|
1118
|
+
done();
|
|
1119
|
+
}
|
|
1120
|
+
else {
|
|
1121
|
+
execMany(ticks, exec, tree, done, scope, context, inLoopOrSwitch);
|
|
1122
|
+
}
|
|
1204
1123
|
}
|
|
1205
|
-
else if (!(tree
|
|
1124
|
+
else if (!isLisp(tree)) {
|
|
1206
1125
|
done(undefined, tree);
|
|
1207
1126
|
}
|
|
1208
|
-
else if (tree
|
|
1127
|
+
else if (tree[0] === 42 /* LispType.Block */) {
|
|
1128
|
+
execMany(ticks, exec, tree[1], done, scope, context, inLoopOrSwitch);
|
|
1129
|
+
}
|
|
1130
|
+
else if (tree[0] === 44 /* LispType.Await */) {
|
|
1209
1131
|
if (!isAsync) {
|
|
1210
1132
|
done(new SandboxError("Illegal use of 'await', must be inside async function"));
|
|
1211
1133
|
}
|
|
1212
|
-
else if (
|
|
1213
|
-
execAsync(ticks, tree
|
|
1134
|
+
else if (context.ctx.prototypeWhitelist?.has(Promise.prototype)) {
|
|
1135
|
+
execAsync(ticks, tree[1], scope, context, async (e, r) => {
|
|
1214
1136
|
if (e)
|
|
1215
1137
|
done(e);
|
|
1216
1138
|
else
|
|
@@ -1226,9 +1148,9 @@ function _execNoneRecurse(ticks, tree, scope, context, done, isAsync, inLoopOrSw
|
|
|
1226
1148
|
done(new SandboxError('Async/await is not permitted'));
|
|
1227
1149
|
}
|
|
1228
1150
|
}
|
|
1229
|
-
else if (unexecTypes.has(tree
|
|
1151
|
+
else if (unexecTypes.has(tree[0])) {
|
|
1230
1152
|
try {
|
|
1231
|
-
ops.get(tree
|
|
1153
|
+
ops.get(tree[0])?.(exec, done, ticks, tree[1], tree[2], tree, context, scope, undefined, inLoopOrSwitch);
|
|
1232
1154
|
}
|
|
1233
1155
|
catch (err) {
|
|
1234
1156
|
done(err);
|
|
@@ -1244,7 +1166,9 @@ export function executeTree(ticks, context, executionTree, scopes = [], inLoopOr
|
|
|
1244
1166
|
}
|
|
1245
1167
|
export async function executeTreeAsync(ticks, context, executionTree, scopes = [], inLoopOrSwitch) {
|
|
1246
1168
|
let ad;
|
|
1247
|
-
return (ad = asyncDone((done) => executeTreeWithDone(execAsync, done, ticks, context, executionTree, scopes, inLoopOrSwitch))).isInstant === true
|
|
1169
|
+
return (ad = asyncDone((done) => executeTreeWithDone(execAsync, done, ticks, context, executionTree, scopes, inLoopOrSwitch))).isInstant === true
|
|
1170
|
+
? ad.instant
|
|
1171
|
+
: (await ad.p).result;
|
|
1248
1172
|
}
|
|
1249
1173
|
function executeTreeWithDone(exec, done, ticks, context, executionTree, scopes = [], inLoopOrSwitch) {
|
|
1250
1174
|
if (!executionTree) {
|
|
@@ -1256,8 +1180,8 @@ function executeTreeWithDone(exec, done, ticks, context, executionTree, scopes =
|
|
|
1256
1180
|
}
|
|
1257
1181
|
let scope = context.ctx.globalScope;
|
|
1258
1182
|
let s;
|
|
1259
|
-
while (s = scopes.shift()) {
|
|
1260
|
-
if (typeof s !==
|
|
1183
|
+
while ((s = scopes.shift())) {
|
|
1184
|
+
if (typeof s !== 'object')
|
|
1261
1185
|
continue;
|
|
1262
1186
|
if (s instanceof Scope) {
|
|
1263
1187
|
scope = s;
|
|
@@ -1304,7 +1228,7 @@ function _executeWithDoneSync(done, ticks, context, executionTree, scope, inLoop
|
|
|
1304
1228
|
done(undefined, res);
|
|
1305
1229
|
return;
|
|
1306
1230
|
}
|
|
1307
|
-
if (current
|
|
1231
|
+
if (isLisp(current) && current[0] === 8 /* LispType.Return */) {
|
|
1308
1232
|
done(undefined, new ExecReturn(context.ctx.auditReport, res, true));
|
|
1309
1233
|
return;
|
|
1310
1234
|
}
|
|
@@ -1336,7 +1260,7 @@ async function _executeWithDoneAsync(done, ticks, context, executionTree, scope,
|
|
|
1336
1260
|
done(undefined, res);
|
|
1337
1261
|
return;
|
|
1338
1262
|
}
|
|
1339
|
-
if (current
|
|
1263
|
+
if (isLisp(current) && current[0] === 8 /* LispType.Return */) {
|
|
1340
1264
|
done(undefined, new ExecReturn(context.ctx.auditReport, res, true));
|
|
1341
1265
|
return;
|
|
1342
1266
|
}
|