Skip to content

Commit 9e48fb4

Browse files
committed
avoid an NPE
1 parent 0eb3caf commit 9e48fb4

File tree

2 files changed

+39
-7
lines changed

2 files changed

+39
-7
lines changed

soot-infoflow-android/src/soot/jimple/infoflow/android/callbacks/filters/ApplicationCallbackFilter.java

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import soot.SootClass;
99
import soot.SootMethod;
1010
import soot.jimple.infoflow.android.entryPointCreators.AndroidEntryPointConstants;
11+
import soot.jimple.infoflow.typing.TypeUtils;
1112

1213
/**
1314
* A callback filter that restricts application callbacks to ComponentCallbacks
@@ -70,9 +71,9 @@ public boolean accepts(SootClass component, SootClass callbackHandler) {
7071
&& !callbackHandler.getName().equals(applicationClass)) {
7172
final FastHierarchy fh = Scene.v().getOrMakeFastHierarchy();
7273
final RefType callbackType = callbackHandler.getType();
73-
if (!fh.canStoreType(callbackType, this.activityLifecycleCallbacks)
74-
&& !fh.canStoreType(callbackType, this.provideAssistDataListener)
75-
&& !fh.canStoreType(callbackType, this.componentCallbacks))
74+
if (!TypeUtils.canStoreType(fh, callbackType, this.activityLifecycleCallbacks)
75+
&& !TypeUtils.canStoreType(fh, callbackType, this.provideAssistDataListener)
76+
&& !TypeUtils.canStoreType(fh, callbackType, this.componentCallbacks))
7677
return false;
7778
}
7879

@@ -81,10 +82,24 @@ public boolean accepts(SootClass component, SootClass callbackHandler) {
8182

8283
@Override
8384
public void reset() {
84-
this.activityLifecycleCallbacks = RefType.v(AndroidEntryPointConstants.ACTIVITYLIFECYCLECALLBACKSINTERFACE);
85-
this.provideAssistDataListener = RefType.v("android.app.Application$OnProvideAssistDataListener");
86-
this.componentCallbacks = RefType.v(AndroidEntryPointConstants.COMPONENTCALLBACKSINTERFACE);
87-
this.componentCallbacks2 = RefType.v(AndroidEntryPointConstants.COMPONENTCALLBACKS2INTERFACE);
85+
this.activityLifecycleCallbacks = getRefTypeUnsafe(
86+
AndroidEntryPointConstants.ACTIVITYLIFECYCLECALLBACKSINTERFACE);
87+
this.provideAssistDataListener = getRefTypeUnsafe("android.app.Application$OnProvideAssistDataListener");
88+
this.componentCallbacks = getRefTypeUnsafe(AndroidEntryPointConstants.COMPONENTCALLBACKSINTERFACE);
89+
this.componentCallbacks2 = getRefTypeUnsafe(AndroidEntryPointConstants.COMPONENTCALLBACKS2INTERFACE);
90+
}
91+
92+
/**
93+
* Gets the {@link RefType} that corresponds to the given class name, or
94+
* <code>null</code> if the class is unknown
95+
*
96+
* @param className The class name for which to get the reference type
97+
* @return The reference type for the given class name, or <code>null</code> if
98+
* the class is unknown
99+
*/
100+
private RefType getRefTypeUnsafe(String className) {
101+
SootClass sc = Scene.v().getSootClassUnsafe(className);
102+
return sc == null ? null : sc.getType();
88103
}
89104

90105
@Override

soot-infoflow/src/soot/jimple/infoflow/typing/TypeUtils.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,4 +315,21 @@ public static List<SootClass> getAllDerivedClasses(SootClass classOrInterface) {
315315
return h.getSubclassesOfIncluding(classOrInterface);
316316
}
317317

318+
/**
319+
* Checks whether a value of type "child" can be stored in a variable of type
320+
* "parent". If one of the types is <code>null</code>, we assume that the value
321+
* cannot be stored.
322+
*
323+
* @param fh The {@link FastHierarchy}
324+
* @param child The actual type of the value
325+
* @param parent The declared type of the variable
326+
* @return True if a value of type "child" can be stored in a variable of type
327+
* "parent", false otherwise
328+
*/
329+
public static boolean canStoreType(FastHierarchy fh, Type child, Type parent) {
330+
if (child == null || parent == null)
331+
return false;
332+
return fh.canStoreType(child, parent);
333+
}
334+
318335
}

0 commit comments

Comments
 (0)