From 97e8a349064e321dff633ff9e16c0ab5df5e2b63 Mon Sep 17 00:00:00 2001 From: Skylot Date: Tue, 15 Feb 2022 12:29:30 +0000 Subject: [PATCH] fix: prevent some NPE in try/catch/finally processing (#1379) --- .../visitors/finaly/MarkFinallyVisitor.java | 6 +++++- .../main/java/jadx/core/utils/BlockUtils.java | 19 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/MarkFinallyVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/MarkFinallyVisitor.java index 1f280e15a..36d2ffc20 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/MarkFinallyVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/finaly/MarkFinallyVisitor.java @@ -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 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; diff --git a/jadx-core/src/main/java/jadx/core/utils/BlockUtils.java b/jadx-core/src/main/java/jadx/core/utils/BlockUtils.java index 1715c11a6..26482939b 100644 --- a/jadx-core/src/main/java/jadx/core/utils/BlockUtils.java +++ b/jadx-core/src/main/java/jadx/core/utils/BlockUtils.java @@ -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 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 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;