Add instantiation count limiter

This commit is contained in:
Anders Hejlsberg 2019-06-24 17:11:16 -10:00
parent 917cd6c6d9
commit 49e3f17886

View File

@ -65,6 +65,7 @@ namespace ts {
let typeCount = 0;
let symbolCount = 0;
let enumCount = 0;
let instantiationCount = 0;
let instantiationDepth = 0;
let constraintDepth = 0;
let currentNode: Node | undefined;
@ -11408,13 +11409,14 @@ namespace ts {
if (!type || !mapper || mapper === identityMapper) {
return type;
}
if (instantiationDepth === 50) {
if (instantiationDepth === 50 || instantiationCount >= 5000000) {
// We have reached 50 recursive type instantiations and there is a very high likelyhood we're dealing
// with a combination of infinite generic types that perpetually generate new type identities. We stop
// the recursion here by yielding the error type.
error(currentNode, Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite);
return errorType;
}
instantiationCount++;
instantiationDepth++;
const result = instantiateTypeWorker(type, mapper);
instantiationDepth--;
@ -24494,6 +24496,7 @@ namespace ts {
function checkExpression(node: Expression | QualifiedName, checkMode?: CheckMode, forceTuple?: boolean): Type {
const saveCurrentNode = currentNode;
currentNode = node;
instantiationCount = 0;
const uninstantiatedType = checkExpressionWorker(node, checkMode, forceTuple);
const type = instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode);
if (isConstEnumObjectType(type)) {
@ -29204,6 +29207,7 @@ namespace ts {
if (node) {
const saveCurrentNode = currentNode;
currentNode = node;
instantiationCount = 0;
checkSourceElementWorker(node);
currentNode = saveCurrentNode;
}
@ -29475,6 +29479,7 @@ namespace ts {
function checkDeferredNode(node: Node) {
const saveCurrentNode = currentNode;
currentNode = node;
instantiationCount = 0;
switch (node.kind) {
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction: