Skip to content

Commit

Permalink
fix: bugfix for soot-oss#1060
Browse files Browse the repository at this point in the history
Instead of isPhantom() we now use !hasSuperclass() || "java.lang.Object".equals(sootClass.getName())
  • Loading branch information
jpstotz committed Nov 29, 2018
1 parent cdd4f65 commit 04b5d72
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 14 deletions.
2 changes: 2 additions & 0 deletions src/main/java/soot/SootClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ public class SootClass extends AbstractHost implements Numberable {

public final static String INVOKEDYNAMIC_DUMMY_CLASS_NAME = "soot.dummy.InvokeDynamic";

public final static String JAVA_LANG_OBJECT = "java.lang.Object";

/**
* Constructs an empty SootClass with the given name and modifiers.
*/
Expand Down
45 changes: 31 additions & 14 deletions src/main/java/soot/toolkits/exceptions/ThrowableSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import soot.RefType;
import soot.Scene;
import soot.Singletons;
import soot.SootClass;
import soot.Unit;
import soot.options.Options;

Expand Down Expand Up @@ -456,19 +457,20 @@ public ThrowableSet add(RefType e) throws ThrowableSet.AlreadyHasExclusionsExcep
}
}
FastHierarchy hierarchy = Scene.v().getOrMakeFastHierarchy();
boolean eHasNoHierarchy = !(e.getSootClass().hasSuperclass() || //
SootClass.JAVA_LANG_OBJECT.equals(e.getSootClass().getName()));

