예제 #1
0
    def structureSingleLoop(self, n):
        '''
        @return: True, if loop was structured, False otherwise.

        '''
        (loope, ALe) = self.findLoopALEdge(n)
        (loop, AL) = (self.nodes[loope.toNode], self.nodes[ALe.toNode])
        if loop.forloop:
            (forloope, AFe) = self.findForAFEdge(loop)
            forloop = self.nodes[forloope.toNode]
            AF = self.nodes[AFe.toNode]
            if len(forloop.outgoing) == 1 and \
               forloop.outgoing[0].toNode == AF.name and \
               len(AF.outgoing) == 1 and AF.outgoing[0].toNode == AL.name:
                forloop.code = indentForText(forloop.code)
                if AF.code != '':
                    AF.code = 'else:\n' + indentText(AF.code, 1)
                self.removeEdge(loop, AF)
                self.removeEdge(n, AL)
                return True
        else:
            (te, fe) = self.findTrueFalseEdge(loop)
            (tn, fn) = (self.nodes[te.toNode], self.nodes[fe.toNode])
            if len(tn.outgoing) == 1 and tn.outgoing[0].toNode == fn.name and \
               len(fn.outgoing) == 1 and fn.outgoing[0].toNode == AL.name:
                loop.code = 'while ' + str(loop.condition) + ':\n'
                if tn.code == '': tn.code = 'pass\n'
                tn.code = indentText(tn.code, 1)
                if fn.code != '':
                    fn.code = 'else:\n' + indentText(fn.code, 1)
                self.removeEdge(loop, fn)
                self.removeEdge(n, AL)
                return True
예제 #2
0
    def mergeCompoundNodes(self, head, x, y, latch):
        '''
        Merges two nodes in if/else construction.

        @param x: first (higher) node.
        @param y: second (lower) node.

        '''
        # TODO: add optimization for latch node to avoid simplifyConsecutive
        if y is None or y.code == '':
            if x.code == '': x.code = 'pass\n'
            if isinstance(head.condition, CompareOp) and \
               head.condition.value == 'EXC_MATCH':
                code = head.code + 'except ' + \
                       str(head.condition.children[1]) + indentExText(x.code)
            else:
                code = head.code + 'if ' + \
                       str(head.condition) + ':\n' + indentText(x.code, 1)
                #+ '\n' + latch.code
            n = node(head.name,
                     head.incoming,
                     x.outgoing,
                     conditional=False,
                     code=code,
                     offset=head.offset)
        else:
            if x.code == '': x.code = 'pass\n'
            if y.code == '': y.code = 'pass\n'
            if isinstance(head.condition, CompareOp) and \
               head.condition.value == 'EXC_MATCH':
                if y.conditional:
                    code = head.code + 'except ' + \
                           str(head.condition.children[1]) + \
                           indentExText(x.code) + y.code
                else:
                    code = head.code + 'except ' + \
                           str(head.condition.children[1]) + \
                           indentExText(x.code) + \
                           'except:\n' + indentText(y.code, 1)
            else:
                code = head.code + 'if ' + str(head.condition) + ':\n' + \
                       indentText(x.code, 1) + \
                       'else:\n' + indentText(y.code, 1)# + '\n' + latch.code
            n = node(head.name,
                     head.incoming,
                     x.outgoing,
                     conditional=False,
                     code=code,
                     offset=head.offset)

        self.nodes[head.name] = n
        self.updateEdges(x.name, head.name)
        if y is not None: self.updateEdges(y.name, head.name)
        del self.nodes[x.name]  #, self.nodes[latch.name])
        if y is not None: del self.nodes[y.name]
예제 #3
0
    def structureSingleLoop(self, n):
        '''
        @return: True, if loop was structured, False otherwise.

        '''
        #THIS ONLY WORKS IF optimizeJumps = True
        self.extra.append(n)
        #print "N: ",n 
        (loope, ALe) = self.findLoopALEdge(n)
        #print "LOOPE: %s"%(loope)
        #print "ALe: %s"%(ALe)
        (loop, AL) = (self.nodes[loope.toNode], self.nodes[ALe.toNode])
        #print "LOOP: %s"%(loop)
        #print "AL: %s"%(AL)
        
        #Rich mod change test condition to look for t/f edges not loop property
        
        if loop.forloop:
            
            (forloope, AFe) = self.findForAFEdge(loop)
            forloop = self.nodes[forloope.toNode]
            AF = self.nodes[AFe.toNode]
            #if len(forloop.outgoing) == 1 and \
            #   forloop.outgoing[0].toNode == AF.name and \
            #   len(AF.outgoing) == 1 and AF.outgoing[0].toNode == AL.name:
            if 1:
                
                forloop.code = indentForText(forloop.code)
                if AF.code != '':
                    AF.code = 'else:\n' + indentText(AF.code, 1)
                    
                
                self.removeEdge(loop, AF)
                self.removeEdge(n, AL)
                return True
        else:
            try:
                (te, fe) = self.findTrueFalseEdge(loop)
                (tn, fn) = (self.nodes[te.toNode], self.nodes[fe.toNode])
                if len(tn.outgoing) == 1 and tn.outgoing[0].toNode == fn.name and \
                   len(fn.outgoing) == 1 and fn.outgoing[0].toNode == AL.name:
                    loop.code = 'while ' + str(loop.condition) + ':\n'
                    if tn.code == '': tn.code = 'pass\n'
                    tn.code = indentText(tn.code, 1)
                    if fn.code != '':
                        fn.code = 'else:\n' + indentText(fn.code, 1)
                    self.removeEdge(loop, fn)
                    self.removeEdge(n, AL)
                    return True
            except Exception, err:
                print "[X] Rich exception caught", err
                traceback.print_exc()
                return False
예제 #4
0
    def structureSingleLoop(self, n):
        '''
        @return: True, if loop was structured, False otherwise.

        '''
        #THIS ONLY WORKS IF optimizeJumps = True
        self.extra.append(n)
        #print "N: ",n
        (loope, ALe) = self.findLoopALEdge(n)
        #print "LOOPE: %s"%(loope)
        #print "ALe: %s"%(ALe)
        (loop, AL) = (self.nodes[loope.toNode], self.nodes[ALe.toNode])
        #print "LOOP: %s"%(loop)
        #print "AL: %s"%(AL)

        #Rich mod change test condition to look for t/f edges not loop property

        if loop.forloop:

            (forloope, AFe) = self.findForAFEdge(loop)
            forloop = self.nodes[forloope.toNode]
            AF = self.nodes[AFe.toNode]
            #if len(forloop.outgoing) == 1 and \
            #   forloop.outgoing[0].toNode == AF.name and \
            #   len(AF.outgoing) == 1 and AF.outgoing[0].toNode == AL.name:
            if 1:

                forloop.code = indentForText(forloop.code)
                if AF.code != '':
                    AF.code = 'else:\n' + indentText(AF.code, 1)

                self.removeEdge(loop, AF)
                self.removeEdge(n, AL)
                return True
        else:
            try:
                (te, fe) = self.findTrueFalseEdge(loop)
                (tn, fn) = (self.nodes[te.toNode], self.nodes[fe.toNode])
                if len(tn.outgoing) == 1 and tn.outgoing[0].toNode == fn.name and \
                   len(fn.outgoing) == 1 and fn.outgoing[0].toNode == AL.name:
                    loop.code = 'while ' + str(loop.condition) + ':\n'
                    if tn.code == '': tn.code = 'pass\n'
                    tn.code = indentText(tn.code, 1)
                    if fn.code != '':
                        fn.code = 'else:\n' + indentText(fn.code, 1)
                    self.removeEdge(loop, fn)
                    self.removeEdge(n, AL)
                    return True
            except Exception, err:
                print "[X] Rich exception caught", err
                traceback.print_exc()
                return False
