mirror of
https://github.com/revanced/Apktool.git
synced 2024-12-12 05:47:46 +01:00
Make sure the elements are sorted in an encoded annotation
This commit is contained in:
parent
757e1dac45
commit
eb3b01f318
@ -55,7 +55,7 @@ public interface Annotation extends BasicAnnotation, Comparable<Annotation> {
|
|||||||
*
|
*
|
||||||
* @return The type of this annotation
|
* @return The type of this annotation
|
||||||
*/
|
*/
|
||||||
@Nonnull String getType();
|
@Nonnull @Override String getType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a set of the name/value elements associated with this annotation.
|
* Gets a set of the name/value elements associated with this annotation.
|
||||||
@ -64,7 +64,7 @@ public interface Annotation extends BasicAnnotation, Comparable<Annotation> {
|
|||||||
*
|
*
|
||||||
* @return A set of AnnotationElements
|
* @return A set of AnnotationElements
|
||||||
*/
|
*/
|
||||||
@Nonnull Set<? extends AnnotationElement> getElements();
|
@Nonnull @Override Set<? extends AnnotationElement> getElements();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a hashcode for this Annotation.
|
* Returns a hashcode for this Annotation.
|
||||||
|
@ -572,7 +572,6 @@ public abstract class DexWriter<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void writeAnnotationSets(@Nonnull DexDataWriter writer) throws IOException {
|
private void writeAnnotationSets(@Nonnull DexDataWriter writer) throws IOException {
|
||||||
writer.align();
|
writer.align();
|
||||||
annotationSetSectionOffset = writer.getPosition();
|
annotationSetSectionOffset = writer.getPosition();
|
||||||
|
@ -31,7 +31,9 @@
|
|||||||
|
|
||||||
package org.jf.dexlib2.writer;
|
package org.jf.dexlib2.writer;
|
||||||
|
|
||||||
|
import com.google.common.collect.Ordering;
|
||||||
import org.jf.dexlib2.ValueType;
|
import org.jf.dexlib2.ValueType;
|
||||||
|
import org.jf.dexlib2.base.BaseAnnotationElement;
|
||||||
import org.jf.dexlib2.iface.reference.FieldReference;
|
import org.jf.dexlib2.iface.reference.FieldReference;
|
||||||
import org.jf.dexlib2.iface.reference.MethodReference;
|
import org.jf.dexlib2.iface.reference.MethodReference;
|
||||||
|
|
||||||
@ -40,7 +42,8 @@ import java.io.IOException;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public abstract class EncodedValueWriter<StringKey, TypeKey, FieldRefKey extends FieldReference,
|
public abstract class EncodedValueWriter<StringKey, TypeKey, FieldRefKey extends FieldReference,
|
||||||
MethodRefKey extends MethodReference, AnnotationElement, EncodedValue> {
|
MethodRefKey extends MethodReference, AnnotationElement extends org.jf.dexlib2.iface.AnnotationElement,
|
||||||
|
EncodedValue> {
|
||||||
@Nonnull private final DexDataWriter writer;
|
@Nonnull private final DexDataWriter writer;
|
||||||
@Nonnull private final StringSection<StringKey, ?> stringSection;
|
@Nonnull private final StringSection<StringKey, ?> stringSection;
|
||||||
@Nonnull private final TypeSection<?, TypeKey, ?> typeSection;
|
@Nonnull private final TypeSection<?, TypeKey, ?> typeSection;
|
||||||
@ -70,7 +73,11 @@ public abstract class EncodedValueWriter<StringKey, TypeKey, FieldRefKey extends
|
|||||||
writer.writeEncodedValueHeader(ValueType.ANNOTATION, 0);
|
writer.writeEncodedValueHeader(ValueType.ANNOTATION, 0);
|
||||||
writer.writeUleb128(typeSection.getItemIndex(annotationType));
|
writer.writeUleb128(typeSection.getItemIndex(annotationType));
|
||||||
writer.writeUleb128(elements.size());
|
writer.writeUleb128(elements.size());
|
||||||
for (AnnotationElement element: elements) {
|
|
||||||
|
Collection<? extends AnnotationElement> sortedElements = Ordering.from(BaseAnnotationElement.BY_NAME)
|
||||||
|
.immutableSortedCopy(elements);
|
||||||
|
|
||||||
|
for (AnnotationElement element: sortedElements) {
|
||||||
writer.writeUleb128(stringSection.getItemIndex(annotationSection.getElementName(element)));
|
writer.writeUleb128(stringSection.getItemIndex(annotationSection.getElementName(element)));
|
||||||
writeEncodedValue(annotationSection.getElementValue(element));
|
writeEncodedValue(annotationSection.getElementValue(element));
|
||||||
}
|
}
|
||||||
|
@ -41,10 +41,12 @@ import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
|||||||
import org.jf.dexlib2.iface.Annotation;
|
import org.jf.dexlib2.iface.Annotation;
|
||||||
import org.jf.dexlib2.iface.AnnotationElement;
|
import org.jf.dexlib2.iface.AnnotationElement;
|
||||||
import org.jf.dexlib2.iface.ClassDef;
|
import org.jf.dexlib2.iface.ClassDef;
|
||||||
|
import org.jf.dexlib2.iface.value.AnnotationEncodedValue;
|
||||||
import org.jf.dexlib2.immutable.ImmutableAnnotation;
|
import org.jf.dexlib2.immutable.ImmutableAnnotation;
|
||||||
import org.jf.dexlib2.immutable.ImmutableAnnotationElement;
|
import org.jf.dexlib2.immutable.ImmutableAnnotationElement;
|
||||||
import org.jf.dexlib2.immutable.ImmutableClassDef;
|
import org.jf.dexlib2.immutable.ImmutableClassDef;
|
||||||
import org.jf.dexlib2.immutable.ImmutableDexFile;
|
import org.jf.dexlib2.immutable.ImmutableDexFile;
|
||||||
|
import org.jf.dexlib2.immutable.value.ImmutableAnnotationEncodedValue;
|
||||||
import org.jf.dexlib2.immutable.value.ImmutableNullEncodedValue;
|
import org.jf.dexlib2.immutable.value.ImmutableNullEncodedValue;
|
||||||
import org.jf.dexlib2.writer.io.MemoryDataStore;
|
import org.jf.dexlib2.writer.io.MemoryDataStore;
|
||||||
import org.jf.dexlib2.writer.pool.DexPool;
|
import org.jf.dexlib2.writer.pool.DexPool;
|
||||||
@ -87,4 +89,48 @@ public class DexWriterTest {
|
|||||||
Assert.assertEquals("blah", dbElements.get(0).getName());
|
Assert.assertEquals("blah", dbElements.get(0).getName());
|
||||||
Assert.assertEquals("zabaglione", dbElements.get(1).getName());
|
Assert.assertEquals("zabaglione", dbElements.get(1).getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEncodedAnnotationElementOrder() {
|
||||||
|
// Elements are out of order wrt to the element name
|
||||||
|
ImmutableSet<ImmutableAnnotationElement> encodedElements =
|
||||||
|
ImmutableSet.of(new ImmutableAnnotationElement("zabaglione", ImmutableNullEncodedValue.INSTANCE),
|
||||||
|
new ImmutableAnnotationElement("blah", ImmutableNullEncodedValue.INSTANCE));
|
||||||
|
|
||||||
|
ImmutableAnnotationEncodedValue encodedAnnotations =
|
||||||
|
new ImmutableAnnotationEncodedValue("Lan/encoded/annotation", encodedElements);
|
||||||
|
|
||||||
|
ImmutableSet<ImmutableAnnotationElement> elements =
|
||||||
|
ImmutableSet.of(new ImmutableAnnotationElement("encoded_annotation", encodedAnnotations));
|
||||||
|
|
||||||
|
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, false), dataStore.getData());
|
||||||
|
ClassDef dbClassDef = Iterables.getFirst(dexFile.getClasses(), null);
|
||||||
|
Assert.assertNotNull(dbClassDef);
|
||||||
|
Annotation dbAnnotation = Iterables.getFirst(dbClassDef.getAnnotations(), null);
|
||||||
|
Assert.assertNotNull(dbAnnotation);
|
||||||
|
|
||||||
|
AnnotationElement element = Iterables.getFirst(dbAnnotation.getElements(), null);
|
||||||
|
AnnotationEncodedValue dbAnnotationEncodedValue = (AnnotationEncodedValue)element.getValue();
|
||||||
|
|
||||||
|
List<AnnotationElement> dbElements = Lists.newArrayList(dbAnnotationEncodedValue.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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user