for (AnySubType excludedType : exceptionsExcluded) {
RefType exclusionBase = excludedType.getBase();
if ((e.getSootClass().isPhantom() && exclusionBase.equals(e))
|| (!e.getSootClass().isPhantom() && hierarchy.canStoreType(e, exclusionBase))) {
if ((eHasNoHierarchy && exclusionBase.equals(e)) || (!eHasNoHierarchy && hierarchy.canStoreType(e, exclusionBase))) {
throw new AlreadyHasExclusionsException("ThrowableSet.add(RefType): adding" + e.toString() + " to the set [ "
+ this.toString() + "] where " + exclusionBase.toString() + " is excluded.");
}
}

// If this is a real class, we need to check whether we already have it
// in the list through subtyping.
if (!e.getSootClass().isPhantom()) {
if (!eHasNoHierarchy) {
for (RefLikeType incumbent : exceptionsIncluded) {
if (incumbent instanceof AnySubType) {
// Need to use incumbent.getBase() because
Expand Down Expand Up @@ -543,6 +545,8 @@ public ThrowableSet add(AnySubType e) throws ThrowableSet.AlreadyHasExclusionsEx

FastHierarchy hierarchy = Scene.v().getOrMakeFastHierarchy();
RefType newBase = e.getBase();
boolean newBaseHasNoHierarchy = !(newBase.getSootClass().hasSuperclass() || //
SootClass.JAVA_LANG_OBJECT.equals(newBase.getSootClass().getName()));

if (INSTRUMENTING) {
if (exceptionsExcluded.isEmpty()) {
Expand All @@ -553,9 +557,11 @@ public ThrowableSet add(AnySubType e) throws ThrowableSet.AlreadyHasExclusionsEx
}
for (AnySubType excludedType : exceptionsExcluded) {
RefType exclusionBase = excludedType.getBase();
boolean exclusionBaseHasNoHierarchy = !(exclusionBase.getSootClass().hasSuperclass() || //
SootClass.JAVA_LANG_OBJECT.equals(exclusionBase.getSootClass().getName()));

boolean isExcluded = exclusionBase.getSootClass().isPhantom() && exclusionBase.equals(newBase);
isExcluded |= !exclusionBase.getSootClass().isPhantom()
boolean isExcluded = exclusionBaseHasNoHierarchy && exclusionBase.equals(newBase);
isExcluded |= !exclusionBaseHasNoHierarchy
&& (hierarchy.canStoreType(newBase, exclusionBase) || hierarchy.canStoreType(exclusionBase, newBase));

if (isExcluded) {
Expand Down Expand Up @@ -593,7 +599,7 @@ public ThrowableSet add(AnySubType e) throws ThrowableSet.AlreadyHasExclusionsEx
}
} else if (incumbent instanceof AnySubType) {
RefType incumbentBase = ((AnySubType) incumbent).getBase();
if (newBase.getSootClass().isPhantom()) {
if (newBaseHasNoHierarchy) {
if (!incumbentBase.equals(newBase)) {
resultSet.add(incumbent);
}
Expand Down Expand Up @@ -830,13 +836,22 @@ public boolean catchableAs(RefType catcher) {
}

FastHierarchy h = Scene.v().getOrMakeFastHierarchy();
/**
* Originally this implementation had checked if the catcher.getSootClass() is a phantom class. However this makes
* problems in case the soot option no_bodies_for_excluded==true because certain library classes will be marked as
* phantom classes even if they have a hierarchy. The workaround for this problem is to check for the suerClass. As every
* class except java.lang.Object have a superClass (even interfaces have!) only real phantom classes can be identified
* using this method.
*/
boolean catcherHasNoHierarchy = !(catcher.getSootClass().hasSuperclass() || //
SootClass.JAVA_LANG_OBJECT.equals(catcher.getSootClass().getName()));

if (exceptionsExcluded.size() > 0) {
if (INSTRUMENTING) {
Manager.v().catchableAsFromSearch++;
}
for (AnySubType exclusion : exceptionsExcluded) {
if (catcher.getSootClass().isPhantom()) {
if (catcherHasNoHierarchy) {
if (exclusion.getBase().equals(catcher)) {
return false;
}
Expand Down Expand Up @@ -867,12 +882,12 @@ public boolean catchableAs(RefType catcher) {
// assertion failure.
throw new IllegalStateException(
"ThrowableSet.catchableAs(RefType): exceptions.contains() failed to match contained RefType " + catcher);
} else if (!catcher.getSootClass().isPhantom() && h.canStoreType(thrownType, catcher)) {
} else if (!catcherHasNoHierarchy && h.canStoreType(thrownType, catcher)) {
return true;
}
} else {
RefType thrownBase = ((AnySubType) thrownType).getBase();
if (catcher.getSootClass().isPhantom()) {
if (catcherHasNoHierarchy) {
if (thrownBase.equals(catcher) || thrownBase.getClassName().equals("java.lang.Throwable")) {
return true;
}
Expand Down Expand Up @@ -913,12 +928,14 @@ public Pair whichCatchableAs(RefType catcher) {
if (INSTRUMENTING) {
Manager.v().removesFromSearch++;
}
boolean catcherHasNoHierarchy = !(catcher.getSootClass().hasSuperclass() || //
SootClass.JAVA_LANG_OBJECT.equals(catcher.getSootClass().getName()));

for (AnySubType exclusion : exceptionsExcluded) {
RefType exclusionBase = exclusion.getBase();

// Is the current type explicitly excluded?
if (catcher.getSootClass().isPhantom() && exclusionBase.equals(catcher)) {
if (catcherHasNoHierarchy && exclusionBase.equals(catcher)) {
return new Pair(ThrowableSet.Manager.v().EMPTY, this);
}

Expand All @@ -940,9 +957,9 @@ public Pair whichCatchableAs(RefType catcher) {

for (RefLikeType inclusion : exceptionsIncluded) {
if (inclusion instanceof RefType) {
// If the current type is a phantom type, we catch it if and
// If the current type is has no hierarchy, we catch it if and
// only if it is in the inclusion list and ignore any hierarchy.
if (catcher.getSootClass().isPhantom()) {
if (catcherHasNoHierarchy) {
if (inclusion.equals(catcher)) {
caughtIncluded = addExceptionToSet(inclusion, caughtIncluded);
} else {
Expand All @@ -955,9 +972,9 @@ public Pair whichCatchableAs(RefType catcher) {
}
} else {
RefType base = ((AnySubType) inclusion).getBase();
// If the current type is a phantom type, we catch it if and
// If the current type is has no hierarchy, we catch it if and
// only if it is in the inclusion list and ignore any hierarchy.
if (catcher.getSootClass().isPhantom()) {
if (catcherHasNoHierarchy) {
if (base.equals(catcher)) {
caughtIncluded = addExceptionToSet(inclusion, caughtIncluded);
} else {
Expand Down

0 comments on commit 04b5d72

Please sign in to comment.