1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Protection against infinite recursion, bug 231742.

This commit is contained in:
Sergey Prigogin 2008-06-02 06:12:17 +00:00
parent d09c6c7601
commit def81d5ae0
7 changed files with 37 additions and 22 deletions

View file

@ -10,14 +10,14 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast; 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 <code>true</code> if the two objects are equal or represent the same type. * Returns <code>true</code> 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) { if (o1 == o2) {
return true; return true;
} }

View file

@ -16,7 +16,7 @@ package org.eclipse.cdt.core.dom.ast;
*/ */
public interface IType extends Cloneable { public interface IType extends Cloneable {
public static final IType[] EMPTY_TYPE_ARRAY = new IType[0]; 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(); public Object clone();

View file

@ -10,6 +10,6 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.parser.util; package org.eclipse.cdt.core.parser.util;
public interface IObjectComparator { public interface IObjectMatcher {
boolean isSame(Object o1, Object o2); boolean isEquivalent(Object o1, Object o2);
} }

View file

@ -145,14 +145,14 @@ public class ObjectMap extends ObjectTable<Object> {
return vals; return vals;
} }
public boolean isSame(ObjectMap other, IObjectComparator comparator) { public boolean isEquivalent(ObjectMap other, IObjectMatcher matcher) {
if (!super.isSame(other, comparator)) { if (!super.isEquivalent(other, matcher)) {
return false; return false;
} }
for (int i = 0; i < keyTable.length; i++) { for (int i = 0; i < keyTable.length; i++) {
Object val1 = valueTable[i]; Object val1 = valueTable[i];
Object val2 = other.valueTable[i]; Object val2 = other.valueTable[i];
if (val1 != val2 && !comparator.isSame(val1, val2)) { if (val1 != val2 && !matcher.isEquivalent(val1, val2)) {
return false; return false;
} }
} }

View file

@ -154,7 +154,7 @@ public abstract class ObjectTable<T> extends HashTable {
return keys; return keys;
} }
public boolean isSame(ObjectTable<T> other, IObjectComparator comparator) { public boolean isEquivalent(ObjectTable<T> other, IObjectMatcher matcher) {
if (size() != other.size()) { if (size() != other.size()) {
return false; return false;
} }
@ -162,7 +162,7 @@ public abstract class ObjectTable<T> extends HashTable {
for (int i = 0; i < keyTable.length; i++) { for (int i = 0; i < keyTable.length; i++) {
T key1 = keyTable[i]; T key1 = keyTable[i];
T key2 = other.keyTable[i]; T key2 = other.keyTable[i];
if (key1 != key2 && !comparator.isSame(key1, key2)) { if (key1 != key2 && !matcher.isEquivalent(key1, key2)) {
return false; return false;
} }
} }

View file

@ -44,6 +44,7 @@ public class CPPASTName extends CPPASTNode implements IASTName, IASTCompletionCo
* For test-purposes, only. * For test-purposes, only.
*/ */
public static boolean fAllowRecursionBindings= true; public static boolean fAllowRecursionBindings= true;
final static class RecursionResolvingBinding extends ProblemBinding { final static class RecursionResolvingBinding extends ProblemBinding {
public RecursionResolvingBinding(IASTName node) { public RecursionResolvingBinding(IASTName node) {
super(node, IProblemBinding.SEMANTIC_RECURSION_IN_LOOKUP, node.toCharArray()); 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$ private static final String EMPTY_STRING = ""; //$NON-NLS-1$
static final int MAX_RESOLUTION_DEPTH = 5; static final int MAX_RESOLUTION_DEPTH = 5;
private char[] name; private char[] name;
private IBinding binding = null; private IBinding binding = null;

View file

@ -13,6 +13,7 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException; 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.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType; 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.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.core.runtime.Assert;
/** /**
* @author aniefer * @author aniefer
*/ */
public class CPPTypedefSpecialization extends CPPSpecialization implements ITypedef, ITypeContainer { 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 * @param specialized
@ -47,15 +59,18 @@ public class CPPTypedefSpecialization extends CPPSpecialization implements IType
*/ */
public IType getType() throws DOMException { public IType getType() throws DOMException {
if (type == null) { if (type == null) {
type = CPPTemplates.instantiateType(getTypedef().getType(), argumentMap, getScope()); if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) {
// A typedef pointing to itself is a sure recipe for an infinite loop -- replace with type = new RecursionResolvingBinding(getDefinition(), getNameCharArray());
// a problem binding. } else {
if (type instanceof CPPTypedefSpecialization && type = CPPTemplates.instantiateType(getTypedef().getType(), argumentMap, getScope());
((CPPTypedefSpecialization) type).getSpecializedBinding().equals(getSpecializedBinding()) && // A typedef pointing to itself is a sure recipe for an infinite loop -- replace
((CPPTypedefSpecialization) type).getArgumentMap().isSame(argumentMap, IType.TYPE_COMPARATOR)) { // with a problem binding.
type = new ProblemBinding(getDefinition(), IProblemBinding.SEMANTIC_INVALID_TYPE, if (type instanceof CPPTypedefSpecialization &&
getNameCharArray()); ((CPPTypedefSpecialization) type).getSpecializedBinding().equals(getSpecializedBinding()) &&
} ((CPPTypedefSpecialization) type).getArgumentMap().isEquivalent(argumentMap, IType.TYPE_MATCHER)) {
type = new RecursionResolvingBinding(getDefinition(), getNameCharArray());
}
}
} }
return type; return type;
} }