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.
- package/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/dist/cjs/Evaluator.d.cts +11 -1
- package/dist/cjs/index.cjs +132 -17
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/Evaluator.d.mts +11 -1
- package/dist/esm/index.mjs +132 -17
- package/dist/esm/index.mjs.map +1 -1
- package/package.json +6 -3
package/dist/esm/index.mjs
CHANGED
|
@@ -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)
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
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
|
-
|
|
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
|
-
|
|
617
|
-
|
|
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 (
|
|
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 &&
|
|
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 (
|
|
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) {
|