From def81d5ae0a9ef557b56360d5ac821775ae5057c Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Mon, 2 Jun 2008 06:12:17 +0000 Subject: [PATCH] Protection against infinite recursion, bug 231742. --- ...ypeComparator.java => ASTTypeMatcher.java} | 6 ++-- .../org/eclipse/cdt/core/dom/ast/IType.java | 2 +- ...ectComparator.java => IObjectMatcher.java} | 4 +-- .../cdt/core/parser/util/ObjectMap.java | 6 ++-- .../cdt/core/parser/util/ObjectTable.java | 4 +-- .../core/dom/parser/cpp/CPPASTName.java | 2 +- .../parser/cpp/CPPTypedefSpecialization.java | 35 +++++++++++++------ 7 files changed, 37 insertions(+), 22 deletions(-) rename core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/{ASTTypeComparator.java => ASTTypeMatcher.java} (83%) rename core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/{IObjectComparator.java => IObjectMatcher.java} (88%) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeComparator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeMatcher.java similarity index 83% rename from core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeComparator.java rename to core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeMatcher.java index 94e16895e28..35d890802ee 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeComparator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeMatcher.java @@ -10,14 +10,14 @@ *******************************************************************************/ package org.eclipse.cdt.core.dom.ast; -import org.eclipse.cdt.core.parser.util.IObjectComparator; +import org.eclipse.cdt.core.parser.util.IObjectMatcher; -public class ASTTypeComparator implements IObjectComparator { +public class ASTTypeMatcher implements IObjectMatcher { /** * Returns true if the two objects are equal or represent the same type. */ - public boolean isSame(Object o1, Object o2) { + public boolean isEquivalent(Object o1, Object o2) { if (o1 == o2) { return true; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IType.java index 53ca22eaef3..5ad70385288 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IType.java @@ -16,7 +16,7 @@ package org.eclipse.cdt.core.dom.ast; */ public interface IType extends Cloneable { public static final IType[] EMPTY_TYPE_ARRAY = new IType[0]; - public static final ASTTypeComparator TYPE_COMPARATOR = new ASTTypeComparator(); + public static final ASTTypeMatcher TYPE_MATCHER = new ASTTypeMatcher(); public Object clone(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/IObjectComparator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/IObjectMatcher.java similarity index 88% rename from core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/IObjectComparator.java rename to core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/IObjectMatcher.java index ebb2fe09b98..48d2f5b3f48 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/IObjectComparator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/IObjectMatcher.java @@ -10,6 +10,6 @@ *******************************************************************************/ package org.eclipse.cdt.core.parser.util; -public interface IObjectComparator { - boolean isSame(Object o1, Object o2); +public interface IObjectMatcher { + boolean isEquivalent(Object o1, Object o2); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectMap.java index 4f33592fc2d..6157913c7a3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectMap.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectMap.java @@ -145,14 +145,14 @@ public class ObjectMap extends ObjectTable { return vals; } - public boolean isSame(ObjectMap other, IObjectComparator comparator) { - if (!super.isSame(other, comparator)) { + public boolean isEquivalent(ObjectMap other, IObjectMatcher matcher) { + if (!super.isEquivalent(other, matcher)) { return false; } for (int i = 0; i < keyTable.length; i++) { Object val1 = valueTable[i]; Object val2 = other.valueTable[i]; - if (val1 != val2 && !comparator.isSame(val1, val2)) { + if (val1 != val2 && !matcher.isEquivalent(val1, val2)) { return false; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectTable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectTable.java index 7a8ae42ffa5..12741cae3c9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectTable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ObjectTable.java @@ -154,7 +154,7 @@ public abstract class ObjectTable extends HashTable { return keys; } - public boolean isSame(ObjectTable other, IObjectComparator comparator) { + public boolean isEquivalent(ObjectTable other, IObjectMatcher matcher) { if (size() != other.size()) { return false; } @@ -162,7 +162,7 @@ public abstract class ObjectTable extends HashTable { for (int i = 0; i < keyTable.length; i++) { T key1 = keyTable[i]; T key2 = other.keyTable[i]; - if (key1 != key2 && !comparator.isSame(key1, key2)) { + if (key1 != key2 && !matcher.isEquivalent(key1, key2)) { return false; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java index dcc3f451d08..280d6728d76 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java @@ -44,6 +44,7 @@ public class CPPASTName extends CPPASTNode implements IASTName, IASTCompletionCo * For test-purposes, only. */ public static boolean fAllowRecursionBindings= true; + final static class RecursionResolvingBinding extends ProblemBinding { public RecursionResolvingBinding(IASTName node) { super(node, IProblemBinding.SEMANTIC_RECURSION_IN_LOOKUP, node.toCharArray()); @@ -55,7 +56,6 @@ public class CPPASTName extends CPPASTNode implements IASTName, IASTCompletionCo private static final String EMPTY_STRING = ""; //$NON-NLS-1$ static final int MAX_RESOLUTION_DEPTH = 5; - private char[] name; private IBinding binding = null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedefSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedefSpecialization.java index 2a4b9714ca7..5ce1c9e2d9f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedefSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedefSpecialization.java @@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IType; @@ -22,12 +23,23 @@ import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; +import org.eclipse.core.runtime.Assert; /** * @author aniefer */ public class CPPTypedefSpecialization extends CPPSpecialization implements ITypedef, ITypeContainer { - private IType type; + final static class RecursionResolvingBinding extends ProblemBinding { + public RecursionResolvingBinding(IASTNode node, char[] arg) { + super(node, IProblemBinding.SEMANTIC_RECURSION_IN_LOOKUP, arg); + Assert.isTrue(CPPASTName.fAllowRecursionBindings, getMessage()); + } + } + + static final int MAX_RESOLUTION_DEPTH = 5; + + private IType type; + private int fResolutionDepth; /** * @param specialized @@ -47,15 +59,18 @@ public class CPPTypedefSpecialization extends CPPSpecialization implements IType */ public IType getType() throws DOMException { if (type == null) { - type = CPPTemplates.instantiateType(getTypedef().getType(), argumentMap, getScope()); - // A typedef pointing to itself is a sure recipe for an infinite loop -- replace with - // a problem binding. - if (type instanceof CPPTypedefSpecialization && - ((CPPTypedefSpecialization) type).getSpecializedBinding().equals(getSpecializedBinding()) && - ((CPPTypedefSpecialization) type).getArgumentMap().isSame(argumentMap, IType.TYPE_COMPARATOR)) { - type = new ProblemBinding(getDefinition(), IProblemBinding.SEMANTIC_INVALID_TYPE, - getNameCharArray()); - } + if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) { + type = new RecursionResolvingBinding(getDefinition(), getNameCharArray()); + } else { + type = CPPTemplates.instantiateType(getTypedef().getType(), argumentMap, getScope()); + // A typedef pointing to itself is a sure recipe for an infinite loop -- replace + // with a problem binding. + if (type instanceof CPPTypedefSpecialization && + ((CPPTypedefSpecialization) type).getSpecializedBinding().equals(getSpecializedBinding()) && + ((CPPTypedefSpecialization) type).getArgumentMap().isEquivalent(argumentMap, IType.TYPE_MATCHER)) { + type = new RecursionResolvingBinding(getDefinition(), getNameCharArray()); + } + } } return type; }