ecma-evaluator 2.0.10 → 2.1.0

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.
@@ -35,6 +35,7 @@ var mutableMethods = [
35
35
  "Array.prototype.sort",
36
36
  "Array.prototype.fill",
37
37
  "Array.prototype.copyWithin",
38
+ "Object.create",
38
39
  "Object.defineProperty",
39
40
  "Object.defineProperties",
40
41
  "Object.preventExtensions",
@@ -338,6 +339,18 @@ var MAX_STRING_LENGTH = 100000;
338
339
  var MAX_DATA_NODES = 100000;
339
340
  var MAX_BIGINT_EXPONENT = 256n;
340
341
  var MAX_BIGINT_BITS = 65536;
342
+ var DEFAULT_MAX_DEPTH = 1000;
343
+ var MAX_CONFIGURABLE_DEPTH = 2000;
344
+ var MAX_REGEXP_SOURCE_LENGTH = 1000;
345
+ var MAX_REGEXP_FLAGS_LENGTH = 32;
346
+ var NON_SANDBOX_GLOBALS = new Set([
347
+ "WeakRef",
348
+ "FinalizationRegistry",
349
+ "Iterator",
350
+ "SharedArrayBuffer",
351
+ "escape",
352
+ "unescape"
353
+ ]);
341
354
  var TYPED_ARRAY_CONSTRUCTORS = new Set([
342
355
  Int8Array,
343
356
  Uint8Array,
@@ -346,6 +359,7 @@ var TYPED_ARRAY_CONSTRUCTORS = new Set([
346
359
  Uint16Array,
347
360
  Int32Array,
348
361
  Uint32Array,
362
+ "function" == typeof Float16Array ? Float16Array : null,
349
363
  Float32Array,
350
364
  Float64Array,
351
365
  "function" == typeof BigInt64Array ? BigInt64Array : null,
@@ -353,6 +367,39 @@ var TYPED_ARRAY_CONSTRUCTORS = new Set([
353
367
  ].filter(function(constructor) {
354
368
  return "function" == typeof constructor;
355
369
  }));
370
+ function isTypedArrayConstructor(value) {
371
+ return TYPED_ARRAY_CONSTRUCTORS.has(value) || "function" == typeof value && "number" == typeof value.BYTES_PER_ELEMENT;
372
+ }
373
+ var TYPED_ARRAY_MUTATORS = function() {
374
+ var map = new Map();
375
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
376
+ try {
377
+ for(var _iterator = TYPED_ARRAY_CONSTRUCTORS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
378
+ var constructor = _step.value;
379
+ for(var _i = 0, _iter = [
380
+ "set",
381
+ "fill",
382
+ "reverse",
383
+ "sort",
384
+ "copyWithin"
385
+ ]; _i < _iter.length; _i++){
386
+ var name = _iter[_i];
387
+ var method = constructor.prototype[name];
388
+ if ("function" == typeof method && !map.has(method)) map.set(method, name);
389
+ }
390
+ }
391
+ } catch (err) {
392
+ _didIteratorError = true;
393
+ _iteratorError = err;
394
+ } finally{
395
+ try {
396
+ if (!_iteratorNormalCompletion && null != _iterator.return) _iterator.return();
397
+ } finally{
398
+ if (_didIteratorError) throw _iteratorError;
399
+ }
400
+ }
401
+ return map;
402
+ }();
356
403
  var NO_OBJECT = Symbol("no-object");
357
404
  var renderErrorMessage = function(template) {
358
405
  var context = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {};
@@ -517,14 +564,20 @@ var BINARY_OPERATION_MAP = {
517
564
  function createGlobalScope() {
518
565
  var scope = Object.create(null);
519
566
  var builtin = globals.builtin;
520
- for(var key in builtin)if (!blockedGlobalBuiltIns.includes(key)) {
521
- var isWritable = builtin[key];
522
- Object.defineProperty(scope, key, {
523
- value: globalThis[key],
524
- writable: isWritable,
525
- enumerable: false,
526
- configurable: false
527
- });
567
+ for(var key in builtin){
568
+ if (!blockedGlobalBuiltIns.includes(key)) {
569
+ if (!NON_SANDBOX_GLOBALS.has(key)) {
570
+ if (Object.hasOwn(globalThis, key)) {
571
+ var isWritable = builtin[key];
572
+ Object.defineProperty(scope, key, {
573
+ value: globalThis[key],
574
+ writable: isWritable,
575
+ enumerable: false,
576
+ configurable: false
577
+ });
578
+ }
579
+ }
580
+ }
528
581
  }
529
582
  Object.defineProperty(scope, "globalThis", {
530
583
  value: scope,
@@ -534,6 +587,7 @@ function createGlobalScope() {
534
587
  });
535
588
  return scope;
536
589
  }
590
+ var GLOBAL_SCOPE = createGlobalScope();
537
591
  var getBlockedMethods = function() {
538
592
  var BLOCKED_METHODS = null;
539
593
  return function() {
@@ -588,11 +642,12 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
588
642
  _class_call_check(this, Evaluator);
589
643
  this.maxInputLength = validateLimit(null == options ? void 0 : options.maxInputLength, "maxInputLength", DEFAULT_MAX_INPUT_LENGTH, MAX_CONFIGURABLE_INPUT_LENGTH);
590
644
  this.maxEvaluationSteps = validateLimit(null == options ? void 0 : options.maxEvaluationSteps, "maxEvaluationSteps", DEFAULT_MAX_EVALUATION_STEPS, MAX_CONFIGURABLE_EVALUATION_STEPS);
645
+ this.maxDepth = validateLimit(null == options ? void 0 : options.maxDepth, "maxDepth", DEFAULT_MAX_DEPTH, MAX_CONFIGURABLE_DEPTH);
591
646
  assertBoundedData(variables, "Evaluation context");
592
647
  var clonedVariables = structuredClone(variables);
593
648
  this.scopes = [
594
649
  clonedVariables,
595
- createGlobalScope()
650
+ GLOBAL_SCOPE
596
651
  ].filter(function(scope) {
597
652
  return null != scope;
598
653
  });
@@ -600,6 +655,7 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
600
655
  this.remainingEvaluationSteps = 0;
601
656
  this.remainingDataSize = MAX_BUFFER_BYTES;
602
657
  this.remainingDataNodes = MAX_DATA_NODES;
658
+ this.evaluationDepth = 0;
603
659
  }
604
660
  _create_class(Evaluator, [
605
661
  {
@@ -613,9 +669,16 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
613
669
  this.remainingEvaluationSteps = this.maxEvaluationSteps;
614
670
  this.remainingDataSize = MAX_BUFFER_BYTES;
615
671
  this.remainingDataNodes = MAX_DATA_NODES;
616
- var ast = external_acorn_parse(expression, {
617
- ecmaVersion: "latest"
618
- });
672
+ this.evaluationDepth = 0;
673
+ var ast;
674
+ try {
675
+ ast = external_acorn_parse(expression, {
676
+ ecmaVersion: "latest"
677
+ });
678
+ } catch (error) {
679
+ if (_instanceof(error, RangeError) && /call stack/i.test(error.message)) throw new SyntaxError("Expression nesting is too deep to parse");
680
+ throw error;
681
+ }
619
682
  try {
620
683
  return this.execute(ast.body);
621
684
  } finally{
@@ -668,9 +731,24 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
668
731
  {
669
732
  key: "visit",
670
733
  value: function(node) {
671
- var _this = this;
672
734
  this.remainingEvaluationSteps--;
673
735
  if (this.remainingEvaluationSteps < 0) throw new RangeError("Evaluation step limit exceeded");
736
+ this.evaluationDepth++;
737
+ if (this.evaluationDepth > this.maxDepth) {
738
+ this.evaluationDepth--;
739
+ throw new RangeError("Maximum evaluation depth exceeded");
740
+ }
741
+ try {
742
+ return this.visitNode(node);
743
+ } finally{
744
+ this.evaluationDepth--;
745
+ }
746
+ }
747
+ },
748
+ {
749
+ key: "visitNode",
750
+ value: function(node) {
751
+ var _this = this;
674
752
  switch(node.type){
675
753
  case "ExpressionStatement":
676
754
  return this.visit(node.expression);
@@ -756,10 +834,18 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
756
834
  throw new SyntaxError("Unsupported operator: ".concat(node.operator));
757
835
  }
758
836
  },
837
+ {
838
+ key: "assertBoundedRegExp",
839
+ value: function(args) {
840
+ if ("string" == typeof args[0] && args[0].length > MAX_REGEXP_SOURCE_LENGTH) throw new RangeError("RegExp source exceeds the maximum allowed length");
841
+ if ("string" == typeof args[1] && args[1].length > MAX_REGEXP_FLAGS_LENGTH) throw new RangeError("RegExp flags exceed the maximum allowed length");
842
+ }
843
+ },
759
844
  {
760
845
  key: "assertBoundedConstruction",
761
846
  value: function(Constructor, args) {
762
847
  var _args_;
848
+ if (Constructor === RegExp) this.assertBoundedRegExp(args);
763
849
  var size = args[0];
764
850
  if (Constructor === Array && 1 === args.length && "number" == typeof size && size > MAX_ARRAY_LENGTH) throw new RangeError("Array length exceeds the maximum allowed length");
765
851
  if (Constructor === ArrayBuffer && (size > MAX_BUFFER_BYTES || (null == (_args_ = args[1]) ? void 0 : _args_.maxByteLength) > MAX_BUFFER_BYTES)) throw new RangeError("ArrayBuffer size exceeds the maximum allowed size");
@@ -769,7 +855,7 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
769
855
  var collectionSize = "string" == typeof size || Array.isArray(size) ? size.length : null != (_size_size = null == size ? void 0 : size.size) ? _size_size : null == size ? void 0 : size.length;
770
856
  if ("number" == typeof collectionSize && collectionSize > MAX_ARRAY_LENGTH) throw new RangeError("Collection source exceeds the maximum allowed size");
771
857
  }
772
- if (TYPED_ARRAY_CONSTRUCTORS.has(Constructor)) {
858
+ if (isTypedArrayConstructor(Constructor)) {
773
859
  var byteLength;
774
860
  if (_instanceof(size, ArrayBuffer)) {
775
861
  var _args_1;
@@ -864,7 +950,7 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
864
950
  if ("stack" === property && _instanceof(object, Error)) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
865
951
  "Accessing error stack"
866
952
  ]));
867
- if (null != object && object[property] === (null == object ? void 0 : object.__proto__)) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
953
+ if (null != object && void 0 !== object.__proto__ && object[property] === object.__proto__) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
868
954
  "Accessing prototype properties"
869
955
  ]));
870
956
  if (null == object) {
@@ -1006,6 +1092,9 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
1006
1092
  path
1007
1093
  ]));
1008
1094
  }
1095
+ if (TYPED_ARRAY_MUTATORS.has(func)) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
1096
+ "TypedArray.prototype.".concat(TYPED_ARRAY_MUTATORS.get(func))
1097
+ ]));
1009
1098
  var args = function() {
1010
1099
  if (0 === node.arguments.length) return [];
1011
1100
  var result = [];
@@ -1047,7 +1136,8 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
1047
1136
  if ("string" == typeof args[0] && "" !== args[0] && countLiteralMatches(target, args[0], true) >= MAX_ARRAY_LENGTH) throw new RangeError("Split result exceeds the maximum allowed length");
1048
1137
  }
1049
1138
  }
1050
- if ((target === Array || TYPED_ARRAY_CONSTRUCTORS.has(target)) && func === target.from) {
1139
+ if (func === RegExp) this.assertBoundedRegExp(args);
1140
+ if ((target === Array || isTypedArrayConstructor(target)) && func === target.from) {
1051
1141
  var source = args[0];
1052
1142
  var _source_size;
1053
1143
  var size = "string" == typeof source || Array.isArray(source) ? source.length : null != (_source_size = null == source ? void 0 : source.size) ? _source_size : null == source ? void 0 : source.length;
@@ -1097,7 +1187,7 @@ function getNodeString(node) {
1097
1187
  return node.raw;
1098
1188
  case "ArrayExpression":
1099
1189
  return "[".concat(node.elements.map(function(child) {
1100
- return getNodeString(child);
1190
+ return null === child ? "" : getNodeString(child);
1101
1191
  }).join(","), "]");
1102
1192
  case "ObjectExpression":
1103
1193
  if (0 === node.properties.length) return "{}";
@@ -1170,6 +1260,7 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
1170
1260
  var buffer = "";
1171
1261
  var exprStartPos = 0;
1172
1262
  var pos = 0;
1263
+ var prevExprChar = "";
1173
1264
  while(pos < length){
1174
1265
  var char = template[pos];
1175
1266
  var nextChar = template[pos + 1];
@@ -1187,6 +1278,7 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
1187
1278
  }
1188
1279
  state = "EXPR";
1189
1280
  exprStartPos = pos;
1281
+ prevExprChar = "";
1190
1282
  pos += this.startLen;
1191
1283
  continue;
1192
1284
  }
@@ -1196,6 +1288,7 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
1196
1288
  if ("'" === char) state = "STRING_SQ";
1197
1289
  else if ('"' === char) state = "STRING_DQ";
1198
1290
  else if ("`" === char) state = "TEMPLATE";
1291
+ else if ("/" === char && this._isRegexPosition(prevExprChar)) state = "REGEX";
1199
1292
  else if ("\\" === char) state = "'" === nextChar ? "ESCAPE_SQ" : '"' === nextChar ? "ESCAPE_DQ" : "`" === nextChar ? "ESCAPE_TEMPLATE" : "ESCAPE_EXPR";
1200
1293
  else if (this._isMatch(pos, template, this.exprEnd)) {
1201
1294
  var exprValue = this.preserveWhitespace ? buffer : buffer.trim();
@@ -1212,6 +1305,7 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
1212
1305
  pos += this.endLen;
1213
1306
  continue;
1214
1307
  }
1308
+ if (!RegExp("\\s", "u").test(char)) prevExprChar = char;
1215
1309
  buffer += char;
1216
1310
  break;
1217
1311
  case "STRING_SQ":
@@ -1229,6 +1323,17 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
1229
1323
  else if ("`" === char) state = "EXPR";
1230
1324
  buffer += char;
1231
1325
  break;
1326
+ case "REGEX":
1327
+ if ("\\" === char) state = "ESCAPE_REGEX";
1328
+ else if ("[" === char) state = "REGEX_CLASS";
1329
+ else if ("/" === char) state = "EXPR";
1330
+ buffer += char;
1331
+ break;
1332
+ case "REGEX_CLASS":
1333
+ if ("\\" === char) state = "ESCAPE_REGEX";
1334
+ else if ("]" === char) state = "REGEX";
1335
+ buffer += char;
1336
+ break;
1232
1337
  case "ESCAPE_SQ":
1233
1338
  buffer += char;
1234
1339
  state = "STRING_SQ";
@@ -1241,6 +1346,10 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
1241
1346
  buffer += char;
1242
1347
  state = "TEMPLATE";
1243
1348
  break;
1349
+ case "ESCAPE_REGEX":
1350
+ buffer += char;
1351
+ state = "REGEX";
1352
+ break;
1244
1353
  case "ESCAPE_EXPR":
1245
1354
  buffer += char;
1246
1355
  state = "EXPR";
@@ -1266,6 +1375,12 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
1266
1375
  return tokens;
1267
1376
  }
1268
1377
  },
1378
+ {
1379
+ key: "_isRegexPosition",
1380
+ value: function(prev) {
1381
+ return "" === prev || "(,=:[!&|?{};+-*%^~<>".includes(prev);
1382
+ }
1383
+ },
1269
1384
  {
1270
1385
  key: "_isMatch",
1271
1386
  value: function(pos, template, sequence) {