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