diff --git a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java index fef28015..87a2ae6b 100644 --- a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java +++ b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/DexWriter.java @@ -31,11 +31,15 @@ package org.jf.dexlib2.writer; -import com.google.common.collect.*; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Ordering; import org.jf.dexlib2.AccessFlags; import org.jf.dexlib2.Opcode; import org.jf.dexlib2.ReferenceType; import org.jf.dexlib2.base.BaseAnnotation; +import org.jf.dexlib2.base.BaseAnnotationElement; import org.jf.dexlib2.builder.MutableMethodImplementation; import org.jf.dexlib2.builder.instruction.BuilderInstruction31c; import org.jf.dexlib2.dexbacked.raw.*; @@ -48,7 +52,10 @@ import org.jf.dexlib2.iface.instruction.Instruction; import org.jf.dexlib2.iface.instruction.OneRegisterInstruction; import org.jf.dexlib2.iface.instruction.ReferenceInstruction; import org.jf.dexlib2.iface.instruction.formats.*; -import org.jf.dexlib2.iface.reference.*; +import org.jf.dexlib2.iface.reference.FieldReference; +import org.jf.dexlib2.iface.reference.MethodReference; +import org.jf.dexlib2.iface.reference.StringReference; +import org.jf.dexlib2.iface.reference.TypeReference; import org.jf.dexlib2.util.InstructionUtil; import org.jf.dexlib2.util.MethodUtil; import org.jf.dexlib2.writer.io.DeferredOutputStream; @@ -81,7 +88,8 @@ public abstract class DexWriter< AnnotationKey extends Annotation, AnnotationSetKey, TypeListKey, FieldKey, MethodKey, - EncodedValue, AnnotationElement> { + EncodedValue, + AnnotationElement extends org.jf.dexlib2.iface.AnnotationElement> { public static final int NO_INDEX = -1; public static final int NO_OFFSET = 0; @@ -552,7 +560,9 @@ public abstract class DexWriter< writer.writeUbyte(annotationSection.getVisibility(key)); writer.writeUleb128(typeSection.getItemIndex(annotationSection.getType(key))); - Collection elements = annotationSection.getElements(key); + Collection elements = Ordering.from(BaseAnnotationElement.BY_NAME) + .immutableSortedCopy(annotationSection.getElements(key)); + writer.writeUleb128(elements.size()); for (AnnotationElement element: elements) { diff --git a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/DexPool.java b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/DexPool.java index 1febead5..d7f63922 100644 --- a/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/DexPool.java +++ b/brut.apktool.smali/dexlib2/src/main/java/org/jf/dexlib2/writer/pool/DexPool.java @@ -39,6 +39,7 @@ import org.jf.dexlib2.iface.Field; import org.jf.dexlib2.iface.reference.*; import org.jf.dexlib2.iface.value.*; import org.jf.dexlib2.writer.DexWriter; +import org.jf.dexlib2.writer.io.DexDataStore; import org.jf.dexlib2.writer.io.FileDataStore; import org.jf.dexlib2.writer.pool.ProtoPool.Key; import org.jf.util.ExceptionWithContext; @@ -82,6 +83,14 @@ public class DexPool extends DexWriter elements = + ImmutableSet.of(new ImmutableAnnotationElement("zabaglione", ImmutableNullEncodedValue.INSTANCE), + new ImmutableAnnotationElement("blah", ImmutableNullEncodedValue.INSTANCE)); + + ImmutableAnnotation annotation = new ImmutableAnnotation(AnnotationVisibility.RUNTIME, + "Lorg/test/anno;", elements); + + ImmutableClassDef classDef = new ImmutableClassDef("Lorg/test/blah;", + 0, "Ljava/lang/Object;", null, null, ImmutableSet.of(annotation), null, null); + + MemoryDataStore dataStore = new MemoryDataStore(); + + try { + DexPool.writeTo(dataStore, new ImmutableDexFile(ImmutableSet.of(classDef))); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + + DexBackedDexFile dexFile = new DexBackedDexFile(new Opcodes(15), dataStore.getData()); + ClassDef dbClassDef = Iterables.getFirst(dexFile.getClasses(), null); + Assert.assertNotNull(dbClassDef); + Annotation dbAnnotation = Iterables.getFirst(dbClassDef.getAnnotations(), null); + Assert.assertNotNull(dbAnnotation); + List dbElements = Lists.newArrayList(dbAnnotation.getElements()); + + // Ensure that the elements were written out in sorted order + Assert.assertEquals(2, dbElements.size()); + Assert.assertEquals("blah", dbElements.get(0).getName()); + Assert.assertEquals("zabaglione", dbElements.get(1).getName()); + } +}