From c7ac851e97a1857308fe2050d5ebedd4cf3ca3c6 Mon Sep 17 00:00:00 2001 From: Matt Suiche Date: Wed, 2 Aug 2017 13:48:17 -0700 Subject: [PATCH] BUGFIX: Fix issue #11 which resulted in an infinite loop when walking through nodes to resolve orphan blocks. --- porosity/porosity/Contract.cpp | 18 ++++++++++++++---- porosity/porosity/Instruction.cpp | 4 ++++ porosity/porosity/PorosityDefs.h | 1 + 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/porosity/porosity/Contract.cpp b/porosity/porosity/Contract.cpp index 94a6c9d..26f8492 100644 --- a/porosity/porosity/Contract.cpp +++ b/porosity/porosity/Contract.cpp @@ -375,19 +375,29 @@ Contract::walkAndConnectNodes( // uint32_t next = _block; while (true) { - auto block = m_listbasicBlockInfo.find(next); + auto block = m_listbasicBlockInfo.find(next); // getBlockAt() if (block == m_listbasicBlockInfo.end()) break; + + if (block->second.walkedNode) break; + next = block->second.dstDefault; + // printf("hash = 0x%x, block = 0x%x, default = 0x%x, JUMPI = 0x%x\n", _hash, _block, block->second.dstDefault, block->second.dstJUMPI); if (block->second.dstJUMPI) { + block->second.walkedNode = true; walkAndConnectNodes(_hash, block->second.dstJUMPI); } if (!next) break; if (next == NODE_DEADEND) { - auto exitNode = m_exitNodesByHash.find(_hash); - block->second.dstDefault = exitNode->second; - block->second.nextDefault = getBlockAt(block->second.dstDefault); + auto exitNode = m_exitNodesByHash.find(_hash); // getBlockAt() + if (exitNode != m_exitNodesByHash.end()) { + block->second.dstDefault = exitNode->second; + } + + if (!block->second.nextDefault) { + block->second.nextDefault = getBlockAt(block->second.dstDefault); + } break; // next } } diff --git a/porosity/porosity/Instruction.cpp b/porosity/porosity/Instruction.cpp index ee14812..66d461c 100644 --- a/porosity/porosity/Instruction.cpp +++ b/porosity/porosity/Instruction.cpp @@ -189,6 +189,10 @@ void dev::eth::eachInstruction( size_t additional = 0; if (isValidInstruction(instr)) additional = instructionInfo(instr).additional; + else { + // printf("Invalid instruction. Aborting...\n"); + return; + } uint32_t offset = std::distance(_mem.begin(), it); u256 data; diff --git a/porosity/porosity/PorosityDefs.h b/porosity/porosity/PorosityDefs.h index 60b71ee..d4e9256 100644 --- a/porosity/porosity/PorosityDefs.h +++ b/porosity/porosity/PorosityDefs.h @@ -160,6 +160,7 @@ typedef struct _BasicBlockInfo string name; bool visited; + bool walkedNode; u256 dominators; ConditionAttribute condAttr;