fix: unload attributes map if empty (#2433)
This commit is contained in:
@@ -32,6 +32,7 @@ jadx-output/
|
||||
*.jadx
|
||||
|
||||
*.class
|
||||
*.jar
|
||||
*.dump
|
||||
*.log
|
||||
*.cfg
|
||||
|
||||
@@ -12,7 +12,7 @@ import jadx.core.utils.Utils;
|
||||
|
||||
public abstract class AttrNode implements IAttributeNode {
|
||||
|
||||
private static final AttributeStorage EMPTY_ATTR_STORAGE = new EmptyAttrStorage();
|
||||
private static final AttributeStorage EMPTY_ATTR_STORAGE = EmptyAttrStorage.INSTANCE;
|
||||
|
||||
private AttributeStorage storage = EMPTY_ATTR_STORAGE;
|
||||
|
||||
@@ -35,6 +35,9 @@ public abstract class AttrNode implements IAttributeNode {
|
||||
|
||||
@Override
|
||||
public void addAttrs(List<IJadxAttribute> list) {
|
||||
if (list.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
initStorage().add(list);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,12 +18,19 @@ import jadx.core.utils.Utils;
|
||||
import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
|
||||
/**
|
||||
* Storage for different attribute types:
|
||||
* 1. flags - boolean attribute (set or not)
|
||||
* 2. attribute - class instance associated with attribute type.
|
||||
* Storage for different attribute types:<br>
|
||||
* 1. Flags - boolean attribute (set or not)<br>
|
||||
* 2. Attributes - class instance ({@link IJadxAttribute}) associated with an attribute type
|
||||
* ({@link IJadxAttrType})<br>
|
||||
*/
|
||||
public class AttributeStorage {
|
||||
|
||||
public static AttributeStorage fromList(List<IJadxAttribute> list) {
|
||||
AttributeStorage storage = new AttributeStorage();
|
||||
storage.add(list);
|
||||
return storage;
|
||||
}
|
||||
|
||||
static {
|
||||
int flagsCount = AFlag.values().length;
|
||||
if (flagsCount >= 64) {
|
||||
@@ -31,17 +38,14 @@ public class AttributeStorage {
|
||||
}
|
||||
}
|
||||
|
||||
private static final Map<IJadxAttrType<?>, IJadxAttribute> EMPTY_ATTRIBUTES = Collections.emptyMap();
|
||||
|
||||
private final Set<AFlag> flags;
|
||||
private Map<IJadxAttrType<?>, IJadxAttribute> attributes;
|
||||
|
||||
public AttributeStorage() {
|
||||
flags = EnumSet.noneOf(AFlag.class);
|
||||
attributes = Collections.emptyMap();
|
||||
}
|
||||
|
||||
public AttributeStorage(List<IJadxAttribute> attributesList) {
|
||||
this();
|
||||
add(attributesList);
|
||||
attributes = EMPTY_ATTRIBUTES;
|
||||
}
|
||||
|
||||
public void add(AFlag flag) {
|
||||
@@ -125,11 +129,14 @@ public class AttributeStorage {
|
||||
}
|
||||
|
||||
private void writeAttributes(Consumer<Map<IJadxAttrType<?>, IJadxAttribute>> mapConsumer) {
|
||||
if (attributes.isEmpty()) {
|
||||
attributes = new IdentityHashMap<>(5);
|
||||
}
|
||||
synchronized (this) {
|
||||
if (attributes == EMPTY_ATTRIBUTES) {
|
||||
attributes = new IdentityHashMap<>(2); // only 1 or 2 attributes added in most cases
|
||||
}
|
||||
mapConsumer.accept(attributes);
|
||||
if (attributes.isEmpty()) {
|
||||
attributes = EMPTY_ATTRIBUTES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,9 +144,7 @@ public class AttributeStorage {
|
||||
if (attributes.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
synchronized (this) {
|
||||
attributes.entrySet().removeIf(entry -> !entry.getValue().keepLoaded());
|
||||
}
|
||||
writeAttributes(map -> map.entrySet().removeIf(entry -> !entry.getValue().keepLoaded()));
|
||||
}
|
||||
|
||||
public List<String> getAttributeStrings() {
|
||||
|
||||
@@ -9,6 +9,12 @@ import jadx.api.plugins.input.data.attributes.IJadxAttribute;
|
||||
|
||||
public final class EmptyAttrStorage extends AttributeStorage {
|
||||
|
||||
public static final AttributeStorage INSTANCE = new EmptyAttrStorage();
|
||||
|
||||
private EmptyAttrStorage() {
|
||||
// singleton
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(AFlag flag) {
|
||||
return false;
|
||||
|
||||
@@ -185,16 +185,14 @@ public class Smali {
|
||||
smali.startLine(String.format("###### Class %s is created by jadx", cls.getFullName()));
|
||||
return;
|
||||
}
|
||||
AttributeStorage attributes = new AttributeStorage();
|
||||
attributes.add(clsData.getAttributes());
|
||||
|
||||
AttributeStorage clsAttributes = AttributeStorage.fromList(clsData.getAttributes());
|
||||
smali.startLine("Class: " + clsData.getType())
|
||||
.startLine("AccessFlags: " + AccessFlags.format(clsData.getAccessFlags(), AccessFlagsScope.CLASS))
|
||||
.startLine("SuperType: " + clsData.getSuperType())
|
||||
.startLine("Interfaces: " + clsData.getInterfacesTypes())
|
||||
.startLine("SourceFile: " + attributes.get(JadxAttrType.SOURCE_FILE));
|
||||
.startLine("SourceFile: " + clsAttributes.get(JadxAttrType.SOURCE_FILE));
|
||||
|
||||
AnnotationsAttr annotationsAttr = attributes.get(JadxAttrType.ANNOTATION_LIST);
|
||||
AnnotationsAttr annotationsAttr = clsAttributes.get(JadxAttrType.ANNOTATION_LIST);
|
||||
if (annotationsAttr != null) {
|
||||
Collection<IAnnotation> annos = annotationsAttr.getList();
|
||||
if (!annos.isEmpty()) {
|
||||
@@ -451,7 +449,8 @@ public class Smali {
|
||||
smali.add(')');
|
||||
smali.add(methodRef.getReturnType());
|
||||
|
||||
AnnotationsAttr annotationsAttr = new AttributeStorage(mth.getAttributes()).get(JadxAttrType.ANNOTATION_LIST);
|
||||
AttributeStorage mthAttributes = AttributeStorage.fromList(mth.getAttributes());
|
||||
AnnotationsAttr annotationsAttr = mthAttributes.get(JadxAttrType.ANNOTATION_LIST);
|
||||
if (annotationsAttr != null && !annotationsAttr.isEmpty()) {
|
||||
smali.incIndent();
|
||||
writeAnnotations(smali, annotationsAttr.getList());
|
||||
@@ -1074,7 +1073,7 @@ public class Smali {
|
||||
field.accessFlag = AccessFlags.format(f.getAccessFlags(), FIELD);
|
||||
field.name = f.getName();
|
||||
field.type = f.getType();
|
||||
field.attributes = new AttributeStorage(f.getAttributes());
|
||||
field.attributes = AttributeStorage.fromList(f.getAttributes());
|
||||
return field;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -1,11 +1,14 @@
|
||||
package jadx.api.plugins.input.data.attributes;
|
||||
|
||||
/**
|
||||
* Jadx attribute: custom data container, can be added to most jadx nodes.
|
||||
*/
|
||||
public interface IJadxAttribute {
|
||||
|
||||
IJadxAttrType<? extends IJadxAttribute> getAttrType();
|
||||
|
||||
/**
|
||||
* Mark type to skip unloading on node unload
|
||||
* Mark type to skip unloading on node unload event
|
||||
*/
|
||||
default boolean keepLoaded() {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user