예제 #5
0
    def structureSingleLoop(self, n):
        '''
        @return: True, if loop was structured, False otherwise.

        '''
        (loope, ALe) = self.findLoopALEdge(n)
        (loop, AL) = (self.nodes[loope.toNode], self.nodes[ALe.toNode])
        if loop.forloop:
            (forloope, AFe) = self.findForAFEdge(loop)
            forloop = self.nodes[forloope.toNode]
            AF = self.nodes[AFe.toNode]
            if len(forloop.outgoing) == 1 and \
               forloop.outgoing[0].toNode == AF.name and \
               len(AF.outgoing) == 1 and AF.outgoing[0].toNode == AL.name:
                forloop.code = indentForText(forloop.code)
                if AF.code != '':
                    AF.code = 'else:\n' + indentText(AF.code, 1)
                self.removeEdge(loop, AF)
                self.removeEdge(n, AL)
                return True
            elif len(forloop.outgoing) == 1 and \
               forloop.outgoing[0].toNode == AF.name and \
               AF.name == AL.name:
                forloop.code = indentForText(forloop.code)
                self.removeEdge(loop, AF)
                self.removeEdge(n, AL)
                return True

        else:
            (te, fe) = self.findTrueFalseEdge(loop)
            (tn, fn) = (self.nodes[te.toNode], self.nodes[fe.toNode])
            if len(tn.outgoing) == 1 and tn.outgoing[0].toNode == fn.name and \
               len(fn.outgoing) == 1 and fn.outgoing[0].toNode == AL.name:
                loop.code = 'while ' + str(loop.condition) + ':\n'
                if tn.code == '': tn.code = 'pass\n'
                tn.code = indentText(tn.code, 1)
                if fn.code != '':
                    fn.code = 'else:\n' + indentText(fn.code, 1)
                self.removeEdge(loop, fn)
                self.removeEdge(n, AL)
                return True
            elif len(tn.outgoing) == 1 and tn.outgoing[0].toNode == fn.name and \
                 fn.name == AL.name:
                loop.code = 'while ' + str(loop.condition) + ':\n'
                if tn.code == '': tn.code = 'pass\n'
                tn.code = indentText(tn.code, 1)
                self.removeEdge(loop, fn)
                self.removeEdge(n, AL)
                return True
예제 #6
0
    def decompile(self, offset=0, startIndent=0):
        '''Entry point for the decompilation process.'''
        try:
            cb = self.disassembler.getAllCodeBlocks(offset)
            print "[+] All code blocks got"
            flowGraph = structure.getGraphFromCodeBlocks(cb, self.debugDraw)
            print "[+] Flow graph from code blocks got"
            flowGraph.DFADecompile(self)
            print "[+] DFA decompiled"
            flowGraph.simplifyComplexIFs()
            print "[+] Complex IF's simplified"
            flowGraph.preprocessWhileLoops()
            print "[+] WHILE loops preprocessed"
            flowGraph.simplifyAllCompound()
            print "[+] All compounds simplified"
            flowGraph.simplifyConsecutive()
            print "[+] Consecutives simplified"
            if len(flowGraph.nodes) == 1:
                r = flowGraph.nodes[flowGraph.root].code
            else:
                print "\n\n"
                print "!!!INCOMPLETE DISASSEMBLY!!!!"
                print "%d code block uncoalesced" % len(flowGraph.nodes)
                #r = '>>> Fatal error: could not structure control flow graph.'
                r = ""
                ordered_nodes = flowGraph.nodes.keys()
                ordered_nodes.sort()
                for n in ordered_nodes:
                    if len(flowGraph.nodes[n].code) == 0:
                        continue
                    r += "#[NODE: %s]\n%s\n" % (n, flowGraph.nodes[n].code)

            return indentText(r, startIndent)
        except:
            traceback.print_exc()
