mirror of
https://github.com/revanced/smali.git
synced 2025-05-29 20:20:12 +02:00
Check for duplicate field/method definitions in ClassDataItem
This commit is contained in:
parent
0d2ce20ee4
commit
9c7c421f51
@ -33,9 +33,7 @@ import org.jf.dexlib.Util.*;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ClassDataItem extends Item<ClassDataItem> {
|
public class ClassDataItem extends Item<ClassDataItem> {
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -95,27 +93,71 @@ public class ClassDataItem extends Item<ClassDataItem> {
|
|||||||
EncodedMethod[] virtualMethodsArray = null;
|
EncodedMethod[] virtualMethodsArray = null;
|
||||||
|
|
||||||
if (staticFields != null && staticFields.size() > 0) {
|
if (staticFields != null && staticFields.size() > 0) {
|
||||||
staticFieldsArray = new EncodedField[staticFields.size()];
|
SortedSet<EncodedField> staticFieldsSet = new TreeSet<EncodedField>();
|
||||||
staticFieldsArray = staticFields.toArray(staticFieldsArray);
|
for (EncodedField staticField: staticFields) {
|
||||||
Arrays.sort(staticFieldsArray);
|
if (staticFieldsSet.contains(staticField)) {
|
||||||
|
System.err.println(String.format("Ignoring duplicate static field definition: %s",
|
||||||
|
staticField.field.getFieldString()));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
staticFieldsSet.add(staticField);
|
||||||
|
}
|
||||||
|
|
||||||
|
staticFieldsArray = new EncodedField[staticFieldsSet.size()];
|
||||||
|
staticFieldsArray = staticFieldsSet.toArray(staticFieldsArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instanceFields != null && instanceFields.size() > 0) {
|
if (instanceFields != null && instanceFields.size() > 0) {
|
||||||
instanceFieldsArray = new EncodedField[instanceFields.size()];
|
SortedSet<EncodedField> instanceFieldsSet = new TreeSet<EncodedField>();
|
||||||
instanceFieldsArray = instanceFields.toArray(instanceFieldsArray);
|
for (EncodedField instanceField: instanceFields) {
|
||||||
Arrays.sort(instanceFieldsArray);
|
if (instanceFieldsSet.contains(instanceField)) {
|
||||||
|
System.err.println(String.format("Ignoring duplicate instance field definition: %s",
|
||||||
|
instanceField.field.getFieldString()));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
instanceFieldsSet.add(instanceField);
|
||||||
|
}
|
||||||
|
|
||||||
|
instanceFieldsArray = new EncodedField[instanceFieldsSet.size()];
|
||||||
|
instanceFieldsArray = instanceFieldsSet.toArray(instanceFieldsArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TreeSet<EncodedMethod> directMethodSet = new TreeSet<EncodedMethod>();
|
||||||
|
|
||||||
if (directMethods != null && directMethods.size() > 0) {
|
if (directMethods != null && directMethods.size() > 0) {
|
||||||
directMethodsArray = new EncodedMethod[directMethods.size()];
|
for (EncodedMethod directMethod: directMethods) {
|
||||||
directMethodsArray = directMethods.toArray(directMethodsArray);
|
if (directMethodSet.contains(directMethod)) {
|
||||||
Arrays.sort(directMethodsArray);
|
System.err.println(String.format("Ignoring duplicate direct method definition: %s",
|
||||||
|
directMethod.method.getMethodString()));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
directMethodSet.add(directMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
directMethodsArray = new EncodedMethod[directMethodSet.size()];
|
||||||
|
directMethodsArray = directMethodSet.toArray(directMethodsArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virtualMethods != null && virtualMethods.size() > 0) {
|
if (virtualMethods != null && virtualMethods.size() > 0) {
|
||||||
virtualMethodsArray = new EncodedMethod[virtualMethods.size()];
|
TreeSet<EncodedMethod> virtualMethodSet = new TreeSet<EncodedMethod>();
|
||||||
virtualMethodsArray = virtualMethods.toArray(virtualMethodsArray);
|
for (EncodedMethod virtualMethod: virtualMethods) {
|
||||||
Arrays.sort(virtualMethodsArray);
|
if (directMethodSet.contains(virtualMethod)) {
|
||||||
|
// If both a direct and virtual definition is present, dalvik's behavior seems to be undefined,
|
||||||
|
// so we can't gracefully handle this case, like we can if the duplicates are all direct or all
|
||||||
|
// virtual -- in which case, we ignore all but the first definition
|
||||||
|
throw new RuntimeException(String.format("Duplicate direct+virtual method definition: %s",
|
||||||
|
virtualMethod.method.getMethodString()));
|
||||||
|
}
|
||||||
|
if (virtualMethodSet.contains(virtualMethod)) {
|
||||||
|
System.err.println(String.format("Ignoring duplicate virtual method definition: %s",
|
||||||
|
virtualMethod.method.getMethodString()));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
virtualMethodSet.add(virtualMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtualMethodsArray = new EncodedMethod[virtualMethodSet.size()];
|
||||||
|
virtualMethodsArray = virtualMethodSet.toArray(virtualMethodsArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassDataItem classDataItem = new ClassDataItem(dexFile, staticFieldsArray, instanceFieldsArray,
|
ClassDataItem classDataItem = new ClassDataItem(dexFile, staticFieldsArray, instanceFieldsArray,
|
||||||
@ -596,6 +638,19 @@ public class ClassDataItem extends Item<ClassDataItem> {
|
|||||||
return field.compareTo(other.field);
|
return field.compareTo(other.field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if this <code>EncodedField</code> is equal to other, based on the equality of the associated
|
||||||
|
* <code>FieldIdItem</code>
|
||||||
|
* @param other The <code>EncodedField</code> to test for equality
|
||||||
|
* @return true if other is equal to this instance, otherwise false
|
||||||
|
*/
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
if (other instanceof EncodedField) {
|
||||||
|
return compareTo((EncodedField)other) == 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if this is a static field
|
* @return true if this is a static field
|
||||||
*/
|
*/
|
||||||
@ -717,6 +772,19 @@ public class ClassDataItem extends Item<ClassDataItem> {
|
|||||||
return method.compareTo(other.method);
|
return method.compareTo(other.method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if this <code>EncodedMethod</code> is equal to other, based on the equality of the associated
|
||||||
|
* <code>MethodIdItem</code>
|
||||||
|
* @param other The <code>EncodedMethod</code> to test for equality
|
||||||
|
* @return true if other is equal to this instance, otherwise false
|
||||||
|
*/
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
if (other instanceof EncodedMethod) {
|
||||||
|
return compareTo((EncodedMethod)other) == 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if this is a direct method
|
* @return true if this is a direct method
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user