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