예제 #7
0
 def str(self, depth=0):
     dis = disasm.Disassembler(self)
     ind = indent(depth + 1)
     
     r = indent(depth, self.offset) + 'CODE:\n' + \
         ind + 'argcount:\n%s\n' % self.argcount.str(depth + 2) + \
         ind + 'nlocals:\n%s\n' % self.nlocals.str(depth + 2) + \
         ind + 'stacksize:\n%s\n' % self.stacksize.str(depth + 2) + \
         ind + 'flags:\n%s\n' % self.flags.str(depth + 2) + \
         indent(depth + 2) + '(' + \
         ', '.join([opcodes.flags[f]
                    for f in opcodes.flags
                    if f & self.flags.value]) + ')\n' + \
         ind + 'code:\n%s\n' % self.code.str(depth + 2) + \
         indentText(dis.codeDisasm(verbose=self.verboseDisasm,
                                   xref=self.xrefDisasm), depth + 2) + \
         ind + 'consts:\n%s\n' % self.consts.str(depth + 2) + \
         ind + 'names:\n%s\n' % self.names.str(depth + 2) + \
         ind + 'varnames:\n%s\n' % self.varnames.str(depth + 2) + \
         ind + 'freevars:\n%s\n' % self.freevars.str(depth + 2) + \
         ind + 'cellvars:\n%s\n' % self.cellvars.str(depth + 2) + \
         ind + 'filename:\n%s\n' % self.filename.str(depth + 2) + \
         ind + 'name:\n%s\n' % self.name.str(depth + 2) + \
         ind + 'firslineno:\n%s\n' % self.firstlineno.str(depth + 2) + \
         ind + 'lnotab:\n%s\n' % self.lnotab.str(depth + 2)
     
     return r
예제 #8
0
    def mergeCompoundNodes(self, head, x, y, latch):
        '''
        Merges two nodes in if/else construction.

        @param x: first (higher) node.
        @param y: second (lower) node.

        '''
        # TODO: add optimization for latch node to avoid simplifyConsecutive
        if y is None or y.code == '':
            if x.code == '': x.code = 'pass\n'
            if isinstance(head.condition, CompareOp) and \
               head.condition.value == 'EXC_MATCH':
                code = head.code + 'except ' + \
                       str(head.condition.children[1]) + indentExText(x.code)
            else:
                code = head.code + 'if ' + \
                       str(head.condition) + ':\n' + indentText(x.code, 1)
                       #+ '\n' + latch.code
            n = node(head.name, head.incoming, x.outgoing,
                     conditional=False, code=code, offset=head.offset)
        else:
            if x.code == '': x.code = 'pass\n'
            if y.code == '': y.code = 'pass\n'
            if isinstance(head.condition, CompareOp) and \
               head.condition.value == 'EXC_MATCH':
                if y.conditional:
                    code = head.code + 'except ' + \
                           str(head.condition.children[1]) + \
                           indentExText(x.code) + y.code
                else:
                    code = head.code + 'except ' + \
                           str(head.condition.children[1]) + \
                           indentExText(x.code) + \
                           'except:\n' + indentText(y.code, 1)
            else:
                code = head.code + 'if ' + str(head.condition) + ':\n' + \
                       indentText(x.code, 1) + \
                       'else:\n' + indentText(y.code, 1)# + '\n' + latch.code
            n = node(head.name, head.incoming, x.outgoing,
                     conditional=False, code=code, offset=head.offset)

        self.nodes[head.name] = n
        self.updateEdges(x.name, head.name)
        if y is not None: self.updateEdges(y.name, head.name)
        del self.nodes[x.name] #, self.nodes[latch.name])
        if y is not None: del self.nodes[y.name]
