summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYohann Roussel <yroussel@google.com>2015-03-09 17:59:10 +0100
committerYohann Roussel <yroussel@google.com>2015-04-07 16:37:03 +0200
commit008da7d42d529761ab85b8e92d3dd366f1fad195 (patch)
treea1392d5f012d61f8628fd29f237339a6b61ae19c
parent45e4d877614b194e24afbb90024130fd4e3156f5 (diff)
downloadandroid_dalvik-008da7d42d529761ab85b8e92d3dd366f1fad195.tar.gz
android_dalvik-008da7d42d529761ab85b8e92d3dd366f1fad195.tar.bz2
android_dalvik-008da7d42d529761ab85b8e92d3dd366f1fad195.zip
Descriptor references are direct references
We have to parse descriptors and treat the types they reference as direct reference as we do for other direct type references. This is required because Dalvik verifier is checking those descriptor the same way as it does for other type references. See: https://android.googlesource.com/platform/dalvik/+/kitkat-mr2.2-release/vm/analysis/CodeVerify.cpp#637 Bug: 19626444 (cherry picked from commit 8f9fb34f2d53beb22ad9055eb071a93157b922ba) Change-Id: Ib9f43dd0c5f0b983fcc80e13caa13fd8b2dc2244
-rw-r--r--dx/src/com/android/multidex/ClassReferenceListBuilder.java44
1 files changed, 30 insertions, 14 deletions
diff --git a/dx/src/com/android/multidex/ClassReferenceListBuilder.java b/dx/src/com/android/multidex/ClassReferenceListBuilder.java
index 0434cad98..8218693c9 100644
--- a/dx/src/com/android/multidex/ClassReferenceListBuilder.java
+++ b/dx/src/com/android/multidex/ClassReferenceListBuilder.java
@@ -19,7 +19,11 @@ package com.android.multidex;
import com.android.dx.cf.direct.DirectClassFile;
import com.android.dx.rop.cst.Constant;
import com.android.dx.rop.cst.ConstantPool;
+import com.android.dx.rop.cst.CstFieldRef;
+import com.android.dx.rop.cst.CstMethodRef;
import com.android.dx.rop.cst.CstType;
+import com.android.dx.rop.type.Prototype;
+import com.android.dx.rop.type.StdTypeList;
import com.android.dx.rop.type.Type;
import com.android.dx.rop.type.TypeList;
@@ -37,8 +41,8 @@ import java.util.zip.ZipFile;
public class ClassReferenceListBuilder {
private static final String CLASS_EXTENSION = ".class";
- private Path path;
- private Set<String> classNames = new HashSet<String>();
+ private final Path path;
+ private final Set<String> classNames = new HashSet<String>();
public ClassReferenceListBuilder(Path path) {
this.path = path;
@@ -96,23 +100,35 @@ public class ClassReferenceListBuilder {
private void addDependencies(ConstantPool pool) {
for (Constant constant : pool.getEntries()) {
if (constant instanceof CstType) {
- Type type = ((CstType) constant).getClassType();
- String descriptor = type.getDescriptor();
- if (descriptor.endsWith(";")) {
- int lastBrace = descriptor.lastIndexOf('[');
- if (lastBrace < 0) {
- addClassWithHierachy(descriptor.substring(1, descriptor.length()-1));
- } else {
- assert descriptor.length() > lastBrace + 3
- && descriptor.charAt(lastBrace + 1) == 'L';
- addClassWithHierachy(descriptor.substring(lastBrace + 2,
- descriptor.length() - 1));
- }
+ checkDescriptor(((CstType) constant).getClassType());
+ } else if (constant instanceof CstFieldRef) {
+ checkDescriptor(((CstFieldRef) constant).getType());
+ } else if (constant instanceof CstMethodRef) {
+ Prototype proto = ((CstMethodRef) constant).getPrototype();
+ checkDescriptor(proto.getReturnType());
+ StdTypeList args = proto.getParameterTypes();
+ for (int i = 0; i < args.size(); i++) {
+ checkDescriptor(args.get(i));
}
}
}
}
+ private void checkDescriptor(Type type) {
+ String descriptor = type.getDescriptor();
+ if (descriptor.endsWith(";")) {
+ int lastBrace = descriptor.lastIndexOf('[');
+ if (lastBrace < 0) {
+ addClassWithHierachy(descriptor.substring(1, descriptor.length()-1));
+ } else {
+ assert descriptor.length() > lastBrace + 3
+ && descriptor.charAt(lastBrace + 1) == 'L';
+ addClassWithHierachy(descriptor.substring(lastBrace + 2,
+ descriptor.length() - 1));
+ }
+ }
+ }
+
private void addClassWithHierachy(String classBinaryName) {
if (classNames.contains(classBinaryName)) {
return;