ecma-evaluator 2.0.9 → 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 +11 -495
- package/README.zh-CN.md +11 -494
- package/dist/cjs/Evaluator.d.cts +26 -3
- package/dist/cjs/TemplateParser.d.cts +12 -0
- package/dist/cjs/index.cjs +468 -40
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/Evaluator.d.mts +26 -3
- package/dist/esm/TemplateParser.d.mts +12 -0
- package/dist/esm/index.mjs +468 -40
- package/dist/esm/index.mjs.map +1 -1
- package/package.json +77 -67
package/dist/cjs/index.cjs
CHANGED
|
@@ -76,6 +76,7 @@ var mutableMethods = [
|
|
|
76
76
|
"Array.prototype.sort",
|
|
77
77
|
"Array.prototype.fill",
|
|
78
78
|
"Array.prototype.copyWithin",
|
|
79
|
+
"Object.create",
|
|
79
80
|
"Object.defineProperty",
|
|
80
81
|
"Object.defineProperties",
|
|
81
82
|
"Object.preventExtensions",
|
|
@@ -185,8 +186,6 @@ var mutableMethods = [
|
|
|
185
186
|
"DataView.prototype.setFloat64",
|
|
186
187
|
"DataView.prototype.setBigInt64",
|
|
187
188
|
"DataView.prototype.setBigUint64",
|
|
188
|
-
"Promise.prototype.catch",
|
|
189
|
-
"Promise.prototype.finally",
|
|
190
189
|
"Generator.prototype.next",
|
|
191
190
|
"Generator.prototype.return",
|
|
192
191
|
"Generator.prototype.throw",
|
|
@@ -221,7 +220,8 @@ var dangerousMethods = [
|
|
|
221
220
|
"Object.getOwnPropertyDescriptors",
|
|
222
221
|
"Object.getOwnPropertyNames",
|
|
223
222
|
"Object.getOwnPropertySymbols",
|
|
224
|
-
"
|
|
223
|
+
"Error.captureStackTrace",
|
|
224
|
+
"Error.prepareStackTrace"
|
|
225
225
|
];
|
|
226
226
|
mutableMethods.push("Object.prototype.__proto__");
|
|
227
227
|
var blockedMethods = _to_consumable_array(mutableMethods).concat(_to_consumable_array(dangerousMethods));
|
|
@@ -268,6 +268,10 @@ var blockedGlobalBuiltIns = [
|
|
|
268
268
|
"Reflect",
|
|
269
269
|
"Atomics",
|
|
270
270
|
"WebAssembly",
|
|
271
|
+
"SharedArrayBuffer",
|
|
272
|
+
"queueMicrotask",
|
|
273
|
+
"AbortSignal",
|
|
274
|
+
"Promise",
|
|
271
275
|
"console",
|
|
272
276
|
"Intl",
|
|
273
277
|
"Deno"
|
|
@@ -363,14 +367,173 @@ var ERROR_MESSAGES = {
|
|
|
363
367
|
IS_INVALID_SYNTAX: "{0} is not a valid syntax",
|
|
364
368
|
IS_NOT_FUNCTION: "{0} is not a function",
|
|
365
369
|
IS_NOT_DEFINED: "{0} is not defined",
|
|
366
|
-
IS_NOT_ALLOWED: "{0} is not allowed"
|
|
370
|
+
IS_NOT_ALLOWED: "{0} is not allowed",
|
|
371
|
+
EXPRESSION_TOO_LONG: "Expression exceeds the maximum length of {0} characters"
|
|
367
372
|
};
|
|
373
|
+
var DEFAULT_MAX_INPUT_LENGTH = 10000;
|
|
374
|
+
var MAX_CONFIGURABLE_INPUT_LENGTH = 100000;
|
|
375
|
+
var DEFAULT_MAX_EVALUATION_STEPS = 10000;
|
|
376
|
+
var MAX_CONFIGURABLE_EVALUATION_STEPS = 100000;
|
|
377
|
+
var MAX_ARRAY_LENGTH = 10000;
|
|
378
|
+
var MAX_BUFFER_BYTES = 1000000;
|
|
379
|
+
var MAX_STRING_LENGTH = 100000;
|
|
380
|
+
var MAX_DATA_NODES = 100000;
|
|
381
|
+
var MAX_BIGINT_EXPONENT = 256n;
|
|
382
|
+
var MAX_BIGINT_BITS = 65536;
|
|
383
|
+
var DEFAULT_MAX_DEPTH = 1000;
|
|
384
|
+
var MAX_CONFIGURABLE_DEPTH = 2000;
|
|
385
|
+
var MAX_REGEXP_SOURCE_LENGTH = 1000;
|
|
386
|
+
var MAX_REGEXP_FLAGS_LENGTH = 32;
|
|
387
|
+
var NON_SANDBOX_GLOBALS = new Set([
|
|
388
|
+
"WeakRef",
|
|
389
|
+
"FinalizationRegistry",
|
|
390
|
+
"Iterator",
|
|
391
|
+
"SharedArrayBuffer",
|
|
392
|
+
"escape",
|
|
393
|
+
"unescape"
|
|
394
|
+
]);
|
|
395
|
+
var TYPED_ARRAY_CONSTRUCTORS = new Set([
|
|
396
|
+
Int8Array,
|
|
397
|
+
Uint8Array,
|
|
398
|
+
Uint8ClampedArray,
|
|
399
|
+
Int16Array,
|
|
400
|
+
Uint16Array,
|
|
401
|
+
Int32Array,
|
|
402
|
+
Uint32Array,
|
|
403
|
+
"function" == typeof Float16Array ? Float16Array : null,
|
|
404
|
+
Float32Array,
|
|
405
|
+
Float64Array,
|
|
406
|
+
"function" == typeof BigInt64Array ? BigInt64Array : null,
|
|
407
|
+
"function" == typeof BigUint64Array ? BigUint64Array : null
|
|
408
|
+
].filter(function(constructor) {
|
|
409
|
+
return "function" == typeof constructor;
|
|
410
|
+
}));
|
|
411
|
+
function isTypedArrayConstructor(value) {
|
|
412
|
+
return TYPED_ARRAY_CONSTRUCTORS.has(value) || "function" == typeof value && "number" == typeof value.BYTES_PER_ELEMENT;
|
|
413
|
+
}
|
|
414
|
+
var TYPED_ARRAY_MUTATORS = function() {
|
|
415
|
+
var map = new Map();
|
|
416
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
|
|
417
|
+
try {
|
|
418
|
+
for(var _iterator = TYPED_ARRAY_CONSTRUCTORS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
419
|
+
var constructor = _step.value;
|
|
420
|
+
for(var _i = 0, _iter = [
|
|
421
|
+
"set",
|
|
422
|
+
"fill",
|
|
423
|
+
"reverse",
|
|
424
|
+
"sort",
|
|
425
|
+
"copyWithin"
|
|
426
|
+
]; _i < _iter.length; _i++){
|
|
427
|
+
var name = _iter[_i];
|
|
428
|
+
var method = constructor.prototype[name];
|
|
429
|
+
if ("function" == typeof method && !map.has(method)) map.set(method, name);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
} catch (err) {
|
|
433
|
+
_didIteratorError = true;
|
|
434
|
+
_iteratorError = err;
|
|
435
|
+
} finally{
|
|
436
|
+
try {
|
|
437
|
+
if (!_iteratorNormalCompletion && null != _iterator.return) _iterator.return();
|
|
438
|
+
} finally{
|
|
439
|
+
if (_didIteratorError) throw _iteratorError;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
return map;
|
|
443
|
+
}();
|
|
444
|
+
var NO_OBJECT = Symbol("no-object");
|
|
368
445
|
var renderErrorMessage = function(template) {
|
|
369
446
|
var context = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {};
|
|
370
447
|
return template.replace(/{(\w+)}/g, function(_, key) {
|
|
371
448
|
return String(context[key]);
|
|
372
449
|
});
|
|
373
450
|
};
|
|
451
|
+
function validateLimit(value, name, defaultValue, maximum) {
|
|
452
|
+
if (void 0 === value) return defaultValue;
|
|
453
|
+
if (!Number.isSafeInteger(value) || value < 1 || value > maximum) throw new RangeError("".concat(name, " must be an integer between 1 and ").concat(maximum));
|
|
454
|
+
return value;
|
|
455
|
+
}
|
|
456
|
+
function countLiteralMatches(value, search, all) {
|
|
457
|
+
if ("" === search) return all ? value.length + 1 : 1;
|
|
458
|
+
var count = 0;
|
|
459
|
+
var position = 0;
|
|
460
|
+
while(-1 !== (position = value.indexOf(search, position))){
|
|
461
|
+
count++;
|
|
462
|
+
if (!all) break;
|
|
463
|
+
position += search.length;
|
|
464
|
+
}
|
|
465
|
+
return count;
|
|
466
|
+
}
|
|
467
|
+
function assertBoundedData(value, label) {
|
|
468
|
+
var pending = [
|
|
469
|
+
value
|
|
470
|
+
];
|
|
471
|
+
var seen = new WeakSet();
|
|
472
|
+
var dataSize = 0;
|
|
473
|
+
var dataNodes = 0;
|
|
474
|
+
var enqueueProperties = function(object) {
|
|
475
|
+
var keys = Object.keys(object);
|
|
476
|
+
if (pending.length + keys.length > MAX_DATA_NODES) throw new RangeError("".concat(label, " exceeds the maximum data node count"));
|
|
477
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
|
|
478
|
+
try {
|
|
479
|
+
for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
480
|
+
var key = _step.value;
|
|
481
|
+
dataSize += key.length;
|
|
482
|
+
var descriptor = Object.getOwnPropertyDescriptor(object, key);
|
|
483
|
+
if (!descriptor || !Object.hasOwn(descriptor, "value")) throw new TypeError("".concat(label, " cannot contain accessor properties"));
|
|
484
|
+
pending.push(descriptor.value);
|
|
485
|
+
}
|
|
486
|
+
} catch (err) {
|
|
487
|
+
_didIteratorError = true;
|
|
488
|
+
_iteratorError = err;
|
|
489
|
+
} finally{
|
|
490
|
+
try {
|
|
491
|
+
if (!_iteratorNormalCompletion && null != _iterator.return) _iterator.return();
|
|
492
|
+
} finally{
|
|
493
|
+
if (_didIteratorError) throw _iteratorError;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
while(pending.length > 0){
|
|
498
|
+
var current = pending.pop();
|
|
499
|
+
dataNodes++;
|
|
500
|
+
if (dataNodes > MAX_DATA_NODES) throw new RangeError("".concat(label, " exceeds the maximum data node count"));
|
|
501
|
+
if ("string" == typeof current) {
|
|
502
|
+
if (current.length > MAX_STRING_LENGTH) throw new RangeError("".concat(label, " contains a string that exceeds the maximum length"));
|
|
503
|
+
dataSize += current.length + 8;
|
|
504
|
+
} else if (null === current || (void 0 === current ? "undefined" : _type_of(current)) !== "object" && "function" != typeof current) {
|
|
505
|
+
dataSize += 8;
|
|
506
|
+
continue;
|
|
507
|
+
} else {
|
|
508
|
+
if ("function" == typeof current || seen.has(current)) continue;
|
|
509
|
+
seen.add(current);
|
|
510
|
+
dataSize += 16;
|
|
511
|
+
if (_instanceof(current, ArrayBuffer) || ArrayBuffer.isView(current)) dataSize += current.byteLength;
|
|
512
|
+
else if (Array.isArray(current)) {
|
|
513
|
+
if (current.length > MAX_ARRAY_LENGTH) throw new RangeError("".concat(label, " contains an array that exceeds the maximum length"));
|
|
514
|
+
dataSize += 8 * current.length;
|
|
515
|
+
enqueueProperties(current);
|
|
516
|
+
} else if (_instanceof(current, Map)) {
|
|
517
|
+
if (current.size > MAX_ARRAY_LENGTH) throw new RangeError("".concat(label, " contains a map that exceeds the maximum size"));
|
|
518
|
+
dataSize += 16 * current.size;
|
|
519
|
+
Map.prototype.forEach.call(current, function(item, key) {
|
|
520
|
+
return pending.push(key, item);
|
|
521
|
+
});
|
|
522
|
+
} else if (_instanceof(current, Set)) {
|
|
523
|
+
if (current.size > MAX_ARRAY_LENGTH) throw new RangeError("".concat(label, " contains a set that exceeds the maximum size"));
|
|
524
|
+
dataSize += 8 * current.size;
|
|
525
|
+
Set.prototype.forEach.call(current, function(item) {
|
|
526
|
+
return pending.push(item);
|
|
527
|
+
});
|
|
528
|
+
} else enqueueProperties(current);
|
|
529
|
+
}
|
|
530
|
+
if (dataSize > MAX_BUFFER_BYTES) throw new RangeError("".concat(label, " exceeds the maximum data size"));
|
|
531
|
+
}
|
|
532
|
+
return {
|
|
533
|
+
dataSize: dataSize,
|
|
534
|
+
dataNodes: dataNodes
|
|
535
|
+
};
|
|
536
|
+
}
|
|
374
537
|
var BINARY_OPERATION_MAP = {
|
|
375
538
|
"+": function(a, b) {
|
|
376
539
|
return a + b;
|
|
@@ -442,14 +605,20 @@ var BINARY_OPERATION_MAP = {
|
|
|
442
605
|
function createGlobalScope() {
|
|
443
606
|
var scope = Object.create(null);
|
|
444
607
|
var builtin = external_globals_namespaceObject.builtin;
|
|
445
|
-
for(var key in builtin)
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
608
|
+
for(var key in builtin){
|
|
609
|
+
if (!blockedGlobalBuiltIns.includes(key)) {
|
|
610
|
+
if (!NON_SANDBOX_GLOBALS.has(key)) {
|
|
611
|
+
if (Object.hasOwn(globalThis, key)) {
|
|
612
|
+
var isWritable = builtin[key];
|
|
613
|
+
Object.defineProperty(scope, key, {
|
|
614
|
+
value: globalThis[key],
|
|
615
|
+
writable: isWritable,
|
|
616
|
+
enumerable: false,
|
|
617
|
+
configurable: false
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
453
622
|
}
|
|
454
623
|
Object.defineProperty(scope, "globalThis", {
|
|
455
624
|
value: scope,
|
|
@@ -459,6 +628,7 @@ function createGlobalScope() {
|
|
|
459
628
|
});
|
|
460
629
|
return scope;
|
|
461
630
|
}
|
|
631
|
+
var GLOBAL_SCOPE = createGlobalScope();
|
|
462
632
|
var getBlockedMethods = function() {
|
|
463
633
|
var BLOCKED_METHODS = null;
|
|
464
634
|
return function() {
|
|
@@ -509,24 +679,47 @@ var getBlockedMethods = function() {
|
|
|
509
679
|
var Evaluator_Evaluator = /*#__PURE__*/ function() {
|
|
510
680
|
"use strict";
|
|
511
681
|
function Evaluator() {
|
|
512
|
-
var variables = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : Object.create(null);
|
|
682
|
+
var variables = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : Object.create(null), options = arguments.length > 1 ? arguments[1] : void 0;
|
|
513
683
|
_class_call_check(this, Evaluator);
|
|
684
|
+
this.maxInputLength = validateLimit(null == options ? void 0 : options.maxInputLength, "maxInputLength", DEFAULT_MAX_INPUT_LENGTH, MAX_CONFIGURABLE_INPUT_LENGTH);
|
|
685
|
+
this.maxEvaluationSteps = validateLimit(null == options ? void 0 : options.maxEvaluationSteps, "maxEvaluationSteps", DEFAULT_MAX_EVALUATION_STEPS, MAX_CONFIGURABLE_EVALUATION_STEPS);
|
|
686
|
+
this.maxDepth = validateLimit(null == options ? void 0 : options.maxDepth, "maxDepth", DEFAULT_MAX_DEPTH, MAX_CONFIGURABLE_DEPTH);
|
|
687
|
+
assertBoundedData(variables, "Evaluation context");
|
|
688
|
+
var clonedVariables = structuredClone(variables);
|
|
514
689
|
this.scopes = [
|
|
515
|
-
|
|
516
|
-
|
|
690
|
+
clonedVariables,
|
|
691
|
+
GLOBAL_SCOPE
|
|
517
692
|
].filter(function(scope) {
|
|
518
693
|
return null != scope;
|
|
519
694
|
});
|
|
520
695
|
this.source = void 0;
|
|
696
|
+
this.remainingEvaluationSteps = 0;
|
|
697
|
+
this.remainingDataSize = MAX_BUFFER_BYTES;
|
|
698
|
+
this.remainingDataNodes = MAX_DATA_NODES;
|
|
699
|
+
this.evaluationDepth = 0;
|
|
521
700
|
}
|
|
522
701
|
_create_class(Evaluator, [
|
|
523
702
|
{
|
|
524
703
|
key: "evaluate",
|
|
525
704
|
value: function(expression) {
|
|
705
|
+
if ("string" != typeof expression) throw new TypeError("Expression must be a string");
|
|
706
|
+
if (expression.length > this.maxInputLength) throw new SyntaxError(renderErrorMessage(ERROR_MESSAGES.EXPRESSION_TOO_LONG, [
|
|
707
|
+
this.maxInputLength
|
|
708
|
+
]));
|
|
526
709
|
this.source = expression;
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
710
|
+
this.remainingEvaluationSteps = this.maxEvaluationSteps;
|
|
711
|
+
this.remainingDataSize = MAX_BUFFER_BYTES;
|
|
712
|
+
this.remainingDataNodes = MAX_DATA_NODES;
|
|
713
|
+
this.evaluationDepth = 0;
|
|
714
|
+
var ast;
|
|
715
|
+
try {
|
|
716
|
+
ast = external_acorn_namespaceObject.parse(expression, {
|
|
717
|
+
ecmaVersion: "latest"
|
|
718
|
+
});
|
|
719
|
+
} catch (error) {
|
|
720
|
+
if (_instanceof(error, RangeError) && /call stack/i.test(error.message)) throw new SyntaxError("Expression nesting is too deep to parse");
|
|
721
|
+
throw error;
|
|
722
|
+
}
|
|
530
723
|
try {
|
|
531
724
|
return this.execute(ast.body);
|
|
532
725
|
} finally{
|
|
@@ -537,6 +730,11 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
|
|
|
537
730
|
{
|
|
538
731
|
key: "execute",
|
|
539
732
|
value: function(body) {
|
|
733
|
+
if (0 === this.remainingEvaluationSteps) {
|
|
734
|
+
this.remainingEvaluationSteps = this.maxEvaluationSteps;
|
|
735
|
+
this.remainingDataSize = MAX_BUFFER_BYTES;
|
|
736
|
+
this.remainingDataNodes = MAX_DATA_NODES;
|
|
737
|
+
}
|
|
540
738
|
var result;
|
|
541
739
|
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
|
|
542
740
|
try {
|
|
@@ -557,11 +755,39 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
|
|
|
557
755
|
if ("function" == typeof result) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
|
|
558
756
|
"Returning functions from expressions"
|
|
559
757
|
]));
|
|
560
|
-
|
|
758
|
+
assertBoundedData(result, "Evaluation result");
|
|
759
|
+
if (_instanceof(result, Promise)) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
|
|
760
|
+
"Returning promises from expressions"
|
|
761
|
+
]));
|
|
762
|
+
try {
|
|
763
|
+
return structuredClone(result);
|
|
764
|
+
} catch (error) {
|
|
765
|
+
if (error && "DataCloneError" === error.name) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
|
|
766
|
+
"Returning non-cloneable values from expressions"
|
|
767
|
+
]));
|
|
768
|
+
throw error;
|
|
769
|
+
}
|
|
561
770
|
}
|
|
562
771
|
},
|
|
563
772
|
{
|
|
564
773
|
key: "visit",
|
|
774
|
+
value: function(node) {
|
|
775
|
+
this.remainingEvaluationSteps--;
|
|
776
|
+
if (this.remainingEvaluationSteps < 0) throw new RangeError("Evaluation step limit exceeded");
|
|
777
|
+
this.evaluationDepth++;
|
|
778
|
+
if (this.evaluationDepth > this.maxDepth) {
|
|
779
|
+
this.evaluationDepth--;
|
|
780
|
+
throw new RangeError("Maximum evaluation depth exceeded");
|
|
781
|
+
}
|
|
782
|
+
try {
|
|
783
|
+
return this.visitNode(node);
|
|
784
|
+
} finally{
|
|
785
|
+
this.evaluationDepth--;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
},
|
|
789
|
+
{
|
|
790
|
+
key: "visitNode",
|
|
565
791
|
value: function(node) {
|
|
566
792
|
var _this = this;
|
|
567
793
|
switch(node.type){
|
|
@@ -600,10 +826,14 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
|
|
|
600
826
|
if ("Function" === node.callee.name) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
|
|
601
827
|
"new Function() constructor"
|
|
602
828
|
]));
|
|
829
|
+
if ("Promise" === node.callee.name) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
|
|
830
|
+
"Promise constructor"
|
|
831
|
+
]));
|
|
603
832
|
var Constructor = this.visit(node.callee);
|
|
604
833
|
var args = node.arguments.length ? node.arguments.map(function(arg) {
|
|
605
834
|
return _this.visit(arg);
|
|
606
835
|
}) : [];
|
|
836
|
+
this.assertBoundedConstruction(Constructor, args);
|
|
607
837
|
return _construct(Constructor, Evaluator_to_consumable_array(args));
|
|
608
838
|
case "ChainExpression":
|
|
609
839
|
return this.visit(node.expression);
|
|
@@ -632,10 +862,57 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
|
|
|
632
862
|
var op = node.operator;
|
|
633
863
|
var left = this.visit(node.left);
|
|
634
864
|
var right = this.visit(node.right);
|
|
865
|
+
if ("+" === op && ("string" == typeof left || "string" == typeof right)) {
|
|
866
|
+
if (String(left).length + String(right).length > MAX_STRING_LENGTH) throw new RangeError("String result exceeds the maximum allowed length");
|
|
867
|
+
}
|
|
868
|
+
if ((void 0 === left ? "undefined" : _type_of(left)) === "bigint" && (void 0 === right ? "undefined" : _type_of(right)) === "bigint") {
|
|
869
|
+
if ("**" === op && (right > MAX_BIGINT_EXPONENT || right < 0n)) throw new RangeError("BigInt exponent must be between 0 and ".concat(MAX_BIGINT_EXPONENT));
|
|
870
|
+
var leftBits = left.toString(2).length;
|
|
871
|
+
var rightBits = right.toString(2).length;
|
|
872
|
+
if ("**" === op && leftBits * Number(right) > MAX_BIGINT_BITS || "<<" === op && right > BigInt(MAX_BIGINT_BITS) || "<<" === op && right >= 0n && leftBits + Number(right) > MAX_BIGINT_BITS || "*" === op && leftBits + rightBits > MAX_BIGINT_BITS || ("+" === op || "-" === op) && Math.max(leftBits, rightBits) + 1 > MAX_BIGINT_BITS) throw new RangeError("BigInt result exceeds the maximum allowed size");
|
|
873
|
+
}
|
|
635
874
|
if (BINARY_OPERATION_MAP.hasOwnProperty(op)) return BINARY_OPERATION_MAP[op](left, right);
|
|
636
875
|
throw new SyntaxError("Unsupported operator: ".concat(node.operator));
|
|
637
876
|
}
|
|
638
877
|
},
|
|
878
|
+
{
|
|
879
|
+
key: "assertBoundedRegExp",
|
|
880
|
+
value: function(args) {
|
|
881
|
+
if ("string" == typeof args[0] && args[0].length > MAX_REGEXP_SOURCE_LENGTH) throw new RangeError("RegExp source exceeds the maximum allowed length");
|
|
882
|
+
if ("string" == typeof args[1] && args[1].length > MAX_REGEXP_FLAGS_LENGTH) throw new RangeError("RegExp flags exceed the maximum allowed length");
|
|
883
|
+
}
|
|
884
|
+
},
|
|
885
|
+
{
|
|
886
|
+
key: "assertBoundedConstruction",
|
|
887
|
+
value: function(Constructor, args) {
|
|
888
|
+
var _args_;
|
|
889
|
+
if (Constructor === RegExp) this.assertBoundedRegExp(args);
|
|
890
|
+
var size = args[0];
|
|
891
|
+
if (Constructor === Array && 1 === args.length && "number" == typeof size && size > MAX_ARRAY_LENGTH) throw new RangeError("Array length exceeds the maximum allowed length");
|
|
892
|
+
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");
|
|
893
|
+
if (Constructor === DataView && _instanceof(size, ArrayBuffer) && size.byteLength > MAX_BUFFER_BYTES) throw new RangeError("DataView size exceeds the maximum allowed size");
|
|
894
|
+
if (Constructor === Map || Constructor === Set) {
|
|
895
|
+
var _size_size;
|
|
896
|
+
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;
|
|
897
|
+
if ("number" == typeof collectionSize && collectionSize > MAX_ARRAY_LENGTH) throw new RangeError("Collection source exceeds the maximum allowed size");
|
|
898
|
+
}
|
|
899
|
+
if (isTypedArrayConstructor(Constructor)) {
|
|
900
|
+
var byteLength;
|
|
901
|
+
if (_instanceof(size, ArrayBuffer)) {
|
|
902
|
+
var _args_1;
|
|
903
|
+
var offset = null != (_args_1 = args[1]) ? _args_1 : 0;
|
|
904
|
+
var _args_2;
|
|
905
|
+
var elementCount = null != (_args_2 = args[2]) ? _args_2 : Math.floor((size.byteLength - offset) / Constructor.BYTES_PER_ELEMENT);
|
|
906
|
+
byteLength = elementCount * Constructor.BYTES_PER_ELEMENT;
|
|
907
|
+
} else {
|
|
908
|
+
var _size_length;
|
|
909
|
+
var elementCount1 = "number" == typeof size ? size : null != (_size_length = null == size ? void 0 : size.length) ? _size_length : 0;
|
|
910
|
+
byteLength = elementCount1 * Constructor.BYTES_PER_ELEMENT;
|
|
911
|
+
}
|
|
912
|
+
if (byteLength > MAX_BUFFER_BYTES) throw new RangeError("Typed array size exceeds the maximum allowed size");
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
},
|
|
639
916
|
{
|
|
640
917
|
key: "handleLogicalExpression",
|
|
641
918
|
value: function(node) {
|
|
@@ -707,10 +984,14 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
|
|
|
707
984
|
{
|
|
708
985
|
key: "handleMemberExpression",
|
|
709
986
|
value: function(node) {
|
|
710
|
-
var
|
|
987
|
+
var objectValue = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : NO_OBJECT;
|
|
988
|
+
var object = objectValue === NO_OBJECT ? this.visit(node.object) : objectValue;
|
|
711
989
|
var isStaticProperty = "Identifier" === node.property.type && !node.computed;
|
|
712
990
|
var property = isStaticProperty ? node.property.name : this.visit(node.property);
|
|
713
|
-
if (
|
|
991
|
+
if ("stack" === property && _instanceof(object, Error)) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
|
|
992
|
+
"Accessing error stack"
|
|
993
|
+
]));
|
|
994
|
+
if (null != object && void 0 !== object.__proto__ && object[property] === object.__proto__) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
|
|
714
995
|
"Accessing prototype properties"
|
|
715
996
|
]));
|
|
716
997
|
if (null == object) {
|
|
@@ -733,30 +1014,52 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
|
|
|
733
1014
|
var result = [];
|
|
734
1015
|
for(var i = 0; i < node.elements.length; i++){
|
|
735
1016
|
var element = node.elements.at(i);
|
|
1017
|
+
if (null === element) {
|
|
1018
|
+
result.length++;
|
|
1019
|
+
continue;
|
|
1020
|
+
}
|
|
736
1021
|
var value = this.visit(element);
|
|
737
1022
|
if ("SpreadElement" === element.type) {
|
|
738
1023
|
var _result;
|
|
1024
|
+
this.assertBoundedSpread(result.length, value);
|
|
739
1025
|
(_result = result).push.apply(_result, Evaluator_to_consumable_array(value));
|
|
740
1026
|
} else result.push(value);
|
|
741
1027
|
}
|
|
742
1028
|
return result;
|
|
743
1029
|
}
|
|
744
1030
|
},
|
|
1031
|
+
{
|
|
1032
|
+
key: "assertBoundedSpread",
|
|
1033
|
+
value: function(currentLength, value) {
|
|
1034
|
+
var size = "string" == typeof value || Array.isArray(value) ? value.length : null == value ? void 0 : value.size;
|
|
1035
|
+
if ("number" == typeof size && currentLength + size > MAX_ARRAY_LENGTH) throw new RangeError("Spread value exceeds the maximum allowed length");
|
|
1036
|
+
}
|
|
1037
|
+
},
|
|
745
1038
|
{
|
|
746
1039
|
key: "handleObjectExpression",
|
|
747
1040
|
value: function(node) {
|
|
748
1041
|
var obj = {};
|
|
1042
|
+
var spreadPropertyCount = 0;
|
|
749
1043
|
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
|
|
750
1044
|
try {
|
|
751
1045
|
for(var _iterator = node.properties[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
752
1046
|
var prop = _step.value;
|
|
753
1047
|
if ("SpreadElement" === prop.type) {
|
|
754
|
-
|
|
1048
|
+
var spreadValue = this.visit(prop.argument);
|
|
1049
|
+
spreadPropertyCount += Object.keys(spreadValue).length;
|
|
1050
|
+
if (spreadPropertyCount > MAX_ARRAY_LENGTH) throw new RangeError("Object spread exceeds the maximum allowed property count");
|
|
1051
|
+
Object.assign(obj, spreadValue);
|
|
755
1052
|
continue;
|
|
756
1053
|
}
|
|
757
|
-
var key = prop.key.name || prop.key.value;
|
|
1054
|
+
var key = prop.computed ? this.visit(prop.key) : prop.key.name || prop.key.value;
|
|
758
1055
|
var value = this.visit(prop.value);
|
|
759
|
-
obj
|
|
1056
|
+
if (prop.computed) Object.defineProperty(obj, key, {
|
|
1057
|
+
value: value,
|
|
1058
|
+
writable: true,
|
|
1059
|
+
enumerable: true,
|
|
1060
|
+
configurable: true
|
|
1061
|
+
});
|
|
1062
|
+
else obj[key] = value;
|
|
760
1063
|
}
|
|
761
1064
|
} catch (err) {
|
|
762
1065
|
_didIteratorError = true;
|
|
@@ -787,28 +1090,52 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
|
|
|
787
1090
|
var paramCount = node.params.length;
|
|
788
1091
|
for(var i = 0; i < paramCount; i++)newScope[node.params[i].name] = args[i];
|
|
789
1092
|
_this.scopes.unshift(newScope);
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
1093
|
+
try {
|
|
1094
|
+
var result = _this.visit(node.body);
|
|
1095
|
+
_this.consumeEvaluationValue(result);
|
|
1096
|
+
return result;
|
|
1097
|
+
} finally{
|
|
1098
|
+
_this.scopes.shift();
|
|
1099
|
+
}
|
|
793
1100
|
};
|
|
794
1101
|
}
|
|
795
1102
|
},
|
|
1103
|
+
{
|
|
1104
|
+
key: "consumeEvaluationValue",
|
|
1105
|
+
value: function(value) {
|
|
1106
|
+
var _assertBoundedData = assertBoundedData(value, "Intermediate evaluation result"), dataSize = _assertBoundedData.dataSize, dataNodes = _assertBoundedData.dataNodes;
|
|
1107
|
+
this.remainingDataSize -= dataSize;
|
|
1108
|
+
this.remainingDataNodes -= dataNodes;
|
|
1109
|
+
if (this.remainingDataSize < 0 || this.remainingDataNodes < 0) throw new RangeError("Evaluation allocation budget exceeded");
|
|
1110
|
+
}
|
|
1111
|
+
},
|
|
796
1112
|
{
|
|
797
1113
|
key: "handleCallExpression",
|
|
798
1114
|
value: function(node) {
|
|
799
1115
|
var _this = this;
|
|
800
|
-
var
|
|
801
|
-
var
|
|
1116
|
+
var isOptional = node.optional || "MemberExpression" === node.callee.type && node.callee.optional;
|
|
1117
|
+
var func;
|
|
1118
|
+
var target = null;
|
|
1119
|
+
if ("MemberExpression" === node.callee.type) {
|
|
1120
|
+
target = this.visit(node.callee.object);
|
|
1121
|
+
func = this.handleMemberExpression(node.callee, target);
|
|
1122
|
+
} else func = this.visit(node.callee);
|
|
802
1123
|
if (null == func && isOptional) return;
|
|
803
1124
|
if (func === Function) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
|
|
804
1125
|
"Function constructor"
|
|
805
1126
|
]));
|
|
1127
|
+
if (func === Error.prepareStackTrace) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
|
|
1128
|
+
"Error.prepareStackTrace"
|
|
1129
|
+
]));
|
|
806
1130
|
if (getBlockedMethods().has(func)) {
|
|
807
1131
|
var path = getBlockedMethods().get(func);
|
|
808
1132
|
throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
|
|
809
1133
|
path
|
|
810
1134
|
]));
|
|
811
1135
|
}
|
|
1136
|
+
if (TYPED_ARRAY_MUTATORS.has(func)) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
|
|
1137
|
+
"TypedArray.prototype.".concat(TYPED_ARRAY_MUTATORS.get(func))
|
|
1138
|
+
]));
|
|
812
1139
|
var args = function() {
|
|
813
1140
|
if (0 === node.arguments.length) return [];
|
|
814
1141
|
var result = [];
|
|
@@ -817,24 +1144,57 @@ var Evaluator_Evaluator = /*#__PURE__*/ function() {
|
|
|
817
1144
|
var value = _this.visit(element);
|
|
818
1145
|
if ("SpreadElement" === element.type) {
|
|
819
1146
|
var _result;
|
|
1147
|
+
_this.assertBoundedSpread(result.length, value);
|
|
820
1148
|
(_result = result).push.apply(_result, Evaluator_to_consumable_array(value));
|
|
821
1149
|
} else result.push(value);
|
|
822
1150
|
}
|
|
823
1151
|
return result;
|
|
824
1152
|
}();
|
|
825
|
-
var target = "MemberExpression" === node.callee.type ? this.visit(node.callee.object) : null;
|
|
826
1153
|
if (args.some(function(arg) {
|
|
827
1154
|
return arg === Function;
|
|
828
1155
|
})) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
|
|
829
1156
|
"Function constructor"
|
|
830
1157
|
]));
|
|
1158
|
+
if ("string" == typeof target) {
|
|
1159
|
+
if (String.prototype.repeat && func === String.prototype.repeat && target.length * Number(args[0]) > MAX_STRING_LENGTH) throw new RangeError("String result exceeds the maximum allowed length");
|
|
1160
|
+
if ((String.prototype.padStart && func === String.prototype.padStart || func === String.prototype.padEnd) && Number(args[0]) > MAX_STRING_LENGTH) throw new RangeError("String result exceeds the maximum allowed length");
|
|
1161
|
+
if (String.prototype.concat && func === String.prototype.concat) {
|
|
1162
|
+
var resultLength = target.length + args.reduce(function(length, value) {
|
|
1163
|
+
return length + String(value).length;
|
|
1164
|
+
}, 0);
|
|
1165
|
+
if (resultLength > MAX_STRING_LENGTH) throw new RangeError("String result exceeds the maximum allowed length");
|
|
1166
|
+
}
|
|
1167
|
+
if (String.prototype.replace && func === String.prototype.replace || String.prototype.replaceAll && func === String.prototype.replaceAll) {
|
|
1168
|
+
if ("string" == typeof args[0]) {
|
|
1169
|
+
if ("function" == typeof args[1] || "string" == typeof args[1] && RegExp("\\$(?:[$&'`])", "u").test(args[1])) throw new Error("Only literal string replacements are allowed");
|
|
1170
|
+
if (target.length * Math.max(1, args[0].length) > 10000000) throw new RangeError("String operation exceeds the maximum work limit");
|
|
1171
|
+
var matchCount = countLiteralMatches(target, args[0], func === String.prototype.replaceAll);
|
|
1172
|
+
if (target.length + matchCount * String(args[1]).length > MAX_STRING_LENGTH) throw new RangeError("String result exceeds the maximum allowed length");
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
if (func === String.prototype.split) {
|
|
1176
|
+
if ("" === args[0] && target.length > MAX_ARRAY_LENGTH) throw new RangeError("Split result exceeds the maximum allowed length");
|
|
1177
|
+
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");
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
if (func === RegExp) this.assertBoundedRegExp(args);
|
|
1181
|
+
if ((target === Array || isTypedArrayConstructor(target)) && func === target.from) {
|
|
1182
|
+
var source = args[0];
|
|
1183
|
+
var _source_size;
|
|
1184
|
+
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;
|
|
1185
|
+
if ("number" == typeof size && size > MAX_ARRAY_LENGTH) throw new RangeError("Array.from source exceeds the maximum allowed length");
|
|
1186
|
+
}
|
|
831
1187
|
if ("function" != typeof func) {
|
|
832
1188
|
var calledString = getNodeString(node.callee);
|
|
833
1189
|
throw new TypeError(renderErrorMessage(ERROR_MESSAGES.IS_NOT_FUNCTION, [
|
|
834
1190
|
calledString
|
|
835
1191
|
]));
|
|
836
1192
|
}
|
|
837
|
-
|
|
1193
|
+
var result = func.apply(target, args);
|
|
1194
|
+
if (_instanceof(result, Promise)) throw new Error(renderErrorMessage(ERROR_MESSAGES.IS_NOT_ALLOWED, [
|
|
1195
|
+
"Returning promises from expressions"
|
|
1196
|
+
]));
|
|
1197
|
+
return result;
|
|
838
1198
|
}
|
|
839
1199
|
},
|
|
840
1200
|
{
|
|
@@ -868,7 +1228,7 @@ function getNodeString(node) {
|
|
|
868
1228
|
return node.raw;
|
|
869
1229
|
case "ArrayExpression":
|
|
870
1230
|
return "[".concat(node.elements.map(function(child) {
|
|
871
|
-
return getNodeString(child);
|
|
1231
|
+
return null === child ? "" : getNodeString(child);
|
|
872
1232
|
}).join(","), "]");
|
|
873
1233
|
case "ObjectExpression":
|
|
874
1234
|
if (0 === node.properties.length) return "{}";
|
|
@@ -899,11 +1259,25 @@ function TemplateParser_create_class(Constructor, protoProps, staticProps) {
|
|
|
899
1259
|
if (staticProps) TemplateParser_defineProperties(Constructor, staticProps);
|
|
900
1260
|
return Constructor;
|
|
901
1261
|
}
|
|
1262
|
+
var DEFAULT_MAX_TEMPLATE_LENGTH = 100000;
|
|
1263
|
+
var MAX_CONFIGURABLE_TEMPLATE_LENGTH = 1000000;
|
|
1264
|
+
var DEFAULT_MAX_TOKENS = 1000;
|
|
1265
|
+
var MAX_CONFIGURABLE_TOKENS = 10000;
|
|
1266
|
+
function TemplateParser_validateLimit(value, name, defaultValue, maximum) {
|
|
1267
|
+
if (void 0 === value) return defaultValue;
|
|
1268
|
+
if (!Number.isSafeInteger(value) || value < 1 || value > maximum) throw new RangeError("".concat(name, " must be an integer between 1 and ").concat(maximum));
|
|
1269
|
+
return value;
|
|
1270
|
+
}
|
|
902
1271
|
var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
|
|
903
1272
|
"use strict";
|
|
904
1273
|
function TemplateParser() {
|
|
905
1274
|
var options = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
|
|
906
1275
|
TemplateParser_class_call_check(this, TemplateParser);
|
|
1276
|
+
null != options || (options = {});
|
|
1277
|
+
this.maxTemplateLength = TemplateParser_validateLimit(options.maxTemplateLength, "maxTemplateLength", DEFAULT_MAX_TEMPLATE_LENGTH, MAX_CONFIGURABLE_TEMPLATE_LENGTH);
|
|
1278
|
+
this.maxTokens = TemplateParser_validateLimit(options.maxTokens, "maxTokens", DEFAULT_MAX_TOKENS, MAX_CONFIGURABLE_TOKENS);
|
|
1279
|
+
if (void 0 !== options.expressionStart && ("string" != typeof options.expressionStart || 0 === options.expressionStart.length || options.expressionStart.length > 128)) throw new TypeError("expressionStart must be a non-empty string of at most 128 characters");
|
|
1280
|
+
if (void 0 !== options.expressionEnd && ("string" != typeof options.expressionEnd || 0 === options.expressionEnd.length || options.expressionEnd.length > 128)) throw new TypeError("expressionEnd must be a non-empty string of at most 128 characters");
|
|
907
1281
|
this.exprStart = options.expressionStart || "{{";
|
|
908
1282
|
this.exprEnd = options.expressionEnd || "}}";
|
|
909
1283
|
this.startLen = this.exprStart.length;
|
|
@@ -914,13 +1288,20 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
|
|
|
914
1288
|
{
|
|
915
1289
|
key: "parse",
|
|
916
1290
|
value: function(template) {
|
|
1291
|
+
var _this = this;
|
|
917
1292
|
if ("string" != typeof template) throw new TypeError("模板必须是字符串");
|
|
1293
|
+
if (template.length > this.maxTemplateLength) throw new RangeError("Template exceeds the maximum length of ".concat(this.maxTemplateLength, " characters"));
|
|
918
1294
|
var tokens = [];
|
|
1295
|
+
var pushToken = function(token) {
|
|
1296
|
+
if (tokens.length >= _this.maxTokens) throw new RangeError("Template exceeds the maximum token count of ".concat(_this.maxTokens));
|
|
1297
|
+
tokens.push(token);
|
|
1298
|
+
};
|
|
919
1299
|
var length = template.length;
|
|
920
1300
|
var state = "TEXT";
|
|
921
1301
|
var buffer = "";
|
|
922
1302
|
var exprStartPos = 0;
|
|
923
1303
|
var pos = 0;
|
|
1304
|
+
var prevExprChar = "";
|
|
924
1305
|
while(pos < length){
|
|
925
1306
|
var char = template[pos];
|
|
926
1307
|
var nextChar = template[pos + 1];
|
|
@@ -928,7 +1309,7 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
|
|
|
928
1309
|
case "TEXT":
|
|
929
1310
|
if (this._isMatch(pos, template, this.exprStart)) {
|
|
930
1311
|
if (buffer.length > 0) {
|
|
931
|
-
|
|
1312
|
+
pushToken({
|
|
932
1313
|
type: "text",
|
|
933
1314
|
value: buffer,
|
|
934
1315
|
start: pos - buffer.length,
|
|
@@ -938,6 +1319,7 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
|
|
|
938
1319
|
}
|
|
939
1320
|
state = "EXPR";
|
|
940
1321
|
exprStartPos = pos;
|
|
1322
|
+
prevExprChar = "";
|
|
941
1323
|
pos += this.startLen;
|
|
942
1324
|
continue;
|
|
943
1325
|
}
|
|
@@ -947,10 +1329,11 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
|
|
|
947
1329
|
if ("'" === char) state = "STRING_SQ";
|
|
948
1330
|
else if ('"' === char) state = "STRING_DQ";
|
|
949
1331
|
else if ("`" === char) state = "TEMPLATE";
|
|
1332
|
+
else if ("/" === char && this._isRegexPosition(prevExprChar)) state = "REGEX";
|
|
950
1333
|
else if ("\\" === char) state = "'" === nextChar ? "ESCAPE_SQ" : '"' === nextChar ? "ESCAPE_DQ" : "`" === nextChar ? "ESCAPE_TEMPLATE" : "ESCAPE_EXPR";
|
|
951
1334
|
else if (this._isMatch(pos, template, this.exprEnd)) {
|
|
952
1335
|
var exprValue = this.preserveWhitespace ? buffer : buffer.trim();
|
|
953
|
-
if (exprValue.length > 0)
|
|
1336
|
+
if (exprValue.length > 0) pushToken({
|
|
954
1337
|
type: "expression",
|
|
955
1338
|
value: exprValue,
|
|
956
1339
|
start: exprStartPos,
|
|
@@ -963,6 +1346,7 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
|
|
|
963
1346
|
pos += this.endLen;
|
|
964
1347
|
continue;
|
|
965
1348
|
}
|
|
1349
|
+
if (!RegExp("\\s", "u").test(char)) prevExprChar = char;
|
|
966
1350
|
buffer += char;
|
|
967
1351
|
break;
|
|
968
1352
|
case "STRING_SQ":
|
|
@@ -980,6 +1364,17 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
|
|
|
980
1364
|
else if ("`" === char) state = "EXPR";
|
|
981
1365
|
buffer += char;
|
|
982
1366
|
break;
|
|
1367
|
+
case "REGEX":
|
|
1368
|
+
if ("\\" === char) state = "ESCAPE_REGEX";
|
|
1369
|
+
else if ("[" === char) state = "REGEX_CLASS";
|
|
1370
|
+
else if ("/" === char) state = "EXPR";
|
|
1371
|
+
buffer += char;
|
|
1372
|
+
break;
|
|
1373
|
+
case "REGEX_CLASS":
|
|
1374
|
+
if ("\\" === char) state = "ESCAPE_REGEX";
|
|
1375
|
+
else if ("]" === char) state = "REGEX";
|
|
1376
|
+
buffer += char;
|
|
1377
|
+
break;
|
|
983
1378
|
case "ESCAPE_SQ":
|
|
984
1379
|
buffer += char;
|
|
985
1380
|
state = "STRING_SQ";
|
|
@@ -992,6 +1387,10 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
|
|
|
992
1387
|
buffer += char;
|
|
993
1388
|
state = "TEMPLATE";
|
|
994
1389
|
break;
|
|
1390
|
+
case "ESCAPE_REGEX":
|
|
1391
|
+
buffer += char;
|
|
1392
|
+
state = "REGEX";
|
|
1393
|
+
break;
|
|
995
1394
|
case "ESCAPE_EXPR":
|
|
996
1395
|
buffer += char;
|
|
997
1396
|
state = "EXPR";
|
|
@@ -999,7 +1398,7 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
|
|
|
999
1398
|
}
|
|
1000
1399
|
pos++;
|
|
1001
1400
|
}
|
|
1002
|
-
if (buffer.length > 0) if ("TEXT" === state)
|
|
1401
|
+
if (buffer.length > 0) if ("TEXT" === state) pushToken({
|
|
1003
1402
|
type: "text",
|
|
1004
1403
|
value: buffer,
|
|
1005
1404
|
start: pos - buffer.length,
|
|
@@ -1007,17 +1406,22 @@ var TemplateParser_TemplateParser = /*#__PURE__*/ function() {
|
|
|
1007
1406
|
});
|
|
1008
1407
|
else {
|
|
1009
1408
|
var incompleteExpr = this.exprStart + buffer;
|
|
1010
|
-
|
|
1409
|
+
pushToken({
|
|
1011
1410
|
type: "text",
|
|
1012
1411
|
value: incompleteExpr,
|
|
1013
1412
|
start: exprStartPos,
|
|
1014
1413
|
end: pos
|
|
1015
1414
|
});
|
|
1016
|
-
console.warn("警告:在位置 ".concat(exprStartPos, " 开始的表达式未正确结束"));
|
|
1017
1415
|
}
|
|
1018
1416
|
return tokens;
|
|
1019
1417
|
}
|
|
1020
1418
|
},
|
|
1419
|
+
{
|
|
1420
|
+
key: "_isRegexPosition",
|
|
1421
|
+
value: function(prev) {
|
|
1422
|
+
return "" === prev || "(,=:[!&|?{};+-*%^~<>".includes(prev);
|
|
1423
|
+
}
|
|
1424
|
+
},
|
|
1021
1425
|
{
|
|
1022
1426
|
key: "_isMatch",
|
|
1023
1427
|
value: function(pos, template, sequence) {
|
|
@@ -1041,18 +1445,36 @@ function src_instanceof(left, right) {
|
|
|
1041
1445
|
if (null != right && "undefined" != typeof Symbol && right[Symbol.hasInstance]) return !!right[Symbol.hasInstance](left);
|
|
1042
1446
|
return left instanceof right;
|
|
1043
1447
|
}
|
|
1448
|
+
var DEFAULT_MAX_TEMPLATE_EXPRESSIONS = 100;
|
|
1449
|
+
var MAX_TEMPLATE_EXPRESSIONS = 1000;
|
|
1450
|
+
var DEFAULT_MAX_TEMPLATE_OUTPUT_LENGTH = 100000;
|
|
1451
|
+
var MAX_TEMPLATE_OUTPUT_LENGTH = 1000000;
|
|
1452
|
+
function src_validateLimit(value, name, defaultValue, maximum) {
|
|
1453
|
+
if (void 0 === value) return defaultValue;
|
|
1454
|
+
if (!Number.isSafeInteger(value) || value < 1 || value > maximum) throw new RangeError("".concat(name, " must be an integer between 1 and ").concat(maximum));
|
|
1455
|
+
return value;
|
|
1456
|
+
}
|
|
1044
1457
|
function evalExpression(expression, context) {
|
|
1045
1458
|
return Evaluator_Evaluator.evaluate(expression, context);
|
|
1046
1459
|
}
|
|
1047
1460
|
function evalTemplate(template, context, templateParserOptions) {
|
|
1461
|
+
var options = null != templateParserOptions ? templateParserOptions : {};
|
|
1462
|
+
var maxExpressions = src_validateLimit(options.maxExpressions, "maxExpressions", DEFAULT_MAX_TEMPLATE_EXPRESSIONS, MAX_TEMPLATE_EXPRESSIONS);
|
|
1463
|
+
var maxOutputLength = src_validateLimit(options.maxOutputLength, "maxOutputLength", DEFAULT_MAX_TEMPLATE_OUTPUT_LENGTH, MAX_TEMPLATE_OUTPUT_LENGTH);
|
|
1464
|
+
var tokens = TemplateParser_TemplateParser.parse(template, options);
|
|
1048
1465
|
var result = "";
|
|
1466
|
+
var expressionCount = 0;
|
|
1467
|
+
var evaluator = new Evaluator_Evaluator(context, {
|
|
1468
|
+
maxInputLength: options.maxExpressionLength,
|
|
1469
|
+
maxEvaluationSteps: options.maxEvaluationSteps
|
|
1470
|
+
});
|
|
1049
1471
|
var typeHandler = {
|
|
1050
1472
|
text: function(token) {
|
|
1051
1473
|
return token.value;
|
|
1052
1474
|
},
|
|
1053
1475
|
expression: function(token) {
|
|
1054
1476
|
try {
|
|
1055
|
-
return
|
|
1477
|
+
return evaluator.evaluate(token.value);
|
|
1056
1478
|
} catch (error) {
|
|
1057
1479
|
if (src_instanceof(error, ReferenceError) && error.message.endsWith("is not defined")) return "undefined";
|
|
1058
1480
|
throw error;
|
|
@@ -1061,11 +1483,17 @@ function evalTemplate(template, context, templateParserOptions) {
|
|
|
1061
1483
|
};
|
|
1062
1484
|
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
|
|
1063
1485
|
try {
|
|
1064
|
-
for(var _iterator =
|
|
1486
|
+
for(var _iterator = tokens[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
1065
1487
|
var token = _step.value;
|
|
1066
1488
|
var _typeHandler_token_type;
|
|
1067
1489
|
var handler = null != (_typeHandler_token_type = typeHandler[token.type]) ? _typeHandler_token_type : typeHandler["text"];
|
|
1068
|
-
|
|
1490
|
+
if ("expression" === token.type) {
|
|
1491
|
+
expressionCount++;
|
|
1492
|
+
if (expressionCount > maxExpressions) throw new RangeError("Template exceeds the maximum expression count of ".concat(maxExpressions));
|
|
1493
|
+
}
|
|
1494
|
+
var chunk = String(handler(token));
|
|
1495
|
+
if (result.length + chunk.length > maxOutputLength) throw new RangeError("Template output exceeds the maximum length of ".concat(maxOutputLength, " characters"));
|
|
1496
|
+
result += chunk;
|
|
1069
1497
|
}
|
|
1070
1498
|
} catch (err) {
|
|
1071
1499
|
_didIteratorError = true;
|