예제 #9
0
    def structureSingleFinally(self, n):
        '''
        @return: True, if finally was structured, False otherwise.

        '''
        changes = False
        (ASFe, ASF2e, finallye) = self.findASFASF2finallyEdge(n)
        if ASFe is not None:
            # it is a try-finally case
            ASFn = self.nodes[ASFe.toNode]
            finallyn = self.nodes[finallye.toNode]
            # check if everything is structured...
            if len(ASFn.outgoing) == 1 and \
               ASFn.outgoing[0].toNode == finallyn.name and \
               len(finallyn.outgoing) == 1 and \
               finallyn.outgoing[0].type == 'AE':
                if ASFn.code == '':
                    ASFn.code = 'pass\n'
                ASFn.code = 'try:\n' + indentText(ASFn.code, 1)
                if finallyn.code == '':
                    finallyn.code = 'pass\n'
                finallyn.code = 'finally:\n' + indentText(finallyn.code, 1)
                self.removeEdge(n, finallyn)
                latch = self.nodes[finallyn.outgoing[0].toNode]
                self.removeEdge(finallyn, latch)  # remove AE
                self.addEdge(finallyn, latch)
                changes = True
        elif ASF2e is not None:
            # it is a try-except-(else)-finally case
            ASFn = self.nodes[ASF2e.toNode]
            finallyn = self.nodes[finallye.toNode]
            # check if everything is structured...
            # TODO: remove copypaste
            if len(ASFn.outgoing) == 1 and \
               ASFn.outgoing[0].toNode == finallyn.name and \
               len(finallyn.outgoing) == 1 and \
               finallyn.outgoing[0].type == 'AE':
                if finallyn.code == '':
                    finallyn.code = 'pass\n'
                finallyn.code = 'finally:\n' + indentText(finallyn.code, 1)
                self.removeEdge(n, finallyn)
                latch = self.nodes[finallyn.outgoing[0].toNode]
                self.removeEdge(finallyn, latch)  # remove AE
                self.addEdge(finallyn, latch)
                changes = True
        return changes
예제 #10
0
    def structureSingleFinally(self, n):
        '''
        @return: True, if finally was structured, False otherwise.

        '''
        changes = False
        (ASFe, ASF2e, finallye) = self.findASFASF2finallyEdge(n)
        if ASFe is not None:
            # it is a try-finally case
            ASFn = self.nodes[ASFe.toNode]
            finallyn = self.nodes[finallye.toNode]
            # check if everything is structured...
            if len(ASFn.outgoing) == 1 and \
               ASFn.outgoing[0].toNode == finallyn.name and \
               len(finallyn.outgoing) == 1 and \
               finallyn.outgoing[0].type == 'AE':
                if ASFn.code == '':
                    ASFn.code = 'pass\n'
                ASFn.code = 'try:\n' + indentText(ASFn.code, 1)
                if finallyn.code == '':
                    finallyn.code = 'pass\n'
                finallyn.code = 'finally:\n' + indentText(finallyn.code, 1)
                self.removeEdge(n, finallyn)
                latch = self.nodes[finallyn.outgoing[0].toNode]
                self.removeEdge(finallyn, latch) # remove AE
                self.addEdge(finallyn, latch)
                changes = True
        elif ASF2e is not None:
            # it is a try-except-(else)-finally case
            ASFn = self.nodes[ASF2e.toNode]
            finallyn = self.nodes[finallye.toNode]
            # check if everything is structured...
            # TODO: remove copypaste
            if len(ASFn.outgoing) == 1 and \
               ASFn.outgoing[0].toNode == finallyn.name and \
               len(finallyn.outgoing) == 1 and \
               finallyn.outgoing[0].type == 'AE':
                if finallyn.code == '':
                    finallyn.code = 'pass\n'
                finallyn.code = 'finally:\n' + indentText(finallyn.code, 1)
                self.removeEdge(n, finallyn)
                latch = self.nodes[finallyn.outgoing[0].toNode]
                self.removeEdge(finallyn, latch) # remove AE
                self.addEdge(finallyn, latch)
                changes = True
        return changes
예제 #11
0
    def decompile(self, offset=0, startIndent=0, full=True):
        '''Entry point for the decompilation process.'''

        if not full:
            co = self.disassembler.co
            func = NewFunction(co)
            r = self.STORE(co.name.value, func, startIndent, True)
            return indentText(r, startIndent)
        else:
            cb = self.disassembler.getAllCodeBlocks(offset)
            flowGraph = structure.getGraphFromCodeBlocks(cb, self.debugDraw)
            flowGraph.DFADecompile(self)
            flowGraph.simplifyComplexIFs()
            flowGraph.preprocessWhileLoops()
            flowGraph.simplifyAllCompound()
            flowGraph.simplifyConsecutive()
            if len(flowGraph.nodes) == 1:
                r = flowGraph.nodes[flowGraph.root].code
            else:
                raise StructuringErrorException()
                #r = '>>> Fatal error: could not structure control flow graph.'
            return indentText(r, startIndent)
