core: guard endless regions processing
This commit is contained in:
@@ -28,6 +28,7 @@ import jadx.core.utils.BlockUtils;
|
||||
import jadx.core.utils.ErrorsCounter;
|
||||
import jadx.core.utils.InstructionRemover;
|
||||
import jadx.core.utils.RegionUtils;
|
||||
import jadx.core.utils.exceptions.JadxOverflowException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
@@ -49,8 +50,12 @@ import static jadx.core.utils.BlockUtils.selectOther;
|
||||
public class RegionMaker {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RegionMaker.class);
|
||||
|
||||
// 'dumb' guard to prevent endless loop in regions processing
|
||||
private static final int REGIONS_LIMIT = 1000 * 1000;
|
||||
|
||||
private final MethodNode mth;
|
||||
private BitSet processedBlocks;
|
||||
private int regionsCount;
|
||||
|
||||
public RegionMaker(MethodNode mth) {
|
||||
this.mth = mth;
|
||||
@@ -68,6 +73,10 @@ public class RegionMaker {
|
||||
processedBlocks.set(id);
|
||||
}
|
||||
}
|
||||
regionsCount++;
|
||||
if (regionsCount > REGIONS_LIMIT) {
|
||||
throw new JadxOverflowException("Regions count limit reached");
|
||||
}
|
||||
|
||||
Region r = new Region(stack.peekRegion());
|
||||
BlockNode next = startBlock;
|
||||
|
||||
@@ -3,6 +3,7 @@ package jadx.core.dex.visitors.regions;
|
||||
import jadx.core.dex.nodes.BlockNode;
|
||||
import jadx.core.dex.nodes.IRegion;
|
||||
import jadx.core.dex.nodes.MethodNode;
|
||||
import jadx.core.utils.exceptions.JadxOverflowException;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Collection;
|
||||
@@ -17,6 +18,8 @@ final class RegionStack {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(RegionStack.class);
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private static final int REGIONS_STACK_LIMIT = 1000;
|
||||
|
||||
static {
|
||||
if (DEBUG) {
|
||||
LOG.debug("Debug enabled for {}", RegionStack.class);
|
||||
@@ -58,8 +61,8 @@ final class RegionStack {
|
||||
|
||||
public void push(IRegion region) {
|
||||
stack.push(curState);
|
||||
if (stack.size() > 1000) {
|
||||
throw new StackOverflowError("Deep code hierarchy");
|
||||
if (stack.size() > REGIONS_STACK_LIMIT) {
|
||||
throw new JadxOverflowException("Regions stack size limit reached");
|
||||
}
|
||||
curState = curState.copy();
|
||||
curState.region = region;
|
||||
|
||||
@@ -5,6 +5,7 @@ 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.HashSet;
|
||||
import java.util.Set;
|
||||
@@ -32,9 +33,9 @@ public class ErrorsCounter {
|
||||
errorsCount++;
|
||||
|
||||
if (e != null) {
|
||||
if (e.getClass() == StackOverflowError.class) {
|
||||
if (e.getClass() == JadxOverflowException.class) {
|
||||
// don't print full stack trace
|
||||
e = new StackOverflowError(e.getMessage());
|
||||
e = new JadxOverflowException(e.getMessage());
|
||||
LOG.error(msg);
|
||||
} else {
|
||||
LOG.error(msg, e);
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package jadx.core.utils.exceptions;
|
||||
|
||||
public class JadxOverflowException extends JadxRuntimeException {
|
||||
public JadxOverflowException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user