Commit c4109142 authored by Skylot's avatar Skylot

core: skip finally extract visitor on error

parent a046f1ca
......@@ -34,4 +34,7 @@ public class DepthTraversal {
e.getClass().getSimpleName() + " in pass: " + visitor.getClass().getSimpleName(), e);
}
}
private DepthTraversal() {
}
}
package jadx.core.dex.visitors.blocksmaker;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.core.Jadx;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.AType;
import jadx.core.dex.attributes.nodes.IgnoreEdgeAttr;
......@@ -14,26 +29,15 @@ import jadx.core.dex.trycatch.ExceptionHandler;
import jadx.core.dex.trycatch.SplitterBlockAttr;
import jadx.core.dex.trycatch.TryCatchBlock;
import jadx.core.dex.visitors.AbstractVisitor;
import jadx.core.dex.visitors.DepthTraversal;
import jadx.core.dex.visitors.IDexTreeVisitor;
import jadx.core.dex.visitors.blocksmaker.helpers.BlocksPair;
import jadx.core.dex.visitors.blocksmaker.helpers.BlocksRemoveInfo;
import jadx.core.dex.visitors.ssa.LiveVarAnalysis;
import jadx.core.utils.BlockUtils;
import jadx.core.utils.ErrorsCounter;
import jadx.core.utils.exceptions.JadxRuntimeException;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static jadx.core.dex.visitors.blocksmaker.BlockSplitter.connect;
import static jadx.core.dex.visitors.blocksmaker.BlockSplitter.insertBlockBetween;
import static jadx.core.dex.visitors.blocksmaker.BlockSplitter.removeConnection;
......@@ -46,7 +50,7 @@ public class BlockFinallyExtract extends AbstractVisitor {
if (mth.isNoCode() || mth.isNoExceptionHandlers()) {
return;
}
try {
boolean reloadBlocks = false;
for (ExceptionHandler excHandler : mth.getExceptionHandlers()) {
if (processExceptionHandler(mth, excHandler)) {
......@@ -57,6 +61,24 @@ public class BlockFinallyExtract extends AbstractVisitor {
mergeReturnBlocks(mth);
BlockProcessor.rerun(mth);
}
} catch (Exception e) {
LOG.warn("Undo finally extract visitor, mth: {}", mth, e);
try {
// reload method without applying this visitor
// TODO: make more common and less hacky
mth.unload();
mth.load();
List<IDexTreeVisitor> passes = Jadx.getPassesList(mth.root().getArgs());
for (IDexTreeVisitor visitor : passes) {
if (visitor instanceof BlockFinallyExtract) {
break;
}
DepthTraversal.visit(visitor, mth);
}
} catch (Exception ee) {
LOG.error("Undo finally extract failed, mth: {}", mth, e);
}
}
}
private static boolean processExceptionHandler(MethodNode mth, ExceptionHandler excHandler) {
......@@ -495,6 +517,12 @@ public class BlockFinallyExtract extends AbstractVisitor {
LOG.warn("Finally extract failed: remBlock pred: {}, {}, method: {}", remBlock, remBlock.getPredecessors(), mth);
return false;
}
if (removeInfo.getOuts().isEmpty()) {
ErrorsCounter.methodError(mth, "Failed to extract finally block: empty outs");
return false;
}
// safe checks finished, altering blocks tree
// all error must throw exception to undo changes
BlockNode remBlockPred = remBlock.getPredecessors().get(0);
removeInfo.setStartPredecessor(remBlockPred);
......@@ -534,7 +562,11 @@ public class BlockFinallyExtract extends AbstractVisitor {
}
}
BlocksPair out = removeInfo.getOuts().iterator().next();
Set<BlocksPair> outs = removeInfo.getOuts();
if (outs.isEmpty()) {
throw new JadxRuntimeException("Failed to extract finally block: all outs is deleted");
}
BlocksPair out = outs.iterator().next();
BlockNode rOut = out.getFirst();
BlockNode sOut = out.getSecond();
......@@ -556,8 +588,7 @@ public class BlockFinallyExtract extends AbstractVisitor {
BlockNode pred = filtPreds.get(0);
BlockNode repl = removeInfo.getBySecond(pred);
if (repl == null) {
LOG.error("Block not found by {}, in {}, method: {}", pred, removeInfo, mth);
return false;
throw new JadxRuntimeException("Block not found by " + pred + ", in " + removeInfo);
}
removeConnection(pred, rOut);
addIgnoredEdge(repl, rOut);
......
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