package jadx.core.utils;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.IAttributeNode;
import jadx.core.dex.attributes.nodes.JadxErrorAttr;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.utils.exceptions.JadxOverflowException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ErrorsCounter {
private static final Logger LOG = LoggerFactory.getLogger(ErrorsCounter.class);
private final Set<Object> errorNodes = new HashSet<Object>();
private int errorsCount;
public int getErrorCount() {
return errorsCount;
}
public void reset() {
errorNodes.clear();
errorsCount = 0;
}
private void addError(IAttributeNode node, String msg, Throwable e) {
errorNodes.add(node);
errorsCount++;
if (e != null) {
if (e.getClass() == JadxOverflowException.class) {
// don't print full stack trace
e = new JadxOverflowException(e.getMessage());
LOG.error(msg + ", message: " + e.getMessage());
} else {
LOG.error(msg, e);
}
node.addAttr(new JadxErrorAttr(e));
} else {
node.add(AFlag.INCONSISTENT_CODE);
LOG.error(msg);
}
}
public static String classError(ClassNode cls, String errorMsg, Throwable e) {
String msg = formatErrorMsg(cls, errorMsg);
cls.dex().root().getErrorsCounter().addError(cls, msg, e);
return msg;
}
public static String classError(ClassNode mth, String errorMsg) {
return classError(mth, errorMsg, null);
}
public static String methodError(MethodNode mth, String errorMsg, Throwable e) {
String msg = formatErrorMsg(mth, errorMsg);
mth.dex().root().getErrorsCounter().addError(mth, msg, e);
return msg;
}
public static String methodError(MethodNode mth, String errorMsg) {
return methodError(mth, errorMsg, null);
}
public void printReport() {
if (getErrorCount() > 0) {
LOG.error("{} errors occurred in following nodes:", getErrorCount());
List<Object> nodes = new ArrayList<Object>(errorNodes);
Collections.sort(nodes, new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
return String.valueOf(o1).compareTo(String.valueOf(o2));
}
});
for (Object node : nodes) {
String nodeName = node.getClass().getSimpleName().replace("Node", "");
LOG.error(" {}: {}", nodeName, node);
}
}
}
public static String formatErrorMsg(ClassNode cls, String msg) {
return msg + " in class: " + cls;
}
public static String formatErrorMsg(MethodNode mth, String msg) {
return msg + " in method: " + mth;
}
private String formatException(Throwable e) {
if (e == null || e.getMessage() == null) {
return "";
} else {
return "\n error: " + e.getMessage();
}
}
public String formatErrorMsg(ClassNode cls, String msg, Throwable e) {
return formatErrorMsg(cls, msg) + formatException(e);
}
public String formatErrorMsg(MethodNode mth, String msg, Throwable e) {
return formatErrorMsg(mth, msg) + formatException(e);
}
}