예제 #12
0
    def decompile(self, offset=0, startIndent=0, full=True):
        '''Entry point for the decompilation process.'''

        if not full:
            co = self.disassembler.co
            func = NewFunction(co)
            r = self.STORE(co.name.value, func, startIndent, True)
            return indentText(r, startIndent)
        else:
            cb = self.disassembler.getAllCodeBlocks(offset)
            flowGraph = structure.getGraphFromCodeBlocks(cb, self.debugDraw)
            flowGraph.DFADecompile(self)
            flowGraph.simplifyComplexIFs()
            flowGraph.preprocessWhileLoops()
            flowGraph.simplifyAllCompound()
            flowGraph.simplifyConsecutive()
            if len(flowGraph.nodes) == 1:
                r = flowGraph.nodes[flowGraph.root].code
            else:
                raise StructuringErrorException()
                #r = '>>> Fatal error: could not structure control flow graph.'
            return indentText(r, startIndent)
예제 #13
0
 def decompile(self, offset=0, startIndent=0):
     '''Entry point for the decompilation process.'''
     cb = self.disassembler.getAllCodeBlocks(offset)
     flowGraph = structure.getGraphFromCodeBlocks(cb, self.debugDraw)
     flowGraph.DFADecompile(self)
     flowGraph.simplifyComplexIFs()
     flowGraph.preprocessWhileLoops()
     flowGraph.simplifyAllCompound()
     flowGraph.simplifyConsecutive()
     if len(flowGraph.nodes) == 1:
         r = flowGraph.nodes[flowGraph.root].code
     else:
         # TODO: throw exception
         r = '>>> Fatal error: could not structure control flow graph.'
     return indentText(r, startIndent)
예제 #14
0
 def decompile(self, offset=0, startIndent=0):
     '''Entry point for the decompilation process.'''
     try:
         cb = self.disassembler.getAllCodeBlocks(offset)
         print "[+] All code blocks got"
         flowGraph = structure.getGraphFromCodeBlocks(cb, self.debugDraw)
         print "[+] Flow graph from code blocks got"
         flowGraph.DFADecompile(self)
         print "[+] DFA decompiled"
         flowGraph.simplifyComplexIFs()
         print "[+] Complex IF's simplified"
         flowGraph.preprocessWhileLoops()
         print "[+] WHILE loops preprocessed"
         flowGraph.simplifyAllCompound()
         print "[+] All compounds simplified"
         flowGraph.simplifyConsecutive()
         print "[+] Consecutives simplified"
         if len(flowGraph.nodes) == 1:
             r = flowGraph.nodes[flowGraph.root].code
         else:
             print "\n\n"
             print "!!!INCOMPLETE DISASSEMBLY!!!!"
             print "%d code block uncoalesced"%len(flowGraph.nodes)
             #r = '>>> Fatal error: could not structure control flow graph.'
             r=""
             ordered_nodes=flowGraph.nodes.keys()
             ordered_nodes.sort()
             for n in ordered_nodes:
                 if len(flowGraph.nodes[n].code) == 0:
                     continue
                 r += "#[NODE: %s]\n%s\n"%(n, flowGraph.nodes[n].code)
             
            
         return indentText(r, startIndent)
     except:
         traceback.print_exc()
예제 #15
0
    def structureSingleExcept(self, n):
        '''
        @return: True, if except was structured, False otherwise.

        '''
        changes = False
        # T - try, E - except, F - finally
        # t - true, f - false
        # e - edge, n - node
        # c - child
        (Te, Ee) = self.findTryExceptEdge(n)
        (Tn, En) = (self.nodes[Te.toNode], self.nodes[Ee.toNode])
        tn = self.nodes[Ee.toNode]
        fn = self.nodes[Ee.toNode]
        (te, fe) = self.findTrueFalseEdge(fn)
        while fe is not None:
            (tn, fn) = (self.nodes[te.toNode], self.nodes[fe.toNode])
            (te, fe) = self.findTrueFalseEdge(fn)

        if tn.name != fn.name and len(tn.outgoing) == 1 and \
           len(fn.outgoing) == 1 and len(fn.incoming) == 1 and \
           fn.code == '':
            pn = self.nodes[fn.incoming[0].fromNode]
            self.removeEdge(pn, fn)
            self.addEdge(pn, self.nodes[tn.outgoing[0].toNode], 'f')
            changes = True

        if tn.name == fn.name:
            if not tn.code.startswith('except ') and \
               not tn.code.startswith('except:'):
                if tn.code == '': tn.code = 'pass\n'
                tn.code = 'except:\n' + indentText(tn.code, 1)
                changes = True

        # check if try block is structured
        TisOK = False
        if len(Tn.outgoing) == 1:
            Tnc = self.nodes[Tn.outgoing[0].toNode]
            for e in Tnc.incoming:
                if e.type == 'AE':
                    TisOK = True
                    break

        # find else block
        elsen = None
        if TisOK:
            if len(tn.outgoing) == 1 and \
               Tn.outgoing[0].toNode == tn.outgoing[0].toNode:
                elsen = None
            else:
                elsen = self.nodes[Tn.outgoing[0].toNode]

        # check if else block is structured
        elseisOK = False
        if TisOK:
            if elsen is None:
                elseisOK = True
            elif len(elsen.outgoing) == 1 and len(tn.outgoing) == 1 and \
                 elsen.outgoing[0].toNode == tn.outgoing[0].toNode:
                elseisOK = True

        # check if except block is structured
        EisOK = False
        if TisOK and elseisOK:
            # TODO: separate method
            for index in xrange(len(n.incoming)):
                if n.incoming[index].type == 'ASF':
                    n.incoming[index].type = 'ASF2'
                    pn = self.nodes[n.incoming[index].fromNode]
                    for index2 in xrange(len(pn.outgoing)):
                        if pn.outgoing[index2].type == 'ASF' and \
                           pn.outgoing[index2].toNode == n.name:
                            pn.outgoing[index2].type = 'ASF2'
                    changes = True
            if elsen is not None and len(En.outgoing) == 1 and \
               En.outgoing[0].toNode == elsen.outgoing[0].toNode:
                if Tn.code == '': Tn.code = 'pass\n'
                Tn.code = 'try:\n' + indentText(Tn.code, 1)
                if elsen.code == '': elsen.code = 'pass\n'
                elsen.code = 'else:\n' + indentText(elsen.code, 1)
                self.removeEdge(n, En)
                self.removeEdge(En, self.nodes[En.outgoing[0].toNode])
                self.removeEdge(Tn, elsen)
                dummyname = elsen.incoming[0].fromNode
                self.removeEdge(self.nodes[dummyname], elsen)
                del self.nodes[dummyname]
                self.addEdge(Tn, En)
                self.addEdge(En, elsen)
                changes = True
            elif elsen is None and len(En.outgoing) == 1 and \
                 En.outgoing[0].toNode == Tn.outgoing[0].toNode:
                latch = self.nodes[En.outgoing[0].toNode]
                if Tn.code == '': Tn.code = 'pass\n'
                Tn.code = 'try:\n' + indentText(Tn.code, 1)
                self.removeEdge(n, En)
                self.removeEdge(Tn, latch)
                for index in xrange(len(latch.incoming)):
                    if latch.incoming[index].type == 'AE':
                        dummyname = latch.incoming[index].fromNode
                        self.removeEdge(self.nodes[dummyname], latch)
                        del self.nodes[dummyname]
                        break
                self.addEdge(Tn, En)
                changes = True
        return changes
예제 #16
0
    def structureSingleExcept(self, n):
        '''
        @return: True, if except was structured, False otherwise.

        '''
        changes = False
        # T - try, E - except, F - finally
        # t - true, f - false
        # e - edge, n - node
        # c - child
        (Te, Ee) = self.findTryExceptEdge(n)
        (Tn, En) = (self.nodes[Te.toNode], self.nodes[Ee.toNode])
        tn = self.nodes[Ee.toNode]
        fn = self.nodes[Ee.toNode]
        (te, fe) = self.findTrueFalseEdge(fn)
        while fe is not None:
            (tn, fn) = (self.nodes[te.toNode], self.nodes[fe.toNode])
            (te, fe) = self.findTrueFalseEdge(fn)

        if tn.name != fn.name and len(tn.outgoing) == 1 and \
           len(fn.outgoing) == 1 and len(fn.incoming) == 1 and \
           fn.code == '':
            pn = self.nodes[fn.incoming[0].fromNode]
            self.removeEdge(pn, fn)
            self.addEdge(pn, self.nodes[tn.outgoing[0].toNode], 'f')
            changes = True

        if tn.name == fn.name:
            if not tn.code.startswith('except ') and \
               not tn.code.startswith('except:'):
                if tn.code == '': tn.code = 'pass\n'
                tn.code = 'except:\n' + indentText(tn.code, 1)
                changes = True

        # check if try block is structured
        TisOK = False
        if len(Tn.outgoing) == 1:
            Tnc = self.nodes[Tn.outgoing[0].toNode]
            for e in Tnc.incoming:
                if e.type == 'AE':
                    TisOK = True
                    break

        # find else block
        elsen = None
        if TisOK:
            if len(tn.outgoing) == 1 and \
               Tn.outgoing[0].toNode == tn.outgoing[0].toNode:
                elsen = None
            else:
                elsen = self.nodes[Tn.outgoing[0].toNode]

        # check if else block is structured
        elseisOK = False
        if TisOK:
            if elsen is None:
                elseisOK = True
            elif len(elsen.outgoing) == 1 and len(tn.outgoing) == 1 and \
                 elsen.outgoing[0].toNode == tn.outgoing[0].toNode:
                elseisOK = True

        # check if except block is structured
        EisOK = False
        if TisOK and elseisOK:
            # TODO: separate method
            for index in xrange(len(n.incoming)):
                if n.incoming[index].type == 'ASF':
                    n.incoming[index].type = 'ASF2'
                    pn = self.nodes[n.incoming[index].fromNode]
                    for index2 in xrange(len(pn.outgoing)):
                        if pn.outgoing[index2].type == 'ASF' and \
                           pn.outgoing[index2].toNode == n.name:
                            pn.outgoing[index2].type = 'ASF2'
                    changes = True
            if elsen is not None and len(En.outgoing) == 1 and \
               En.outgoing[0].toNode == elsen.outgoing[0].toNode:
                if Tn.code == '': Tn.code = 'pass\n'
                Tn.code = 'try:\n' + indentText(Tn.code, 1)
                if elsen.code == '': elsen.code = 'pass\n'
                elsen.code = 'else:\n' + indentText(elsen.code, 1)
                self.removeEdge(n, En)
                self.removeEdge(En, self.nodes[En.outgoing[0].toNode])
                self.removeEdge(Tn, elsen)
                dummyname = elsen.incoming[0].fromNode
                self.removeEdge(self.nodes[dummyname], elsen)
                del self.nodes[dummyname]
                self.addEdge(Tn, En)
                self.addEdge(En, elsen)
                changes = True
            elif elsen is None and len(En.outgoing) == 1 and \
                 En.outgoing[0].toNode == Tn.outgoing[0].toNode:
                latch = self.nodes[En.outgoing[0].toNode]
                if Tn.code == '': Tn.code = 'pass\n'
                Tn.code = 'try:\n' + indentText(Tn.code, 1)
                self.removeEdge(n, En)
                self.removeEdge(Tn, latch)
                for index in xrange(len(latch.incoming)):
                    if latch.incoming[index].type == 'AE':
                        dummyname = latch.incoming[index].fromNode
                        self.removeEdge(self.nodes[dummyname], latch)
                        del self.nodes[dummyname]
                        break
                self.addEdge(Tn, En)
                changes = True
        return changes