Fix for Dalvik VM crash on parameter annotations

Dalvik VM before Jelly Bean MR1 (4.2) crashes if there are any
NO_OFFSET (0) values in parameter annotation list.
(https://code.google.com/p/android/issues/detail?id=35304)
This commit is contained in:
Jiri Hruska 2015-02-19 02:59:41 +01:00 committed by Connor Tumbleson
parent 2abcd59cbe
commit 9450cc915c

View File

@ -576,6 +576,9 @@ public abstract class DexWriter<
private void writeAnnotationSets(@Nonnull DexDataWriter writer) throws IOException {
writer.align();
annotationSetSectionOffset = writer.getPosition();
if (shouldCreateEmptyAnnotationSet()) {
writer.writeInt(0);
}
for (Map.Entry<? extends AnnotationSetKey, Integer> entry: annotationSetSection.getItems()) {
Collection<? extends AnnotationKey> annotations = Ordering.from(BaseAnnotation.BY_TYPE)
.immutableSortedCopy(annotationSetSection.getAnnotations(entry.getKey()));
@ -613,6 +616,8 @@ public abstract class DexWriter<
for (AnnotationSetKey annotationSetKey: parameterAnnotations) {
if (annotationSetSection.getAnnotations(annotationSetKey).size() > 0) {
writer.writeInt(annotationSetSection.getItemOffset(annotationSetKey));
} else if (shouldCreateEmptyAnnotationSet()) {
writer.writeInt(annotationSetSectionOffset);
} else {
writer.writeInt(NO_OFFSET);
}
@ -1115,7 +1120,7 @@ public abstract class DexWriter<
if (annotationSection.getItems().size() > 0) {
numItems++;
}
if (annotationSetSection.getItems().size() > 0) {
if (annotationSetSection.getItems().size() > 0 || shouldCreateEmptyAnnotationSet()) {
numItems++;
}
if (numAnnotationSetRefItems > 0) {
@ -1163,8 +1168,8 @@ public abstract class DexWriter<
writeMapItem(writer, ItemType.TYPE_LIST, typeListSection.getItems().size(), typeListSectionOffset);
writeMapItem(writer, ItemType.ENCODED_ARRAY_ITEM, numEncodedArrayItems, encodedArraySectionOffset);
writeMapItem(writer, ItemType.ANNOTATION_ITEM, annotationSection.getItems().size(), annotationSectionOffset);
writeMapItem(writer, ItemType.ANNOTATION_SET_ITEM, annotationSetSection.getItems().size(),
annotationSetSectionOffset);
writeMapItem(writer, ItemType.ANNOTATION_SET_ITEM,
annotationSetSection.getItems().size() + (shouldCreateEmptyAnnotationSet() ? 1 : 0), annotationSetSectionOffset);
writeMapItem(writer, ItemType.ANNOTATION_SET_REF_LIST, numAnnotationSetRefItems, annotationSetRefSectionOffset);
writeMapItem(writer, ItemType.ANNOTATION_DIRECTORY_ITEM, numAnnotationDirectoryItems,
annotationDirectorySectionOffset);
@ -1226,4 +1231,11 @@ public abstract class DexWriter<
writer.writeInt(0);
}
}
private boolean shouldCreateEmptyAnnotationSet() {
// Workaround for a crash in Dalvik VM before Jelly Bean MR1 (4.2)
// which is triggered by NO_OFFSET in parameter annotation list.
// (https://code.google.com/p/android/issues/detail?id=35304)
return (api < 17);
}
}