Add better support for the case when an odex file has missing classes

git-svn-id: https://smali.googlecode.com/svn/trunk@693 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
JesusFreke@JesusFreke.com 2010-04-03 23:02:48 +00:00
parent 19b601436a
commit c1cc0e0934
3 changed files with 29 additions and 11 deletions

View File

@ -321,10 +321,10 @@ public class ClassDefinition {
MethodDefinition methodDefinition = new MethodDefinition(method);
methodDefinition.writeTo(writer, annotationSet, parameterAnnotationList);
ValidationException validationException = methodDefinition.getValidationException();
if (validationException != null) {
System.err.println(String.format("Error while disassembling method %s. Continuing.",
method.method.getMethodString()));
validationException.printStackTrace(System.err);
this.validationErrors = true;
}

View File

@ -113,6 +113,15 @@ public class baksmali {
* package name are separated by '/'
*/
if (registerInfo != 0 || deodex || verify) {
//If we are analyzing the bytecode, make sure that this class is loaded into the ClassPath. If it isn't
//then there was some error while loading it, and we should skip it
ClassPath.ClassDef classDef = ClassPath.getClassDef(classDefItem.getClassType(), false);
if (classDef == null || classDef instanceof ClassPath.UnresolvedClassDef) {
continue;
}
}
String classDescriptor = classDefItem.getClassType().getTypeDescriptor();
//validate that the descriptor is formatted like we expect
@ -179,11 +188,6 @@ public class baksmali {
}
}
}
//TODO: GROT
if (classDefinition.hadValidationErrors()) {
System.exit(1);
}
}
}

View File

@ -145,7 +145,15 @@ public class ClassPath {
for (String classType: tempClasses.keySet()) {
ClassDef classDef = ClassPath.loadClassDef(classType);
ClassDef classDef = null;
try {
classDef = ClassPath.loadClassDef(classType);
assert classDef != null;
} catch (Exception ex) {
System.err.println(String.format("Skipping %s", classType));
ex.printStackTrace(System.err);
}
if (classType.equals("Ljava/lang/Object;")) {
this.javaLangObjectClassDef = classDef;
}
@ -240,7 +248,7 @@ public class ClassPath {
* This method checks if the given class has been loaded yet. If it has, it returns the loaded ClassDef. If not,
* then it looks up the TempClassItem for the given class and (possibly recursively) loads the ClassDef.
* @param classType the class to load
* @return the existing or newly loaded ClassDef object for the given class
* @return the existing or newly loaded ClassDef object for the given class, or null if the class cannot be found
*/
private static ClassDef loadClassDef(String classType) {
ClassDef classDef = getClassDef(classType, false);
@ -248,7 +256,7 @@ public class ClassPath {
if (classDef == null) {
TempClassInfo classInfo = theClassPath.tempClasses.get(classType);
if (classInfo == null) {
throw new ExceptionWithContext(String.format("Could not find class %s", classType));
return null;
}
try {
@ -755,6 +763,9 @@ public class ClassPath {
}
ClassDef superclass = ClassPath.loadClassDef(superclassType);
if (superclass == null) {
throw new ClassNotFoundException(String.format("Could not find superclass %s", superclassType));
}
if (!isInterface && superclass.isInterface) {
throw new ValidationException("Class " + classType + " has the interface " + superclass.classType +
@ -787,6 +798,9 @@ public class ClassPath {
if (classInfo.interfaces != null) {
for (String interfaceType: classInfo.interfaces) {
ClassDef interfaceDef = ClassPath.loadClassDef(interfaceType);
if (interfaceDef == null) {
throw new ClassNotFoundException(String.format("Could not find interface %s", interfaceType));
}
assert interfaceDef.isInterface();
implementedInterfaceSet.add(interfaceDef);
@ -813,7 +827,7 @@ public class ClassPath {
if (!interfaceTable.containsKey(interfaceType)) {
ClassDef interfaceDef = ClassPath.loadClassDef(interfaceType);
if (interfaceDef == null) {
throw new ValidationException(String.format("Could not resolve type %s", interfaceType));
throw new ClassNotFoundException(String.format("Could not find interface %s", interfaceType));
}
interfaceTable.put(interfaceType, interfaceDef);