@nyariv/sandboxjs 0.8.22 → 0.8.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/npm-publish.yml +2 -2
- package/build/Sandbox.d.ts +5 -4
- package/build/Sandbox.js +1 -1
- package/build/executor.d.ts +46 -24
- package/build/executor.js +627 -624
- package/build/parser.d.ts +321 -52
- package/build/parser.js +217 -157
- package/dist/Sandbox.d.ts +5 -4
- package/dist/Sandbox.js +1 -1
- package/dist/Sandbox.js.map +1 -1
- package/dist/executor.d.ts +46 -24
- package/dist/node/Sandbox.d.ts +5 -4
- package/dist/node/Sandbox.js +842 -782
- package/dist/node/executor.d.ts +46 -24
- package/dist/node/parser.d.ts +321 -52
- package/dist/parser.d.ts +321 -52
- package/package.json +14 -14
- package/rollup.config.mjs +33 -0
- package/dist/Sandbox.min.js +0 -2
- package/dist/Sandbox.min.js.map +0 -1
package/build/executor.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parse, lispifyFunction, CodeString, isLisp } from "./parser.js";
|
|
2
2
|
export class ExecReturn {
|
|
3
3
|
constructor(auditReport, result, returned, breakLoop = false, continueLoop = false) {
|
|
4
4
|
this.auditReport = auditReport;
|
|
@@ -193,11 +193,10 @@ export function createFunction(argNames, parsed, ticks, context, scope, name) {
|
|
|
193
193
|
return func;
|
|
194
194
|
}
|
|
195
195
|
export function createFunctionAsync(argNames, parsed, ticks, context, scope, name) {
|
|
196
|
-
var _a;
|
|
197
196
|
if (context.ctx.options.forbidFunctionCreation) {
|
|
198
197
|
throw new SandboxError("Function creation is forbidden");
|
|
199
198
|
}
|
|
200
|
-
if (!
|
|
199
|
+
if (!context.ctx.prototypeWhitelist?.has(Promise.prototype)) {
|
|
201
200
|
throw new SandboxError("Async/await not permitted");
|
|
202
201
|
}
|
|
203
202
|
let func;
|
|
@@ -240,7 +239,6 @@ export function sandboxedSetInterval(func) {
|
|
|
240
239
|
};
|
|
241
240
|
}
|
|
242
241
|
export function assignCheck(obj, context, op = 'assign') {
|
|
243
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
244
242
|
if (obj.context === undefined) {
|
|
245
243
|
throw new ReferenceError(`Cannot ${op} value to undefined.`);
|
|
246
244
|
}
|
|
@@ -258,21 +256,21 @@ export function assignCheck(obj, context, op = 'assign') {
|
|
|
258
256
|
}
|
|
259
257
|
if (op === "delete") {
|
|
260
258
|
if (obj.context.hasOwnProperty(obj.prop)) {
|
|
261
|
-
|
|
262
|
-
|
|
259
|
+
context.changeSubscriptions.get(obj.context)?.forEach((cb) => cb({ type: "delete", prop: obj.prop }));
|
|
260
|
+
context.changeSubscriptionsGlobal.get(obj.context)?.forEach((cb) => cb({ type: "delete", prop: obj.prop }));
|
|
263
261
|
}
|
|
264
262
|
}
|
|
265
263
|
else if (obj.context.hasOwnProperty(obj.prop)) {
|
|
266
|
-
|
|
264
|
+
context.setSubscriptions.get(obj.context)?.get(obj.prop)?.forEach((cb) => cb({
|
|
267
265
|
type: "replace"
|
|
268
266
|
}));
|
|
269
|
-
|
|
267
|
+
context.setSubscriptionsGlobal.get(obj.context)?.get(obj.prop)?.forEach((cb) => cb({
|
|
270
268
|
type: "replace"
|
|
271
269
|
}));
|
|
272
270
|
}
|
|
273
271
|
else {
|
|
274
|
-
|
|
275
|
-
|
|
272
|
+
context.changeSubscriptions.get(obj.context)?.forEach((cb) => cb({ type: "create", prop: obj.prop }));
|
|
273
|
+
context.changeSubscriptionsGlobal.get(obj.context)?.forEach((cb) => cb({ type: "create", prop: obj.prop }));
|
|
276
274
|
}
|
|
277
275
|
}
|
|
278
276
|
const arrayChange = new Set([
|
|
@@ -285,544 +283,509 @@ const arrayChange = new Set([
|
|
|
285
283
|
[].sort,
|
|
286
284
|
[].copyWithin
|
|
287
285
|
]);
|
|
286
|
+
export class KeyVal {
|
|
287
|
+
constructor(key, val) {
|
|
288
|
+
this.key = key;
|
|
289
|
+
this.val = val;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
export class SpreadObject {
|
|
293
|
+
constructor(item) {
|
|
294
|
+
this.item = item;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
export class SpreadArray {
|
|
298
|
+
constructor(item) {
|
|
299
|
+
this.item = item;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
export class If {
|
|
303
|
+
constructor(t, f) {
|
|
304
|
+
this.t = t;
|
|
305
|
+
this.f = f;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
288
308
|
const literalRegex = /(\$\$)*(\$)?\${(\d+)}/g;
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
done(undefined, rep);
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
309
|
+
export const ops = new Map();
|
|
310
|
+
export function addOps(type, cb) {
|
|
311
|
+
ops.set(type, cb);
|
|
312
|
+
}
|
|
313
|
+
addOps(1 /* LispType.Prop */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
314
|
+
if (a === null) {
|
|
315
|
+
throw new TypeError(`Cannot get property ${b} of null`);
|
|
316
|
+
}
|
|
317
|
+
const type = typeof a;
|
|
318
|
+
if (type === 'undefined' && obj === undefined) {
|
|
319
|
+
let prop = scope.get(b);
|
|
320
|
+
if (prop.context === context.ctx.sandboxGlobal) {
|
|
321
|
+
if (context.ctx.options.audit) {
|
|
322
|
+
context.ctx.auditReport.globalsAccess.add(b);
|
|
306
323
|
}
|
|
307
|
-
|
|
308
|
-
|
|
324
|
+
const rep = context.ctx.globalsWhitelist.has(context.ctx.sandboxGlobal[b]) ? context.evals.get(context.ctx.sandboxGlobal[b]) : undefined;
|
|
325
|
+
if (rep) {
|
|
326
|
+
done(undefined, rep);
|
|
309
327
|
return;
|
|
310
328
|
}
|
|
311
|
-
|
|
329
|
+
}
|
|
330
|
+
if (prop.context && prop.context[b] === globalThis) {
|
|
331
|
+
done(undefined, context.ctx.globalScope.get('this'));
|
|
312
332
|
return;
|
|
313
333
|
}
|
|
314
|
-
|
|
315
|
-
|
|
334
|
+
done(undefined, prop);
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
else if (a === undefined) {
|
|
338
|
+
throw new SandboxError("Cannot get property '" + b + "' of undefined");
|
|
339
|
+
}
|
|
340
|
+
if (type !== 'object') {
|
|
341
|
+
if (type === 'number') {
|
|
342
|
+
a = new Number(a);
|
|
316
343
|
}
|
|
317
|
-
if (type
|
|
318
|
-
|
|
319
|
-
a = new Number(a);
|
|
320
|
-
}
|
|
321
|
-
else if (type === 'string') {
|
|
322
|
-
a = new String(a);
|
|
323
|
-
}
|
|
324
|
-
else if (type === 'boolean') {
|
|
325
|
-
a = new Boolean(a);
|
|
326
|
-
}
|
|
344
|
+
else if (type === 'string') {
|
|
345
|
+
a = new String(a);
|
|
327
346
|
}
|
|
328
|
-
else if (
|
|
329
|
-
|
|
330
|
-
return;
|
|
347
|
+
else if (type === 'boolean') {
|
|
348
|
+
a = new Boolean(a);
|
|
331
349
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
350
|
+
}
|
|
351
|
+
else if (typeof a.hasOwnProperty === 'undefined') {
|
|
352
|
+
done(undefined, new Prop(undefined, b));
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
const isFunction = type === 'function';
|
|
356
|
+
let prototypeAccess = isFunction || !(a.hasOwnProperty(b) || typeof b === 'number');
|
|
357
|
+
if (context.ctx.options.audit && prototypeAccess) {
|
|
358
|
+
if (typeof b === 'string') {
|
|
359
|
+
let prot = Object.getPrototypeOf(a);
|
|
360
|
+
do {
|
|
361
|
+
if (prot.hasOwnProperty(b)) {
|
|
362
|
+
if (!context.ctx.auditReport.prototypeAccess[prot.constructor.name]) {
|
|
363
|
+
context.ctx.auditReport.prototypeAccess[prot.constructor.name] = new Set();
|
|
343
364
|
}
|
|
344
|
-
|
|
345
|
-
|
|
365
|
+
context.ctx.auditReport.prototypeAccess[prot.constructor.name].add(b);
|
|
366
|
+
}
|
|
367
|
+
} while (prot = Object.getPrototypeOf(prot));
|
|
346
368
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
if (whitelist && (!whitelist.size || whitelist.has(b))) {
|
|
357
|
-
}
|
|
358
|
-
else {
|
|
359
|
-
throw new SandboxError(`Static method or property access not permitted: ${a.name}.${b}`);
|
|
360
|
-
}
|
|
369
|
+
}
|
|
370
|
+
if (prototypeAccess) {
|
|
371
|
+
if (isFunction) {
|
|
372
|
+
if (!['name', 'length', 'constructor'].includes(b) && a.hasOwnProperty(b)) {
|
|
373
|
+
const whitelist = context.ctx.prototypeWhitelist.get(a.prototype);
|
|
374
|
+
const replace = context.ctx.options.prototypeReplacements.get(a);
|
|
375
|
+
if (replace) {
|
|
376
|
+
done(undefined, new Prop(replace(a, true), b));
|
|
377
|
+
return;
|
|
361
378
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
if (prot.hasOwnProperty(b)) {
|
|
367
|
-
const whitelist = context.ctx.prototypeWhitelist.get(prot);
|
|
368
|
-
const replace = context.ctx.options.prototypeReplacements.get(prot.constuctor);
|
|
369
|
-
if (replace) {
|
|
370
|
-
done(undefined, new Prop(replace(a, false), b));
|
|
371
|
-
return;
|
|
372
|
-
}
|
|
373
|
-
if (whitelist && (!whitelist.size || whitelist.has(b))) {
|
|
374
|
-
break;
|
|
375
|
-
}
|
|
376
|
-
throw new SandboxError(`Method or property access not permitted: ${prot.constructor.name}.${b}`);
|
|
377
|
-
}
|
|
379
|
+
if (whitelist && (!whitelist.size || whitelist.has(b))) {
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
throw new SandboxError(`Static method or property access not permitted: ${a.name}.${b}`);
|
|
378
383
|
}
|
|
379
|
-
;
|
|
380
384
|
}
|
|
381
385
|
}
|
|
382
|
-
if (
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
let g = obj.isGlobal || (isFunction && !sandboxedFunctions.has(a)) || context.ctx.globalsWhitelist.has(a);
|
|
391
|
-
done(undefined, new Prop(a, b, false, g));
|
|
392
|
-
},
|
|
393
|
-
'call': (exec, done, ticks, a, b, obj, context, scope) => {
|
|
394
|
-
if (context.ctx.options.forbidFunctionCalls)
|
|
395
|
-
throw new SandboxError("Function invocations are not allowed");
|
|
396
|
-
if (typeof a !== 'function') {
|
|
397
|
-
throw new TypeError(`${obj.prop} is not a function`);
|
|
398
|
-
}
|
|
399
|
-
const args = b.map((item) => {
|
|
400
|
-
if (item instanceof SpreadArray) {
|
|
401
|
-
return [...item.item];
|
|
402
|
-
}
|
|
403
|
-
else {
|
|
404
|
-
return [item];
|
|
405
|
-
}
|
|
406
|
-
}).flat();
|
|
407
|
-
execMany(ticks, exec, toLispArray(args), (err, vals) => {
|
|
408
|
-
var _a, _b;
|
|
409
|
-
if (err) {
|
|
410
|
-
done(err);
|
|
411
|
-
return;
|
|
412
|
-
}
|
|
413
|
-
if (typeof obj === 'function') {
|
|
414
|
-
done(undefined, obj(...vals));
|
|
415
|
-
return;
|
|
416
|
-
}
|
|
417
|
-
if (obj.context[obj.prop] === JSON.stringify && context.getSubscriptions.size) {
|
|
418
|
-
const cache = new Set();
|
|
419
|
-
const recurse = (x) => {
|
|
420
|
-
if (!x || !(typeof x === 'object') || cache.has(x))
|
|
386
|
+
else if (b !== 'constructor') {
|
|
387
|
+
let prot = a;
|
|
388
|
+
while (prot = Object.getPrototypeOf(prot)) {
|
|
389
|
+
if (prot.hasOwnProperty(b)) {
|
|
390
|
+
const whitelist = context.ctx.prototypeWhitelist.get(prot);
|
|
391
|
+
const replace = context.ctx.options.prototypeReplacements.get(prot.constuctor);
|
|
392
|
+
if (replace) {
|
|
393
|
+
done(undefined, new Prop(replace(a, false), b));
|
|
421
394
|
return;
|
|
422
|
-
cache.add(x);
|
|
423
|
-
for (let y in x) {
|
|
424
|
-
context.getSubscriptions.forEach((cb) => cb(x, y));
|
|
425
|
-
recurse(x[y]);
|
|
426
395
|
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
let change;
|
|
432
|
-
let changed = false;
|
|
433
|
-
if (obj.prop === "push") {
|
|
434
|
-
change = {
|
|
435
|
-
type: "push",
|
|
436
|
-
added: vals
|
|
437
|
-
};
|
|
438
|
-
changed = !!vals.length;
|
|
439
|
-
}
|
|
440
|
-
else if (obj.prop === "pop") {
|
|
441
|
-
change = {
|
|
442
|
-
type: "pop",
|
|
443
|
-
removed: obj.context.slice(-1)
|
|
444
|
-
};
|
|
445
|
-
changed = !!change.removed.length;
|
|
446
|
-
}
|
|
447
|
-
else if (obj.prop === "shift") {
|
|
448
|
-
change = {
|
|
449
|
-
type: "shift",
|
|
450
|
-
removed: obj.context.slice(0, 1)
|
|
451
|
-
};
|
|
452
|
-
changed = !!change.removed.length;
|
|
453
|
-
}
|
|
454
|
-
else if (obj.prop === "unshift") {
|
|
455
|
-
change = {
|
|
456
|
-
type: "unshift",
|
|
457
|
-
added: vals
|
|
458
|
-
};
|
|
459
|
-
changed = !!vals.length;
|
|
460
|
-
}
|
|
461
|
-
else if (obj.prop === "splice") {
|
|
462
|
-
change = {
|
|
463
|
-
type: "splice",
|
|
464
|
-
startIndex: vals[0],
|
|
465
|
-
deleteCount: vals[1] === undefined ? obj.context.length : vals[1],
|
|
466
|
-
added: vals.slice(2),
|
|
467
|
-
removed: obj.context.slice(vals[0], vals[1] === undefined ? undefined : vals[0] + vals[1])
|
|
468
|
-
};
|
|
469
|
-
changed = !!change.added.length || !!change.removed.length;
|
|
470
|
-
}
|
|
471
|
-
else if (obj.prop === "reverse" || obj.prop === "sort") {
|
|
472
|
-
change = { type: obj.prop };
|
|
473
|
-
changed = !!obj.context.length;
|
|
474
|
-
}
|
|
475
|
-
else if (obj.prop === "copyWithin") {
|
|
476
|
-
let len = vals[2] === undefined ? obj.context.length - vals[1] : Math.min(obj.context.length, vals[2] - vals[1]);
|
|
477
|
-
change = {
|
|
478
|
-
type: "copyWithin",
|
|
479
|
-
startIndex: vals[0],
|
|
480
|
-
endIndex: vals[0] + len,
|
|
481
|
-
added: obj.context.slice(vals[1], vals[1] + len),
|
|
482
|
-
removed: obj.context.slice(vals[0], vals[0] + len)
|
|
483
|
-
};
|
|
484
|
-
changed = !!change.added.length || !!change.removed.length;
|
|
485
|
-
}
|
|
486
|
-
if (changed) {
|
|
487
|
-
(_a = context.changeSubscriptions.get(obj.context)) === null || _a === void 0 ? void 0 : _a.forEach((cb) => cb(change));
|
|
488
|
-
(_b = context.changeSubscriptionsGlobal.get(obj.context)) === null || _b === void 0 ? void 0 : _b.forEach((cb) => cb(change));
|
|
396
|
+
if (whitelist && (!whitelist.size || whitelist.has(b))) {
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
throw new SandboxError(`Method or property access not permitted: ${prot.constructor.name}.${b}`);
|
|
489
400
|
}
|
|
490
401
|
}
|
|
491
|
-
|
|
492
|
-
done(undefined, obj.context[obj.prop](...vals));
|
|
493
|
-
}, scope, context);
|
|
494
|
-
},
|
|
495
|
-
'createObject': (exec, done, ticks, a, b, obj, context, scope) => {
|
|
496
|
-
let res = {};
|
|
497
|
-
for (let item of b) {
|
|
498
|
-
if (item instanceof SpreadObject) {
|
|
499
|
-
res = { ...res, ...item.item };
|
|
500
|
-
}
|
|
501
|
-
else {
|
|
502
|
-
res[item.key] = item.val;
|
|
503
|
-
}
|
|
402
|
+
;
|
|
504
403
|
}
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
404
|
+
}
|
|
405
|
+
if (context.evals.has(a[b])) {
|
|
406
|
+
done(undefined, context.evals.get(a[b]));
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
if (a[b] === globalThis) {
|
|
410
|
+
done(undefined, context.ctx.globalScope.get('this'));
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
let g = obj.isGlobal || (isFunction && !sandboxedFunctions.has(a)) || context.ctx.globalsWhitelist.has(a);
|
|
414
|
+
done(undefined, new Prop(a, b, false, g));
|
|
415
|
+
});
|
|
416
|
+
addOps(5 /* LispType.Call */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
417
|
+
if (context.ctx.options.forbidFunctionCalls)
|
|
418
|
+
throw new SandboxError("Function invocations are not allowed");
|
|
419
|
+
if (typeof a !== 'function') {
|
|
420
|
+
throw new TypeError(`${typeof obj.prop === 'symbol' ? 'Symbol' : obj.prop} is not a function`);
|
|
421
|
+
}
|
|
422
|
+
const vals = b.map((item) => {
|
|
423
|
+
if (item instanceof SpreadArray) {
|
|
424
|
+
return [...item.item];
|
|
525
425
|
}
|
|
526
426
|
else {
|
|
527
|
-
|
|
528
|
-
}
|
|
529
|
-
},
|
|
530
|
-
'literal': (exec, done, ticks, a, b, obj, context, scope) => {
|
|
531
|
-
let name = context.constants.literals[b].a;
|
|
532
|
-
let found = toLispArray([]);
|
|
533
|
-
let f;
|
|
534
|
-
let resnums = [];
|
|
535
|
-
while (f = literalRegex.exec(name)) {
|
|
536
|
-
if (!f[2]) {
|
|
537
|
-
found.push(context.constants.literals[b].b[parseInt(f[3], 10)]);
|
|
538
|
-
resnums.push(f[3]);
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
execMany(ticks, exec, found, (err, processed) => {
|
|
542
|
-
const reses = {};
|
|
543
|
-
if (err) {
|
|
544
|
-
done(err);
|
|
545
|
-
return;
|
|
546
|
-
}
|
|
547
|
-
for (let i in resnums) {
|
|
548
|
-
const num = resnums[i];
|
|
549
|
-
reses[num] = processed[i];
|
|
550
|
-
}
|
|
551
|
-
done(undefined, name.replace(/(\\\\)*(\\)?\${(\d+)}/g, (match, $$, $, num) => {
|
|
552
|
-
if ($)
|
|
553
|
-
return match;
|
|
554
|
-
let res = reses[num];
|
|
555
|
-
return ($$ ? $$ : '') + `${valueOrProp(res, context)}`;
|
|
556
|
-
}));
|
|
557
|
-
}, scope, context);
|
|
558
|
-
},
|
|
559
|
-
'spreadArray': (exec, done, ticks, a, b, obj, context, scope) => {
|
|
560
|
-
exec(ticks, b, scope, context, (err, res) => {
|
|
561
|
-
if (err) {
|
|
562
|
-
done(err);
|
|
563
|
-
return;
|
|
564
|
-
}
|
|
565
|
-
done(undefined, new SpreadArray(res));
|
|
566
|
-
});
|
|
567
|
-
},
|
|
568
|
-
'spreadObject': (exec, done, ticks, a, b, obj, context, scope) => {
|
|
569
|
-
exec(ticks, b, scope, context, (err, res) => {
|
|
570
|
-
if (err) {
|
|
571
|
-
done(err);
|
|
572
|
-
return;
|
|
573
|
-
}
|
|
574
|
-
done(undefined, new SpreadObject(res));
|
|
575
|
-
});
|
|
576
|
-
},
|
|
577
|
-
'!': (exec, done, ticks, a, b) => done(undefined, !b),
|
|
578
|
-
'~': (exec, done, ticks, a, b) => done(undefined, ~b),
|
|
579
|
-
'++$': (exec, done, ticks, a, b, obj, context) => {
|
|
580
|
-
assignCheck(obj, context);
|
|
581
|
-
done(undefined, ++obj.context[obj.prop]);
|
|
582
|
-
},
|
|
583
|
-
'$++': (exec, done, ticks, a, b, obj, context) => {
|
|
584
|
-
assignCheck(obj, context);
|
|
585
|
-
done(undefined, obj.context[obj.prop]++);
|
|
586
|
-
},
|
|
587
|
-
'--$': (exec, done, ticks, a, b, obj, context) => {
|
|
588
|
-
assignCheck(obj, context);
|
|
589
|
-
done(undefined, --obj.context[obj.prop]);
|
|
590
|
-
},
|
|
591
|
-
'$--': (exec, done, ticks, a, b, obj, context) => {
|
|
592
|
-
assignCheck(obj, context);
|
|
593
|
-
done(undefined, obj.context[obj.prop]--);
|
|
594
|
-
},
|
|
595
|
-
'=': (exec, done, ticks, a, b, obj, context) => {
|
|
596
|
-
assignCheck(obj, context);
|
|
597
|
-
done(undefined, obj.context[obj.prop] = b);
|
|
598
|
-
},
|
|
599
|
-
'+=': (exec, done, ticks, a, b, obj, context) => {
|
|
600
|
-
assignCheck(obj, context);
|
|
601
|
-
done(undefined, obj.context[obj.prop] += b);
|
|
602
|
-
},
|
|
603
|
-
'-=': (exec, done, ticks, a, b, obj, context) => {
|
|
604
|
-
assignCheck(obj, context);
|
|
605
|
-
done(undefined, obj.context[obj.prop] -= b);
|
|
606
|
-
},
|
|
607
|
-
'/=': (exec, done, ticks, a, b, obj, context) => {
|
|
608
|
-
assignCheck(obj, context);
|
|
609
|
-
done(undefined, obj.context[obj.prop] /= b);
|
|
610
|
-
},
|
|
611
|
-
'*=': (exec, done, ticks, a, b, obj, context) => {
|
|
612
|
-
assignCheck(obj, context);
|
|
613
|
-
done(undefined, obj.context[obj.prop] *= b);
|
|
614
|
-
},
|
|
615
|
-
'**=': (exec, done, ticks, a, b, obj, context) => {
|
|
616
|
-
assignCheck(obj, context);
|
|
617
|
-
done(undefined, obj.context[obj.prop] **= b);
|
|
618
|
-
},
|
|
619
|
-
'%=': (exec, done, ticks, a, b, obj, context) => {
|
|
620
|
-
assignCheck(obj, context);
|
|
621
|
-
done(undefined, obj.context[obj.prop] %= b);
|
|
622
|
-
},
|
|
623
|
-
'^=': (exec, done, ticks, a, b, obj, context) => {
|
|
624
|
-
assignCheck(obj, context);
|
|
625
|
-
done(undefined, obj.context[obj.prop] ^= b);
|
|
626
|
-
},
|
|
627
|
-
'&=': (exec, done, ticks, a, b, obj, context) => {
|
|
628
|
-
assignCheck(obj, context);
|
|
629
|
-
done(undefined, obj.context[obj.prop] &= b);
|
|
630
|
-
},
|
|
631
|
-
'|=': (exec, done, ticks, a, b, obj, context) => {
|
|
632
|
-
assignCheck(obj, context);
|
|
633
|
-
done(undefined, obj.context[obj.prop] |= b);
|
|
634
|
-
},
|
|
635
|
-
'<<=': (exec, done, ticks, a, b, obj, context) => {
|
|
636
|
-
assignCheck(obj, context);
|
|
637
|
-
done(undefined, obj.context[obj.prop] <<= b);
|
|
638
|
-
},
|
|
639
|
-
'>>=': (exec, done, ticks, a, b, obj, context) => {
|
|
640
|
-
assignCheck(obj, context);
|
|
641
|
-
done(undefined, obj.context[obj.prop] >>= b);
|
|
642
|
-
},
|
|
643
|
-
'>>>=': (exec, done, ticks, a, b, obj, context) => {
|
|
644
|
-
assignCheck(obj, context);
|
|
645
|
-
done(undefined, obj.context[obj.prop] >>= b);
|
|
646
|
-
},
|
|
647
|
-
'?': (exec, done, ticks, a, b, obj, context, scope) => {
|
|
648
|
-
if (!(b instanceof If)) {
|
|
649
|
-
throw new SyntaxError('Invalid inline if');
|
|
650
|
-
}
|
|
651
|
-
exec(ticks, a, scope, context, (err, res) => {
|
|
652
|
-
if (err) {
|
|
653
|
-
done(err);
|
|
654
|
-
}
|
|
655
|
-
else {
|
|
656
|
-
exec(ticks, valueOrProp(res, context) ? b.t : b.f, scope, context, done);
|
|
657
|
-
}
|
|
658
|
-
});
|
|
659
|
-
},
|
|
660
|
-
'>': (exec, done, ticks, a, b) => done(undefined, a > b),
|
|
661
|
-
'<': (exec, done, ticks, a, b) => done(undefined, a < b),
|
|
662
|
-
'>=': (exec, done, ticks, a, b) => done(undefined, a >= b),
|
|
663
|
-
'<=': (exec, done, ticks, a, b) => done(undefined, a <= b),
|
|
664
|
-
'==': (exec, done, ticks, a, b) => done(undefined, a == b),
|
|
665
|
-
'===': (exec, done, ticks, a, b) => done(undefined, a === b),
|
|
666
|
-
'!=': (exec, done, ticks, a, b) => done(undefined, a != b),
|
|
667
|
-
'!==': (exec, done, ticks, a, b) => done(undefined, a !== b),
|
|
668
|
-
'&&': (exec, done, ticks, a, b) => done(undefined, a && b),
|
|
669
|
-
'||': (exec, done, ticks, a, b) => done(undefined, a || b),
|
|
670
|
-
'&': (exec, done, ticks, a, b) => done(undefined, a & b),
|
|
671
|
-
'|': (exec, done, ticks, a, b) => done(undefined, a | b),
|
|
672
|
-
':': (exec, done, ticks, a, b) => done(undefined, new If(a, b)),
|
|
673
|
-
'+': (exec, done, ticks, a, b) => done(undefined, a + b),
|
|
674
|
-
'-': (exec, done, ticks, a, b) => done(undefined, a - b),
|
|
675
|
-
'$+': (exec, done, ticks, a, b) => done(undefined, +b),
|
|
676
|
-
'$-': (exec, done, ticks, a, b) => done(undefined, -b),
|
|
677
|
-
'/': (exec, done, ticks, a, b) => done(undefined, a / b),
|
|
678
|
-
'^': (exec, done, ticks, a, b) => done(undefined, a ^ b),
|
|
679
|
-
'*': (exec, done, ticks, a, b) => done(undefined, a * b),
|
|
680
|
-
'%': (exec, done, ticks, a, b) => done(undefined, a % b),
|
|
681
|
-
'<<': (exec, done, ticks, a, b) => done(undefined, a << b),
|
|
682
|
-
'>>': (exec, done, ticks, a, b) => done(undefined, a >> b),
|
|
683
|
-
'>>>': (exec, done, ticks, a, b) => done(undefined, a >>> b),
|
|
684
|
-
'typeof': (exec, done, ticks, a, b, obj, context, scope) => {
|
|
685
|
-
exec(ticks, b, scope, context, (e, prop) => {
|
|
686
|
-
done(undefined, typeof valueOrProp(prop, context));
|
|
687
|
-
});
|
|
688
|
-
},
|
|
689
|
-
'instanceof': (exec, done, ticks, a, b) => done(undefined, a instanceof b),
|
|
690
|
-
'in': (exec, done, ticks, a, b) => done(undefined, a in b),
|
|
691
|
-
'delete': (exec, done, ticks, a, b, obj, context, scope, bobj) => {
|
|
692
|
-
if (bobj.context === undefined) {
|
|
693
|
-
done(undefined, true);
|
|
694
|
-
return;
|
|
427
|
+
return [item];
|
|
695
428
|
}
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
exec(ticks, b, scope, context, (err, res) => {
|
|
706
|
-
if (err) {
|
|
707
|
-
done(err);
|
|
708
|
-
return;
|
|
709
|
-
}
|
|
710
|
-
done(undefined, scope.declare(a, VarType.var, res));
|
|
711
|
-
});
|
|
712
|
-
},
|
|
713
|
-
'let': (exec, done, ticks, a, b, obj, context, scope, bobj) => {
|
|
714
|
-
exec(ticks, b, scope, context, (err, res) => {
|
|
715
|
-
if (err) {
|
|
716
|
-
done(err);
|
|
717
|
-
return;
|
|
718
|
-
}
|
|
719
|
-
done(undefined, scope.declare(a, VarType.let, res, bobj && bobj.isGlobal));
|
|
720
|
-
});
|
|
721
|
-
},
|
|
722
|
-
'const': (exec, done, ticks, a, b, obj, context, scope, bobj) => {
|
|
723
|
-
exec(ticks, b, scope, context, (err, res) => {
|
|
724
|
-
if (err) {
|
|
725
|
-
done(err);
|
|
429
|
+
}).flat().map((item) => valueOrProp(item, context));
|
|
430
|
+
if (typeof obj === 'function') {
|
|
431
|
+
done(undefined, obj(...vals));
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
if (obj.context[obj.prop] === JSON.stringify && context.getSubscriptions.size) {
|
|
435
|
+
const cache = new Set();
|
|
436
|
+
const recurse = (x) => {
|
|
437
|
+
if (!x || !(typeof x === 'object') || cache.has(x))
|
|
726
438
|
return;
|
|
439
|
+
cache.add(x);
|
|
440
|
+
for (let y in x) {
|
|
441
|
+
context.getSubscriptions.forEach((cb) => cb(x, y));
|
|
442
|
+
recurse(x[y]);
|
|
727
443
|
}
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
444
|
+
};
|
|
445
|
+
recurse(vals[0]);
|
|
446
|
+
}
|
|
447
|
+
if (obj.context instanceof Array && arrayChange.has(obj.context[obj.prop]) && (context.changeSubscriptions.get(obj.context) || context.changeSubscriptionsGlobal.get(obj.context))) {
|
|
448
|
+
let change;
|
|
449
|
+
let changed = false;
|
|
450
|
+
if (obj.prop === "push") {
|
|
451
|
+
change = {
|
|
452
|
+
type: "push",
|
|
453
|
+
added: vals
|
|
454
|
+
};
|
|
455
|
+
changed = !!vals.length;
|
|
456
|
+
}
|
|
457
|
+
else if (obj.prop === "pop") {
|
|
458
|
+
change = {
|
|
459
|
+
type: "pop",
|
|
460
|
+
removed: obj.context.slice(-1)
|
|
461
|
+
};
|
|
462
|
+
changed = !!change.removed.length;
|
|
463
|
+
}
|
|
464
|
+
else if (obj.prop === "shift") {
|
|
465
|
+
change = {
|
|
466
|
+
type: "shift",
|
|
467
|
+
removed: obj.context.slice(0, 1)
|
|
468
|
+
};
|
|
469
|
+
changed = !!change.removed.length;
|
|
470
|
+
}
|
|
471
|
+
else if (obj.prop === "unshift") {
|
|
472
|
+
change = {
|
|
473
|
+
type: "unshift",
|
|
474
|
+
added: vals
|
|
475
|
+
};
|
|
476
|
+
changed = !!vals.length;
|
|
477
|
+
}
|
|
478
|
+
else if (obj.prop === "splice") {
|
|
479
|
+
change = {
|
|
480
|
+
type: "splice",
|
|
481
|
+
startIndex: vals[0],
|
|
482
|
+
deleteCount: vals[1] === undefined ? obj.context.length : vals[1],
|
|
483
|
+
added: vals.slice(2),
|
|
484
|
+
removed: obj.context.slice(vals[0], vals[1] === undefined ? undefined : vals[0] + vals[1])
|
|
485
|
+
};
|
|
486
|
+
changed = !!change.added.length || !!change.removed.length;
|
|
487
|
+
}
|
|
488
|
+
else if (obj.prop === "reverse" || obj.prop === "sort") {
|
|
489
|
+
change = { type: obj.prop };
|
|
490
|
+
changed = !!obj.context.length;
|
|
491
|
+
}
|
|
492
|
+
else if (obj.prop === "copyWithin") {
|
|
493
|
+
let len = vals[2] === undefined ? obj.context.length - vals[1] : Math.min(obj.context.length, vals[2] - vals[1]);
|
|
494
|
+
change = {
|
|
495
|
+
type: "copyWithin",
|
|
496
|
+
startIndex: vals[0],
|
|
497
|
+
endIndex: vals[0] + len,
|
|
498
|
+
added: obj.context.slice(vals[1], vals[1] + len),
|
|
499
|
+
removed: obj.context.slice(vals[0], vals[0] + len)
|
|
500
|
+
};
|
|
501
|
+
changed = !!change.added.length || !!change.removed.length;
|
|
502
|
+
}
|
|
503
|
+
if (changed) {
|
|
504
|
+
context.changeSubscriptions.get(obj.context)?.forEach((cb) => cb(change));
|
|
505
|
+
context.changeSubscriptionsGlobal.get(obj.context)?.forEach((cb) => cb(change));
|
|
735
506
|
}
|
|
736
|
-
|
|
737
|
-
|
|
507
|
+
}
|
|
508
|
+
obj.get(context);
|
|
509
|
+
done(undefined, obj.context[obj.prop](...vals));
|
|
510
|
+
});
|
|
511
|
+
addOps(22 /* LispType.CreateObject */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
512
|
+
let res = {};
|
|
513
|
+
for (let item of b) {
|
|
514
|
+
if (item.key instanceof SpreadObject) {
|
|
515
|
+
res = { ...res, ...item.key.item };
|
|
738
516
|
}
|
|
739
517
|
else {
|
|
740
|
-
|
|
741
|
-
}
|
|
742
|
-
},
|
|
743
|
-
'function': (exec, done, ticks, a, b, obj, context, scope) => {
|
|
744
|
-
if (typeof obj.b === "string" || obj.b instanceof CodeString) {
|
|
745
|
-
obj.b = b = lispifyFunction(new CodeString(obj.b), context.constants);
|
|
518
|
+
res[item.key] = item.val;
|
|
746
519
|
}
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
520
|
+
}
|
|
521
|
+
done(undefined, res);
|
|
522
|
+
});
|
|
523
|
+
addOps(6 /* LispType.KeyVal */, (exec, done, ticks, a, b) => done(undefined, new KeyVal(a, b)));
|
|
524
|
+
addOps(12 /* LispType.CreateArray */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
525
|
+
const items = b.map((item) => {
|
|
526
|
+
if (item instanceof SpreadArray) {
|
|
527
|
+
return [...item.item];
|
|
752
528
|
}
|
|
753
529
|
else {
|
|
754
|
-
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
530
|
+
return [item];
|
|
531
|
+
}
|
|
532
|
+
}).flat().map((item) => valueOrProp(item, context));
|
|
533
|
+
done(undefined, items);
|
|
534
|
+
});
|
|
535
|
+
addOps(23 /* LispType.Group */, (exec, done, ticks, a, b) => done(undefined, b));
|
|
536
|
+
addOps(35 /* LispType.GlobalSymbol */, (exec, done, ticks, a, b) => {
|
|
537
|
+
switch (b) {
|
|
538
|
+
case 'true': return done(undefined, true);
|
|
539
|
+
case 'false': return done(undefined, false);
|
|
540
|
+
case 'null': return done(undefined, null);
|
|
541
|
+
case 'undefined': return done(undefined, undefined);
|
|
542
|
+
case 'NaN': return done(undefined, NaN);
|
|
543
|
+
case 'Infinity': return done(undefined, Infinity);
|
|
544
|
+
}
|
|
545
|
+
done(new Error('Unknown symbol: ' + b));
|
|
546
|
+
});
|
|
547
|
+
addOps(7 /* LispType.Number */, (exec, done, ticks, a, b) => done(undefined, Number(b)));
|
|
548
|
+
addOps(83 /* LispType.BigInt */, (exec, done, ticks, a, b) => done(undefined, BigInt(b)));
|
|
549
|
+
addOps(2 /* LispType.StringIndex */, (exec, done, ticks, a, b, obj, context) => done(undefined, context.constants.strings[parseInt(b)]));
|
|
550
|
+
addOps(85 /* LispType.RegexIndex */, (exec, done, ticks, a, b, obj, context) => {
|
|
551
|
+
const reg = context.constants.regexes[parseInt(b)];
|
|
552
|
+
if (!context.ctx.globalsWhitelist.has(RegExp)) {
|
|
553
|
+
throw new SandboxError("Regex not permitted");
|
|
554
|
+
}
|
|
555
|
+
else {
|
|
556
|
+
done(undefined, new RegExp(reg.regex, reg.flags));
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
addOps(84 /* LispType.LiteralIndex */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
560
|
+
let item = context.constants.literals[parseInt(b)];
|
|
561
|
+
const [, name, js] = item;
|
|
562
|
+
let found = [];
|
|
563
|
+
let f;
|
|
564
|
+
let resnums = [];
|
|
565
|
+
while (f = literalRegex.exec(name)) {
|
|
566
|
+
if (!f[2]) {
|
|
567
|
+
found.push(js[parseInt(f[3], 10)]);
|
|
568
|
+
resnums.push(f[3]);
|
|
764
569
|
}
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
570
|
+
}
|
|
571
|
+
exec(ticks, found, scope, context, (err, processed) => {
|
|
572
|
+
const reses = {};
|
|
573
|
+
if (err) {
|
|
574
|
+
done(err);
|
|
575
|
+
return;
|
|
769
576
|
}
|
|
770
|
-
let
|
|
771
|
-
|
|
772
|
-
|
|
577
|
+
for (let i in resnums) {
|
|
578
|
+
const num = resnums[i];
|
|
579
|
+
reses[num] = processed[i];
|
|
773
580
|
}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
581
|
+
done(undefined, name.replace(/(\\\\)*(\\)?\${(\d+)}/g, (match, $$, $, num) => {
|
|
582
|
+
if ($)
|
|
583
|
+
return match;
|
|
584
|
+
let res = reses[num];
|
|
585
|
+
return ($$ ? $$ : '') + `${valueOrProp(res, context)}`;
|
|
586
|
+
}));
|
|
587
|
+
});
|
|
588
|
+
});
|
|
589
|
+
addOps(18 /* LispType.SpreadArray */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
590
|
+
done(undefined, new SpreadArray(b));
|
|
591
|
+
});
|
|
592
|
+
addOps(17 /* LispType.SpreadObject */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
593
|
+
done(undefined, new SpreadObject(b));
|
|
594
|
+
});
|
|
595
|
+
addOps(24 /* LispType.Not */, (exec, done, ticks, a, b) => done(undefined, !b));
|
|
596
|
+
addOps(64 /* LispType.Inverse */, (exec, done, ticks, a, b) => done(undefined, ~b));
|
|
597
|
+
addOps(25 /* LispType.IncrementBefore */, (exec, done, ticks, a, b, obj, context) => {
|
|
598
|
+
assignCheck(obj, context);
|
|
599
|
+
done(undefined, ++obj.context[obj.prop]);
|
|
600
|
+
});
|
|
601
|
+
addOps(26 /* LispType.IncrementAfter */, (exec, done, ticks, a, b, obj, context) => {
|
|
602
|
+
assignCheck(obj, context);
|
|
603
|
+
done(undefined, obj.context[obj.prop]++);
|
|
604
|
+
});
|
|
605
|
+
addOps(27 /* LispType.DecrementBefore */, (exec, done, ticks, a, b, obj, context) => {
|
|
606
|
+
assignCheck(obj, context);
|
|
607
|
+
done(undefined, --obj.context[obj.prop]);
|
|
608
|
+
});
|
|
609
|
+
addOps(28 /* LispType.DecrementAfter */, (exec, done, ticks, a, b, obj, context) => {
|
|
610
|
+
assignCheck(obj, context);
|
|
611
|
+
done(undefined, obj.context[obj.prop]--);
|
|
612
|
+
});
|
|
613
|
+
addOps(9 /* LispType.Assign */, (exec, done, ticks, a, b, obj, context) => {
|
|
614
|
+
assignCheck(obj, context);
|
|
615
|
+
done(undefined, obj.context[obj.prop] = b);
|
|
616
|
+
});
|
|
617
|
+
addOps(66 /* LispType.AddEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
618
|
+
assignCheck(obj, context);
|
|
619
|
+
done(undefined, obj.context[obj.prop] += b);
|
|
620
|
+
});
|
|
621
|
+
addOps(65 /* LispType.SubractEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
622
|
+
assignCheck(obj, context);
|
|
623
|
+
done(undefined, obj.context[obj.prop] -= b);
|
|
624
|
+
});
|
|
625
|
+
addOps(67 /* LispType.DivideEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
626
|
+
assignCheck(obj, context);
|
|
627
|
+
done(undefined, obj.context[obj.prop] /= b);
|
|
628
|
+
});
|
|
629
|
+
addOps(69 /* LispType.MultiplyEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
630
|
+
assignCheck(obj, context);
|
|
631
|
+
done(undefined, obj.context[obj.prop] *= b);
|
|
632
|
+
});
|
|
633
|
+
addOps(68 /* LispType.PowerEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
634
|
+
assignCheck(obj, context);
|
|
635
|
+
done(undefined, obj.context[obj.prop] **= b);
|
|
636
|
+
});
|
|
637
|
+
addOps(70 /* LispType.ModulusEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
638
|
+
assignCheck(obj, context);
|
|
639
|
+
done(undefined, obj.context[obj.prop] %= b);
|
|
640
|
+
});
|
|
641
|
+
addOps(71 /* LispType.BitNegateEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
642
|
+
assignCheck(obj, context);
|
|
643
|
+
done(undefined, obj.context[obj.prop] ^= b);
|
|
644
|
+
});
|
|
645
|
+
addOps(72 /* LispType.BitAndEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
646
|
+
assignCheck(obj, context);
|
|
647
|
+
done(undefined, obj.context[obj.prop] &= b);
|
|
648
|
+
});
|
|
649
|
+
addOps(73 /* LispType.BitOrEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
650
|
+
assignCheck(obj, context);
|
|
651
|
+
done(undefined, obj.context[obj.prop] |= b);
|
|
652
|
+
});
|
|
653
|
+
addOps(76 /* LispType.ShiftLeftEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
654
|
+
assignCheck(obj, context);
|
|
655
|
+
done(undefined, obj.context[obj.prop] <<= b);
|
|
656
|
+
});
|
|
657
|
+
addOps(75 /* LispType.ShiftRightEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
658
|
+
assignCheck(obj, context);
|
|
659
|
+
done(undefined, obj.context[obj.prop] >>= b);
|
|
660
|
+
});
|
|
661
|
+
addOps(74 /* LispType.UnsignedShiftRightEquals */, (exec, done, ticks, a, b, obj, context) => {
|
|
662
|
+
assignCheck(obj, context);
|
|
663
|
+
done(undefined, obj.context[obj.prop] >>= b);
|
|
664
|
+
});
|
|
665
|
+
addOps(57 /* LispType.LargerThan */, (exec, done, ticks, a, b) => done(undefined, a > b));
|
|
666
|
+
addOps(56 /* LispType.SmallerThan */, (exec, done, ticks, a, b) => done(undefined, a < b));
|
|
667
|
+
addOps(55 /* LispType.LargerEqualThan */, (exec, done, ticks, a, b) => done(undefined, a >= b));
|
|
668
|
+
addOps(54 /* LispType.SmallerEqualThan */, (exec, done, ticks, a, b) => done(undefined, a <= b));
|
|
669
|
+
addOps(52 /* LispType.Equal */, (exec, done, ticks, a, b) => done(undefined, a == b));
|
|
670
|
+
addOps(32 /* LispType.StrictEqual */, (exec, done, ticks, a, b) => done(undefined, a === b));
|
|
671
|
+
addOps(53 /* LispType.NotEqual */, (exec, done, ticks, a, b) => done(undefined, a != b));
|
|
672
|
+
addOps(31 /* LispType.StrictNotEqual */, (exec, done, ticks, a, b) => done(undefined, a !== b));
|
|
673
|
+
addOps(29 /* LispType.And */, (exec, done, ticks, a, b) => done(undefined, a && b));
|
|
674
|
+
addOps(30 /* LispType.Or */, (exec, done, ticks, a, b) => done(undefined, a || b));
|
|
675
|
+
addOps(77 /* LispType.BitAnd */, (exec, done, ticks, a, b) => done(undefined, a & b));
|
|
676
|
+
addOps(78 /* LispType.BitOr */, (exec, done, ticks, a, b) => done(undefined, a | b));
|
|
677
|
+
addOps(33 /* LispType.Plus */, (exec, done, ticks, a, b) => done(undefined, a + b));
|
|
678
|
+
addOps(47 /* LispType.Minus */, (exec, done, ticks, a, b) => done(undefined, a - b));
|
|
679
|
+
addOps(59 /* LispType.Positive */, (exec, done, ticks, a, b) => done(undefined, +b));
|
|
680
|
+
addOps(58 /* LispType.Negative */, (exec, done, ticks, a, b) => done(undefined, -b));
|
|
681
|
+
addOps(48 /* LispType.Divide */, (exec, done, ticks, a, b) => done(undefined, a / b));
|
|
682
|
+
addOps(79 /* LispType.BitNegate */, (exec, done, ticks, a, b) => done(undefined, a ^ b));
|
|
683
|
+
addOps(50 /* LispType.Multiply */, (exec, done, ticks, a, b) => done(undefined, a * b));
|
|
684
|
+
addOps(51 /* LispType.Modulus */, (exec, done, ticks, a, b) => done(undefined, a % b));
|
|
685
|
+
addOps(80 /* LispType.BitShiftLeft */, (exec, done, ticks, a, b) => done(undefined, a << b));
|
|
686
|
+
addOps(81 /* LispType.BitShiftRight */, (exec, done, ticks, a, b) => done(undefined, a >> b));
|
|
687
|
+
addOps(82 /* LispType.BitUnsignedShiftRight */, (exec, done, ticks, a, b) => done(undefined, a >>> b));
|
|
688
|
+
addOps(60 /* LispType.Typeof */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
689
|
+
exec(ticks, b, scope, context, (e, prop) => {
|
|
690
|
+
done(undefined, typeof valueOrProp(prop, context));
|
|
691
|
+
});
|
|
692
|
+
});
|
|
693
|
+
addOps(62 /* LispType.Instanceof */, (exec, done, ticks, a, b) => done(undefined, a instanceof b));
|
|
694
|
+
addOps(63 /* LispType.In */, (exec, done, ticks, a, b) => done(undefined, a in b));
|
|
695
|
+
addOps(61 /* LispType.Delete */, (exec, done, ticks, a, b, obj, context, scope, bobj) => {
|
|
696
|
+
if (bobj.context === undefined) {
|
|
697
|
+
done(undefined, true);
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
assignCheck(bobj, context, 'delete');
|
|
701
|
+
if (bobj.isVariable) {
|
|
702
|
+
done(undefined, false);
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
done(undefined, delete bobj.context[bobj.prop]);
|
|
706
|
+
});
|
|
707
|
+
addOps(8 /* LispType.Return */, (exec, done, ticks, a, b, obj, context) => done(undefined, b));
|
|
708
|
+
addOps(34 /* LispType.Var */, (exec, done, ticks, a, b, obj, context, scope, bobj) => {
|
|
709
|
+
done(undefined, scope.declare(a, VarType.var, b));
|
|
710
|
+
});
|
|
711
|
+
addOps(3 /* LispType.Let */, (exec, done, ticks, a, b, obj, context, scope, bobj) => {
|
|
712
|
+
done(undefined, scope.declare(a, VarType.let, b, bobj && bobj.isGlobal));
|
|
713
|
+
});
|
|
714
|
+
addOps(4 /* LispType.Const */, (exec, done, ticks, a, b, obj, context, scope, bobj) => {
|
|
715
|
+
done(undefined, scope.declare(a, VarType.const, b));
|
|
716
|
+
});
|
|
717
|
+
addOps(11 /* LispType.ArrowFunction */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
718
|
+
a = [...a];
|
|
719
|
+
if (typeof obj[2] === "string" || obj[2] instanceof CodeString) {
|
|
720
|
+
obj[2] = b = lispifyFunction(new CodeString(obj[2]), context.constants);
|
|
721
|
+
}
|
|
722
|
+
if (a.shift()) {
|
|
723
|
+
done(undefined, createFunctionAsync(a, b, ticks, context, scope));
|
|
724
|
+
}
|
|
725
|
+
else {
|
|
726
|
+
done(undefined, createFunction(a, b, ticks, context, scope));
|
|
727
|
+
}
|
|
728
|
+
});
|
|
729
|
+
addOps(37 /* LispType.Function */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
730
|
+
if (typeof obj[2] === "string" || obj[2] instanceof CodeString) {
|
|
731
|
+
obj[2] = b = lispifyFunction(new CodeString(obj[2]), context.constants);
|
|
732
|
+
}
|
|
733
|
+
let isAsync = a.shift();
|
|
734
|
+
let name = a.shift();
|
|
735
|
+
let func;
|
|
736
|
+
if (isAsync === 88 /* LispType.True */) {
|
|
737
|
+
func = createFunctionAsync(a, b, ticks, context, scope, name);
|
|
738
|
+
}
|
|
739
|
+
else {
|
|
740
|
+
func = createFunction(a, b, ticks, context, scope, name);
|
|
741
|
+
}
|
|
742
|
+
if (name) {
|
|
743
|
+
scope.declare(name, VarType.var, func);
|
|
744
|
+
}
|
|
745
|
+
done(undefined, func);
|
|
746
|
+
});
|
|
747
|
+
addOps(10 /* LispType.InlineFunction */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
748
|
+
if (typeof obj[2] === "string" || obj[2] instanceof CodeString) {
|
|
749
|
+
obj[2] = b = lispifyFunction(new CodeString(obj[2]), context.constants);
|
|
750
|
+
}
|
|
751
|
+
let isAsync = a.shift();
|
|
752
|
+
let name = a.shift();
|
|
753
|
+
if (name) {
|
|
754
|
+
scope = new Scope(scope, {});
|
|
755
|
+
}
|
|
756
|
+
let func;
|
|
757
|
+
if (isAsync === 88 /* LispType.True */) {
|
|
758
|
+
func = createFunctionAsync(a, b, ticks, context, scope, name);
|
|
759
|
+
}
|
|
760
|
+
else {
|
|
761
|
+
func = createFunction(a, b, ticks, context, scope, name);
|
|
762
|
+
}
|
|
763
|
+
if (name) {
|
|
764
|
+
scope.declare(name, VarType.let, func);
|
|
765
|
+
}
|
|
766
|
+
done(undefined, func);
|
|
767
|
+
});
|
|
768
|
+
addOps(38 /* LispType.Loop */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
769
|
+
const [checkFirst, startInternal, getIterator, startStep, step, condition, beforeStep] = a;
|
|
770
|
+
let loop = true;
|
|
771
|
+
const loopScope = new Scope(scope, {});
|
|
772
|
+
let internalVars = {
|
|
773
|
+
'$$obj': undefined
|
|
774
|
+
};
|
|
775
|
+
const interalScope = new Scope(loopScope, internalVars);
|
|
776
|
+
if (exec === execAsync) {
|
|
777
|
+
(async () => {
|
|
778
|
+
let ad;
|
|
779
|
+
ad = asyncDone((d) => exec(ticks, startStep, loopScope, context, d));
|
|
780
|
+
internalVars['$$obj'] = (ad = asyncDone((d) => exec(ticks, getIterator, loopScope, context, d))).isInstant === true ? ad.instant : (await ad.p).result;
|
|
781
|
+
ad = asyncDone((d) => exec(ticks, startInternal, interalScope, context, d));
|
|
820
782
|
if (checkFirst)
|
|
821
|
-
loop = (
|
|
783
|
+
loop = (ad = asyncDone((d) => exec(ticks, condition, interalScope, context, d))).isInstant === true ? ad.instant : (await ad.p).result;
|
|
822
784
|
while (loop) {
|
|
823
785
|
let innerLoopVars = {};
|
|
824
|
-
|
|
825
|
-
|
|
786
|
+
ad = asyncDone((d) => exec(ticks, beforeStep, new Scope(interalScope, innerLoopVars), context, d));
|
|
787
|
+
ad.isInstant === true ? ad.instant : (await ad.p).result;
|
|
788
|
+
let res = await executeTreeAsync(ticks, context, b, [new Scope(loopScope, innerLoopVars)], "loop");
|
|
826
789
|
if (res instanceof ExecReturn && res.returned) {
|
|
827
790
|
done(undefined, res);
|
|
828
791
|
return;
|
|
@@ -830,116 +793,131 @@ let ops2 = {
|
|
|
830
793
|
if (res instanceof ExecReturn && res.breakLoop) {
|
|
831
794
|
break;
|
|
832
795
|
}
|
|
833
|
-
|
|
834
|
-
loop = (
|
|
796
|
+
ad = asyncDone((d) => exec(ticks, step, interalScope, context, d));
|
|
797
|
+
loop = (ad = asyncDone((d) => exec(ticks, condition, interalScope, context, d))).isInstant === true ? ad.instant : (await ad.p).result;
|
|
835
798
|
}
|
|
836
799
|
done();
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
done(err);
|
|
800
|
+
})().catch(done);
|
|
801
|
+
}
|
|
802
|
+
else {
|
|
803
|
+
syncDone((d) => exec(ticks, startStep, loopScope, context, d));
|
|
804
|
+
internalVars['$$obj'] = syncDone((d) => exec(ticks, getIterator, loopScope, context, d)).result;
|
|
805
|
+
syncDone((d) => exec(ticks, startInternal, interalScope, context, d));
|
|
806
|
+
if (checkFirst)
|
|
807
|
+
loop = (syncDone((d) => exec(ticks, condition, interalScope, context, d))).result;
|
|
808
|
+
while (loop) {
|
|
809
|
+
let innerLoopVars = {};
|
|
810
|
+
syncDone((d) => exec(ticks, beforeStep, new Scope(interalScope, innerLoopVars), context, d));
|
|
811
|
+
let res = executeTree(ticks, context, b, [new Scope(loopScope, innerLoopVars)], "loop");
|
|
812
|
+
if (res instanceof ExecReturn && res.returned) {
|
|
813
|
+
done(undefined, res);
|
|
852
814
|
return;
|
|
853
815
|
}
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
816
|
+
if (res instanceof ExecReturn && res.breakLoop) {
|
|
817
|
+
break;
|
|
818
|
+
}
|
|
819
|
+
syncDone((d) => exec(ticks, step, interalScope, context, d));
|
|
820
|
+
loop = (syncDone((d) => exec(ticks, condition, interalScope, context, d))).result;
|
|
821
|
+
}
|
|
822
|
+
done();
|
|
823
|
+
}
|
|
824
|
+
});
|
|
825
|
+
addOps(86 /* LispType.LoopAction */, (exec, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch) => {
|
|
826
|
+
if ((inLoopOrSwitch === "switch" && a === "continue") || !inLoopOrSwitch) {
|
|
827
|
+
throw new SandboxError("Illegal " + a + " statement");
|
|
828
|
+
}
|
|
829
|
+
done(undefined, new ExecReturn(context.ctx.auditReport, undefined, false, a === "break", a === "continue"));
|
|
830
|
+
});
|
|
831
|
+
addOps(13 /* LispType.If */, (exec, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch) => {
|
|
832
|
+
exec(ticks, valueOrProp(a, context) ? b.t : b.f, scope, context, done);
|
|
833
|
+
});
|
|
834
|
+
addOps(15 /* LispType.InlineIf */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
835
|
+
exec(ticks, valueOrProp(a, context) ? b.t : b.f, scope, context, done);
|
|
836
|
+
});
|
|
837
|
+
addOps(16 /* LispType.InlineIfCase */, (exec, done, ticks, a, b) => done(undefined, new If(a, b)));
|
|
838
|
+
addOps(14 /* LispType.IfCase */, (exec, done, ticks, a, b) => done(undefined, new If(a, b)));
|
|
839
|
+
addOps(40 /* LispType.Switch */, (exec, done, ticks, a, b, obj, context, scope) => {
|
|
840
|
+
exec(ticks, a, scope, context, (err, toTest) => {
|
|
841
|
+
if (err) {
|
|
842
|
+
done(err);
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
toTest = valueOrProp(toTest, context);
|
|
846
|
+
if (exec === execSync) {
|
|
847
|
+
let res;
|
|
848
|
+
let isTrue = false;
|
|
849
|
+
for (let caseItem of b) {
|
|
850
|
+
if (isTrue || (isTrue = !caseItem[1] || toTest === valueOrProp((syncDone((d) => exec(ticks, caseItem[1], scope, context, d))).result, context))) {
|
|
851
|
+
if (!caseItem[2])
|
|
852
|
+
continue;
|
|
853
|
+
res = executeTree(ticks, context, caseItem[2], [scope], "switch");
|
|
854
|
+
if (res.breakLoop)
|
|
855
|
+
break;
|
|
856
|
+
if (res.returned) {
|
|
857
|
+
done(undefined, res);
|
|
858
|
+
return;
|
|
859
|
+
}
|
|
860
|
+
if (!caseItem[1]) { // default case
|
|
861
|
+
break;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
862
864
|
}
|
|
863
|
-
|
|
864
|
-
|
|
865
|
+
done();
|
|
866
|
+
}
|
|
867
|
+
else {
|
|
868
|
+
(async () => {
|
|
865
869
|
let res;
|
|
866
870
|
let isTrue = false;
|
|
867
871
|
for (let caseItem of b) {
|
|
868
|
-
|
|
869
|
-
|
|
872
|
+
let ad;
|
|
873
|
+
if (isTrue || (isTrue = !caseItem[1] || toTest === valueOrProp((ad = asyncDone((d) => exec(ticks, caseItem[1], scope, context, d))).isInstant === true ? ad.instant : (await ad.p).result, context))) {
|
|
874
|
+
if (!caseItem[2])
|
|
870
875
|
continue;
|
|
871
|
-
res =
|
|
876
|
+
res = await executeTreeAsync(ticks, context, caseItem[2], [scope], "switch");
|
|
872
877
|
if (res.breakLoop)
|
|
873
878
|
break;
|
|
874
879
|
if (res.returned) {
|
|
875
880
|
done(undefined, res);
|
|
876
881
|
return;
|
|
877
882
|
}
|
|
878
|
-
if (!caseItem
|
|
883
|
+
if (!caseItem[1]) { // default case
|
|
879
884
|
break;
|
|
880
885
|
}
|
|
881
886
|
}
|
|
882
887
|
}
|
|
883
888
|
done();
|
|
889
|
+
})().catch(done);
|
|
890
|
+
}
|
|
891
|
+
});
|
|
892
|
+
});
|
|
893
|
+
addOps(39 /* LispType.Try */, (exec, done, ticks, a, b, obj, context, scope, bobj, inLoopOrSwitch) => {
|
|
894
|
+
const [exception, catchBody, finallyBody] = b;
|
|
895
|
+
executeTreeWithDone(exec, (err, res) => {
|
|
896
|
+
executeTreeWithDone(exec, (e) => {
|
|
897
|
+
if (e)
|
|
898
|
+
done(e);
|
|
899
|
+
else if (err) {
|
|
900
|
+
let sc = {};
|
|
901
|
+
if (exception)
|
|
902
|
+
sc[exception] = err;
|
|
903
|
+
executeTreeWithDone(exec, done, ticks, context, catchBody, [new Scope(scope)], inLoopOrSwitch);
|
|
884
904
|
}
|
|
885
905
|
else {
|
|
886
|
-
(
|
|
887
|
-
let res;
|
|
888
|
-
let isTrue = false;
|
|
889
|
-
for (let caseItem of b) {
|
|
890
|
-
let ad;
|
|
891
|
-
if (isTrue || (isTrue = !caseItem.a || toTest === valueOrProp((ad = asyncDone((d) => exec(ticks, caseItem.a, scope, context, d))).isInstant === true ? ad.instant : (await ad.p).result, context))) {
|
|
892
|
-
if (!caseItem.b)
|
|
893
|
-
continue;
|
|
894
|
-
res = await executeTreeAsync(ticks, context, caseItem.b, [scope], "switch");
|
|
895
|
-
if (res.breakLoop)
|
|
896
|
-
break;
|
|
897
|
-
if (res.returned) {
|
|
898
|
-
done(undefined, res);
|
|
899
|
-
return;
|
|
900
|
-
}
|
|
901
|
-
if (!caseItem.a) { // default case
|
|
902
|
-
break;
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
}
|
|
906
|
-
done();
|
|
907
|
-
})().catch(done);
|
|
906
|
+
done(undefined, res);
|
|
908
907
|
}
|
|
909
|
-
});
|
|
910
|
-
},
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
}
|
|
923
|
-
else {
|
|
924
|
-
done(undefined, res);
|
|
925
|
-
}
|
|
926
|
-
}, ticks, context, finallyBody, [new Scope(scope, {})]);
|
|
927
|
-
}, ticks, context, a, [new Scope(scope)], inLoopOrSwitch);
|
|
928
|
-
},
|
|
929
|
-
'void': (exec, done, ticks, a) => { done(); },
|
|
930
|
-
'new': (exec, done, ticks, a, b, obj, context) => {
|
|
931
|
-
if (!context.ctx.globalsWhitelist.has(a) && !sandboxedFunctions.has(a)) {
|
|
932
|
-
throw new SandboxError(`Object construction not allowed: ${a.constructor.name}`);
|
|
933
|
-
}
|
|
934
|
-
done(undefined, new a(...b));
|
|
935
|
-
},
|
|
936
|
-
'throw': (exec, done, ticks, a, b) => { done(b); },
|
|
937
|
-
'multi': (exec, done, ticks, a) => done(undefined, a.pop())
|
|
938
|
-
};
|
|
939
|
-
export let ops = new Map();
|
|
940
|
-
for (let op in ops2) {
|
|
941
|
-
ops.set(op, ops2[op]);
|
|
942
|
-
}
|
|
908
|
+
}, ticks, context, finallyBody, [new Scope(scope, {})]);
|
|
909
|
+
}, ticks, context, a, [new Scope(scope)], inLoopOrSwitch);
|
|
910
|
+
});
|
|
911
|
+
addOps(87 /* LispType.Void */, (exec, done, ticks, a) => { done(); });
|
|
912
|
+
addOps(45 /* LispType.New */, (exec, done, ticks, a, b, obj, context) => {
|
|
913
|
+
if (!context.ctx.globalsWhitelist.has(a) && !sandboxedFunctions.has(a)) {
|
|
914
|
+
throw new SandboxError(`Object construction not allowed: ${a.constructor.name}`);
|
|
915
|
+
}
|
|
916
|
+
done(undefined, new a(...b));
|
|
917
|
+
});
|
|
918
|
+
addOps(46 /* LispType.Throw */, (exec, done, ticks, a, b) => { done(b); });
|
|
919
|
+
addOps(43 /* LispType.Expression */, (exec, done, ticks, a) => done(undefined, a.pop()));
|
|
920
|
+
addOps(0 /* LispType.None */, (exec, done, ticks, a) => done());
|
|
943
921
|
function valueOrProp(a, context) {
|
|
944
922
|
if (a instanceof Prop)
|
|
945
923
|
return a.get(context);
|
|
@@ -970,6 +948,10 @@ function _execManySync(ticks, tree, done, scope, context, inLoopOrSwitch) {
|
|
|
970
948
|
done(undefined, res);
|
|
971
949
|
return;
|
|
972
950
|
}
|
|
951
|
+
if (isLisp(tree[i]) && tree[i][0] === 8 /* LispType.Return */) {
|
|
952
|
+
done(undefined, new ExecReturn(context.ctx.auditReport, res, true));
|
|
953
|
+
return;
|
|
954
|
+
}
|
|
973
955
|
ret.push(res);
|
|
974
956
|
}
|
|
975
957
|
done(undefined, ret);
|
|
@@ -990,6 +972,10 @@ async function _execManyAsync(ticks, tree, done, scope, context, inLoopOrSwitch)
|
|
|
990
972
|
done(undefined, res);
|
|
991
973
|
return;
|
|
992
974
|
}
|
|
975
|
+
if (isLisp(tree[i]) && tree[i][0] === 8 /* LispType.Return */) {
|
|
976
|
+
done(undefined, new ExecReturn(context.ctx.auditReport, res, true));
|
|
977
|
+
return;
|
|
978
|
+
}
|
|
993
979
|
ret.push(res);
|
|
994
980
|
}
|
|
995
981
|
done(undefined, ret);
|
|
@@ -1036,11 +1022,12 @@ export async function execAsync(ticks, tree, scope, context, doneOriginal, inLoo
|
|
|
1036
1022
|
});
|
|
1037
1023
|
if (_execNoneRecurse(ticks, tree, scope, context, done, true, inLoopOrSwitch)) {
|
|
1038
1024
|
}
|
|
1039
|
-
else if (tree
|
|
1025
|
+
else if (isLisp(tree)) {
|
|
1026
|
+
let op = tree[0];
|
|
1040
1027
|
let obj;
|
|
1041
1028
|
try {
|
|
1042
1029
|
let ad;
|
|
1043
|
-
obj = (ad = asyncDone((d) => execAsync(ticks, tree
|
|
1030
|
+
obj = (ad = asyncDone((d) => execAsync(ticks, tree[1], scope, context, d, inLoopOrSwitch))).isInstant === true ? ad.instant : (await ad.p).result;
|
|
1044
1031
|
}
|
|
1045
1032
|
catch (e) {
|
|
1046
1033
|
done(e);
|
|
@@ -1054,16 +1041,15 @@ export async function execAsync(ticks, tree, scope, context, doneOriginal, inLoo
|
|
|
1054
1041
|
done(e);
|
|
1055
1042
|
return;
|
|
1056
1043
|
}
|
|
1057
|
-
|
|
1058
|
-
if (op === '?prop' || op === '?call') {
|
|
1044
|
+
if (op === 20 /* LispType.PropOptional */ || op === 21 /* LispType.CallOptional */) {
|
|
1059
1045
|
if (a === undefined || a === null) {
|
|
1060
1046
|
done(undefined, optional);
|
|
1061
1047
|
return;
|
|
1062
1048
|
}
|
|
1063
|
-
op = op.
|
|
1049
|
+
op = op === 20 /* LispType.PropOptional */ ? 1 /* LispType.Prop */ : 5 /* LispType.Call */;
|
|
1064
1050
|
}
|
|
1065
1051
|
if (a === optional) {
|
|
1066
|
-
if (op ===
|
|
1052
|
+
if (op === 1 /* LispType.Prop */ || op === 5 /* LispType.Call */) {
|
|
1067
1053
|
done(undefined, a);
|
|
1068
1054
|
return;
|
|
1069
1055
|
}
|
|
@@ -1074,7 +1060,7 @@ export async function execAsync(ticks, tree, scope, context, doneOriginal, inLoo
|
|
|
1074
1060
|
let bobj;
|
|
1075
1061
|
try {
|
|
1076
1062
|
let ad;
|
|
1077
|
-
bobj = (ad = asyncDone((d) => execAsync(ticks, tree
|
|
1063
|
+
bobj = (ad = asyncDone((d) => execAsync(ticks, tree[2], scope, context, d, inLoopOrSwitch))).isInstant === true ? ad.instant : (await ad.p).result;
|
|
1078
1064
|
}
|
|
1079
1065
|
catch (e) {
|
|
1080
1066
|
done(e);
|
|
@@ -1108,10 +1094,11 @@ export async function execAsync(ticks, tree, scope, context, doneOriginal, inLoo
|
|
|
1108
1094
|
export function execSync(ticks, tree, scope, context, done, inLoopOrSwitch) {
|
|
1109
1095
|
if (_execNoneRecurse(ticks, tree, scope, context, done, false, inLoopOrSwitch)) {
|
|
1110
1096
|
}
|
|
1111
|
-
else if (tree
|
|
1097
|
+
else if (isLisp(tree)) {
|
|
1098
|
+
let op = tree[0];
|
|
1112
1099
|
let obj;
|
|
1113
1100
|
try {
|
|
1114
|
-
obj = syncDone((d) => execSync(ticks, tree
|
|
1101
|
+
obj = syncDone((d) => execSync(ticks, tree[1], scope, context, d, inLoopOrSwitch)).result;
|
|
1115
1102
|
}
|
|
1116
1103
|
catch (e) {
|
|
1117
1104
|
done(e);
|
|
@@ -1125,16 +1112,15 @@ export function execSync(ticks, tree, scope, context, done, inLoopOrSwitch) {
|
|
|
1125
1112
|
done(e);
|
|
1126
1113
|
return;
|
|
1127
1114
|
}
|
|
1128
|
-
|
|
1129
|
-
if (op === '?prop' || op === '?call') {
|
|
1115
|
+
if (op === 20 /* LispType.PropOptional */ || op === 21 /* LispType.CallOptional */) {
|
|
1130
1116
|
if (a === undefined || a === null) {
|
|
1131
1117
|
done(undefined, optional);
|
|
1132
1118
|
return;
|
|
1133
1119
|
}
|
|
1134
|
-
op = op.
|
|
1120
|
+
op = op === 20 /* LispType.PropOptional */ ? 1 /* LispType.Prop */ : 5 /* LispType.Call */;
|
|
1135
1121
|
}
|
|
1136
1122
|
if (a === optional) {
|
|
1137
|
-
if (op ===
|
|
1123
|
+
if (op === 1 /* LispType.Prop */ || op === 5 /* LispType.Call */) {
|
|
1138
1124
|
done(undefined, a);
|
|
1139
1125
|
return;
|
|
1140
1126
|
}
|
|
@@ -1144,7 +1130,7 @@ export function execSync(ticks, tree, scope, context, done, inLoopOrSwitch) {
|
|
|
1144
1130
|
}
|
|
1145
1131
|
let bobj;
|
|
1146
1132
|
try {
|
|
1147
|
-
bobj = syncDone((d) => execSync(ticks, tree
|
|
1133
|
+
bobj = syncDone((d) => execSync(ticks, tree[2], scope, context, d, inLoopOrSwitch)).result;
|
|
1148
1134
|
}
|
|
1149
1135
|
catch (e) {
|
|
1150
1136
|
done(e);
|
|
@@ -1174,9 +1160,18 @@ export function execSync(ticks, tree, scope, context, done, inLoopOrSwitch) {
|
|
|
1174
1160
|
}
|
|
1175
1161
|
}
|
|
1176
1162
|
}
|
|
1177
|
-
const unexecTypes = new Set([
|
|
1163
|
+
const unexecTypes = new Set([
|
|
1164
|
+
11 /* LispType.ArrowFunction */,
|
|
1165
|
+
37 /* LispType.Function */,
|
|
1166
|
+
10 /* LispType.InlineFunction */,
|
|
1167
|
+
38 /* LispType.Loop */,
|
|
1168
|
+
39 /* LispType.Try */,
|
|
1169
|
+
40 /* LispType.Switch */,
|
|
1170
|
+
14 /* LispType.IfCase */,
|
|
1171
|
+
16 /* LispType.InlineIfCase */,
|
|
1172
|
+
60 /* LispType.Typeof */
|
|
1173
|
+
]);
|
|
1178
1174
|
function _execNoneRecurse(ticks, tree, scope, context, done, isAsync, inLoopOrSwitch) {
|
|
1179
|
-
var _a;
|
|
1180
1175
|
const exec = isAsync ? execAsync : execSync;
|
|
1181
1176
|
if (context.ctx.options.executionQuota <= ticks.ticks) {
|
|
1182
1177
|
if (typeof context.ctx.options.onExecutionQuotaReached === 'function' && context.ctx.options.onExecutionQuotaReached(ticks, scope, context, tree)) {
|
|
@@ -1199,18 +1194,26 @@ function _execNoneRecurse(ticks, tree, scope, context, done, isAsync, inLoopOrSw
|
|
|
1199
1194
|
else if (tree === optional) {
|
|
1200
1195
|
done();
|
|
1201
1196
|
}
|
|
1202
|
-
else if (Array.isArray(tree) && tree
|
|
1203
|
-
|
|
1197
|
+
else if (Array.isArray(tree) && !isLisp(tree)) {
|
|
1198
|
+
if (tree[0] === 0 /* LispType.None */) {
|
|
1199
|
+
done();
|
|
1200
|
+
}
|
|
1201
|
+
else {
|
|
1202
|
+
execMany(ticks, exec, tree, done, scope, context, inLoopOrSwitch);
|
|
1203
|
+
}
|
|
1204
1204
|
}
|
|
1205
|
-
else if (!(tree
|
|
1205
|
+
else if (!isLisp(tree)) {
|
|
1206
1206
|
done(undefined, tree);
|
|
1207
1207
|
}
|
|
1208
|
-
else if (tree
|
|
1208
|
+
else if (tree[0] === 42 /* LispType.Block */) {
|
|
1209
|
+
execMany(ticks, exec, tree[1], done, scope, context, inLoopOrSwitch);
|
|
1210
|
+
}
|
|
1211
|
+
else if (tree[0] === 44 /* LispType.Await */) {
|
|
1209
1212
|
if (!isAsync) {
|
|
1210
1213
|
done(new SandboxError("Illegal use of 'await', must be inside async function"));
|
|
1211
1214
|
}
|
|
1212
|
-
else if (
|
|
1213
|
-
execAsync(ticks, tree
|
|
1215
|
+
else if (context.ctx.prototypeWhitelist?.has(Promise.prototype)) {
|
|
1216
|
+
execAsync(ticks, tree[1], scope, context, async (e, r) => {
|
|
1214
1217
|
if (e)
|
|
1215
1218
|
done(e);
|
|
1216
1219
|
else
|
|
@@ -1226,9 +1229,9 @@ function _execNoneRecurse(ticks, tree, scope, context, done, isAsync, inLoopOrSw
|
|
|
1226
1229
|
done(new SandboxError('Async/await is not permitted'));
|
|
1227
1230
|
}
|
|
1228
1231
|
}
|
|
1229
|
-
else if (unexecTypes.has(tree
|
|
1232
|
+
else if (unexecTypes.has(tree[0])) {
|
|
1230
1233
|
try {
|
|
1231
|
-
ops.get(tree
|
|
1234
|
+
ops.get(tree[0])(exec, done, ticks, tree[1], tree[2], tree, context, scope, undefined, inLoopOrSwitch);
|
|
1232
1235
|
}
|
|
1233
1236
|
catch (err) {
|
|
1234
1237
|
done(err);
|
|
@@ -1304,7 +1307,7 @@ function _executeWithDoneSync(done, ticks, context, executionTree, scope, inLoop
|
|
|
1304
1307
|
done(undefined, res);
|
|
1305
1308
|
return;
|
|
1306
1309
|
}
|
|
1307
|
-
if (current
|
|
1310
|
+
if (isLisp(current) && current[0] === 8 /* LispType.Return */) {
|
|
1308
1311
|
done(undefined, new ExecReturn(context.ctx.auditReport, res, true));
|
|
1309
1312
|
return;
|
|
1310
1313
|
}
|
|
@@ -1336,7 +1339,7 @@ async function _executeWithDoneAsync(done, ticks, context, executionTree, scope,
|
|
|
1336
1339
|
done(undefined, res);
|
|
1337
1340
|
return;
|
|
1338
1341
|
}
|
|
1339
|
-
if (current
|
|
1342
|
+
if (isLisp(current) && current[0] === 8 /* LispType.Return */) {
|
|
1340
1343
|
done(undefined, new ExecReturn(context.ctx.auditReport, res, true));
|
|
1341
1344
|
return;
|
|
1342
1345
|
}
|