fix: prevent some NPE in try/catch/finally processing (#1379)

This commit is contained in:
Skylot
2022-02-15 12:29:30 +00:00
parent 82f3b57e83
commit 97e8a34906
2 changed files with 23 additions and 2 deletions
@@ -154,7 +154,11 @@ public class MarkFinallyVisitor extends AbstractVisitor {
// remove 'finally' from 'try' blocks, check all up paths on each exit (connected with finally exit)
List<BlockNode> tryBlocks = allHandler.getTryBlock().getBlocks();
BlockNode bottomFinallyBlock = BlockUtils.followEmptyPath(BlockUtils.getBottomBlock(allHandler.getBlocks()));
BlockNode bottomBlock = BlockUtils.getBottomBlock(allHandler.getBlocks());
if (bottomBlock == null) {
return false;
}
BlockNode bottomFinallyBlock = BlockUtils.followEmptyPath(bottomBlock);
BlockNode bottom = BlockUtils.getNextBlock(bottomFinallyBlock);
if (bottom == null) {
return false;
@@ -35,6 +35,7 @@ import jadx.core.dex.nodes.IBlock;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.regions.conditions.IfCondition;
import jadx.core.dex.trycatch.ExceptionHandler;
import jadx.core.utils.exceptions.JadxRuntimeException;
public class BlockUtils {
@@ -382,6 +383,7 @@ public class BlockUtils {
/**
* Return first successor which not exception handler and not follow loop back edge
*/
@Nullable
public static BlockNode getNextBlock(BlockNode block) {
List<BlockNode> s = block.getCleanSuccessors();
return s.isEmpty() ? null : s.get(0);
@@ -594,6 +596,7 @@ public class BlockUtils {
/**
* Search last block in control flow graph from input set.
*/
@Nullable
public static BlockNode getBottomBlock(List<BlockNode> blocks) {
if (blocks.size() == 1) {
return blocks.get(0);
@@ -701,7 +704,7 @@ public class BlockUtils {
mth.getLoops().forEach(l -> excluded.set(l.getStart().getId()));
if (!mth.isNoExceptionHandlers()) {
// exclude exception handlers paths
mth.getExceptionHandlers().forEach(h -> excluded.or(h.getHandlerBlock().getDomFrontier()));
mth.getExceptionHandlers().forEach(h -> mergeExcHandlerDomFrontier(mth, h, excluded));
}
domFrontBS.andNot(excluded);
oneBlock = bitSetToOneBlock(mth, domFrontBS);
@@ -738,6 +741,20 @@ public class BlockUtils {
}
}
private static void mergeExcHandlerDomFrontier(MethodNode mth, ExceptionHandler handler, BitSet set) {
BlockNode handlerBlock = handler.getHandlerBlock();
if (handlerBlock == null) {
mth.addDebugComment("Null handler block in: " + handler);
return;
}
BitSet domFrontier = handlerBlock.getDomFrontier();
if (domFrontier == null) {
mth.addDebugComment("Null dom frontier in handler: " + handler);
return;
}
set.or(domFrontier);
}
public static BlockNode getPathCross(MethodNode mth, BlockNode b1, BlockNode b2) {
if (b1 == b2) {
return b1;