Commit 26aa5045 authored by Skylot's avatar Skylot

core: guard endless regions processing

parent e4dde3f4
...@@ -28,6 +28,7 @@ import jadx.core.utils.BlockUtils; ...@@ -28,6 +28,7 @@ import jadx.core.utils.BlockUtils;
import jadx.core.utils.ErrorsCounter; import jadx.core.utils.ErrorsCounter;
import jadx.core.utils.InstructionRemover; import jadx.core.utils.InstructionRemover;
import jadx.core.utils.RegionUtils; import jadx.core.utils.RegionUtils;
import jadx.core.utils.exceptions.JadxOverflowException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.BitSet; import java.util.BitSet;
...@@ -49,8 +50,12 @@ import static jadx.core.utils.BlockUtils.selectOther; ...@@ -49,8 +50,12 @@ import static jadx.core.utils.BlockUtils.selectOther;
public class RegionMaker { public class RegionMaker {
private static final Logger LOG = LoggerFactory.getLogger(RegionMaker.class); 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 final MethodNode mth;
private BitSet processedBlocks; private BitSet processedBlocks;
private int regionsCount;
public RegionMaker(MethodNode mth) { public RegionMaker(MethodNode mth) {
this.mth = mth; this.mth = mth;
...@@ -68,6 +73,10 @@ public class RegionMaker { ...@@ -68,6 +73,10 @@ public class RegionMaker {
processedBlocks.set(id); processedBlocks.set(id);
} }
} }
regionsCount++;
if (regionsCount > REGIONS_LIMIT) {
throw new JadxOverflowException("Regions count limit reached");
}
Region r = new Region(stack.peekRegion()); Region r = new Region(stack.peekRegion());
BlockNode next = startBlock; BlockNode next = startBlock;
......
...@@ -3,6 +3,7 @@ package jadx.core.dex.visitors.regions; ...@@ -3,6 +3,7 @@ package jadx.core.dex.visitors.regions;
import jadx.core.dex.nodes.BlockNode; import jadx.core.dex.nodes.BlockNode;
import jadx.core.dex.nodes.IRegion; import jadx.core.dex.nodes.IRegion;
import jadx.core.dex.nodes.MethodNode; import jadx.core.dex.nodes.MethodNode;
import jadx.core.utils.exceptions.JadxOverflowException;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Collection; import java.util.Collection;
...@@ -17,6 +18,8 @@ final class RegionStack { ...@@ -17,6 +18,8 @@ final class RegionStack {
private static final Logger LOG = LoggerFactory.getLogger(RegionStack.class); private static final Logger LOG = LoggerFactory.getLogger(RegionStack.class);
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
private static final int REGIONS_STACK_LIMIT = 1000;
static { static {
if (DEBUG) { if (DEBUG) {
LOG.debug("Debug enabled for {}", RegionStack.class); LOG.debug("Debug enabled for {}", RegionStack.class);
...@@ -58,8 +61,8 @@ final class RegionStack { ...@@ -58,8 +61,8 @@ final class RegionStack {
public void push(IRegion region) { public void push(IRegion region) {
stack.push(curState); stack.push(curState);
if (stack.size() > 1000) { if (stack.size() > REGIONS_STACK_LIMIT) {
throw new StackOverflowError("Deep code hierarchy"); throw new JadxOverflowException("Regions stack size limit reached");
} }
curState = curState.copy(); curState = curState.copy();
curState.region = region; curState.region = region;
......
...@@ -5,6 +5,7 @@ import jadx.core.dex.attributes.IAttributeNode; ...@@ -5,6 +5,7 @@ import jadx.core.dex.attributes.IAttributeNode;
import jadx.core.dex.attributes.nodes.JadxErrorAttr; import jadx.core.dex.attributes.nodes.JadxErrorAttr;
import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.MethodNode; import jadx.core.dex.nodes.MethodNode;
import jadx.core.utils.exceptions.JadxOverflowException;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
...@@ -32,9 +33,9 @@ public class ErrorsCounter { ...@@ -32,9 +33,9 @@ public class ErrorsCounter {
errorsCount++; errorsCount++;
if (e != null) { if (e != null) {
if (e.getClass() == StackOverflowError.class) { if (e.getClass() == JadxOverflowException.class) {
// don't print full stack trace // don't print full stack trace
e = new StackOverflowError(e.getMessage()); e = new JadxOverflowException(e.getMessage());
LOG.error(msg); LOG.error(msg);
} else { } else {
LOG.error(msg, e); LOG.error(msg, e);
......
package jadx.core.utils.exceptions;
public class JadxOverflowException extends JadxRuntimeException {
public JadxOverflowException(String message) {
super(message);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment