You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
More 2.6, 2.7 control-flow bugs
Wasn't limiting exception clause to try finally. Probably still has bugs in try-finally nesting Add another 2.6/2.7 COME_FROM to try to limit if/end scope better
This commit is contained in:
@@ -126,6 +126,7 @@ class Python2Parser(PythonParser):
|
|||||||
assert_expr_and ::= assert_expr jmp_false expr
|
assert_expr_and ::= assert_expr jmp_false expr
|
||||||
|
|
||||||
ifstmt ::= testexpr _ifstmts_jump
|
ifstmt ::= testexpr _ifstmts_jump
|
||||||
|
ifstmt ::= testexpr return_if_stmts COME_FROM
|
||||||
|
|
||||||
testexpr ::= testfalse
|
testexpr ::= testfalse
|
||||||
testexpr ::= testtrue
|
testexpr ::= testtrue
|
||||||
@@ -144,6 +145,8 @@ class Python2Parser(PythonParser):
|
|||||||
|
|
||||||
ifelsestmtr ::= testexpr return_if_stmts return_stmts
|
ifelsestmtr ::= testexpr return_if_stmts return_stmts
|
||||||
|
|
||||||
|
ifelsestmtr ::= testexpr return_if_stmts COME_FROM return_stmts
|
||||||
|
|
||||||
ifelsestmtl ::= testexpr c_stmts_opt JUMP_BACK else_suitel
|
ifelsestmtl ::= testexpr c_stmts_opt JUMP_BACK else_suitel
|
||||||
|
|
||||||
|
|
||||||
|
@@ -61,7 +61,7 @@ class Python27Parser(Python2Parser):
|
|||||||
|
|
||||||
ret_and ::= expr JUMP_IF_FALSE_OR_POP ret_expr_or_cond COME_FROM
|
ret_and ::= expr JUMP_IF_FALSE_OR_POP ret_expr_or_cond COME_FROM
|
||||||
ret_or ::= expr JUMP_IF_TRUE_OR_POP ret_expr_or_cond COME_FROM
|
ret_or ::= expr JUMP_IF_TRUE_OR_POP ret_expr_or_cond COME_FROM
|
||||||
ret_cond ::= expr POP_JUMP_IF_FALSE expr RETURN_END_IF ret_expr_or_cond
|
ret_cond ::= expr POP_JUMP_IF_FALSE expr RETURN_END_IF COME_FROM ret_expr_or_cond
|
||||||
ret_cond_not ::= expr POP_JUMP_IF_TRUE expr RETURN_END_IF ret_expr_or_cond
|
ret_cond_not ::= expr POP_JUMP_IF_TRUE expr RETURN_END_IF ret_expr_or_cond
|
||||||
|
|
||||||
or ::= expr JUMP_IF_TRUE_OR_POP expr COME_FROM
|
or ::= expr JUMP_IF_TRUE_OR_POP expr COME_FROM
|
||||||
|
@@ -630,9 +630,16 @@ class Scanner2(scan.Scanner):
|
|||||||
# Now isolate the except and else blocks
|
# Now isolate the except and else blocks
|
||||||
end_else = start_else = self.get_target(self.prev[end])
|
end_else = start_else = self.get_target(self.prev[end])
|
||||||
|
|
||||||
|
|
||||||
|
end_finally_offset = end
|
||||||
|
while end_finally_offset < len(self.code):
|
||||||
|
if self.code[end_finally_offset] == self.opc.END_FINALLY:
|
||||||
|
break
|
||||||
|
end_finally_offset += self.op_size(code[end_finally_offset])
|
||||||
|
|
||||||
# Add the except blocks
|
# Add the except blocks
|
||||||
i = end
|
i = end
|
||||||
while i < len(self.code) and self.code[i] != self.opc.END_FINALLY:
|
while i < len(self.code) and i < end_finally_offset:
|
||||||
jmp = self.next_except_jump(i)
|
jmp = self.next_except_jump(i)
|
||||||
if jmp is None: # check
|
if jmp is None: # check
|
||||||
i = self.next_stmt[i]
|
i = self.next_stmt[i]
|
||||||
@@ -924,6 +931,7 @@ class Scanner2(scan.Scanner):
|
|||||||
'end': rtarget})
|
'end': rtarget})
|
||||||
self.thens[start] = rtarget
|
self.thens[start] = rtarget
|
||||||
if self.version == 2.7 or code[pre_rtarget+1] != self.opc.JUMP_FORWARD:
|
if self.version == 2.7 or code[pre_rtarget+1] != self.opc.JUMP_FORWARD:
|
||||||
|
self.fixed_jumps[offset] = rtarget
|
||||||
self.return_end_ifs.add(pre_rtarget)
|
self.return_end_ifs.add(pre_rtarget)
|
||||||
|
|
||||||
elif op in self.pop_jump_if_or_pop:
|
elif op in self.pop_jump_if_or_pop:
|
||||||
|
@@ -223,6 +223,7 @@ TABLE_DIRECT = {
|
|||||||
'elifstmt': ( '%|elif %c:\n%+%c%-', 0, 1 ),
|
'elifstmt': ( '%|elif %c:\n%+%c%-', 0, 1 ),
|
||||||
'elifelsestmt': ( '%|elif %c:\n%+%c%-%|else:\n%+%c%-', 0, 1, 3 ),
|
'elifelsestmt': ( '%|elif %c:\n%+%c%-%|else:\n%+%c%-', 0, 1, 3 ),
|
||||||
'ifelsestmtr': ( '%|if %c:\n%+%c%-%|else:\n%+%c%-', 0, 1, 2 ),
|
'ifelsestmtr': ( '%|if %c:\n%+%c%-%|else:\n%+%c%-', 0, 1, 2 ),
|
||||||
|
'ifelsestmtr2': ( '%|if %c:\n%+%c%-%|else:\n%+%c%-\n\n', 0, 1, 3 ), # has COME_FROM
|
||||||
'elifelsestmtr': ( '%|elif %c:\n%+%c%-%|else:\n%+%c%-\n\n', 0, 1, 2 ),
|
'elifelsestmtr': ( '%|elif %c:\n%+%c%-%|else:\n%+%c%-\n\n', 0, 1, 2 ),
|
||||||
|
|
||||||
'whileTruestmt': ( '%|while True:\n%+%c%-\n\n', 1 ),
|
'whileTruestmt': ( '%|while True:\n%+%c%-\n\n', 1 ),
|
||||||
|
@@ -723,11 +723,18 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
n_ifelsestmtc = n_ifelsestmtl = n_ifelsestmt
|
n_ifelsestmtc = n_ifelsestmtl = n_ifelsestmt
|
||||||
|
|
||||||
def n_ifelsestmtr(self, node):
|
def n_ifelsestmtr(self, node):
|
||||||
if len(node[2]) != 2:
|
if node[2] == 'COME_FROM':
|
||||||
|
return_stmts_node = node[3]
|
||||||
|
node.type = 'ifelsestmtr2'
|
||||||
|
else:
|
||||||
|
return_stmts_node = node[2]
|
||||||
|
if len(return_stmts_node) != 2:
|
||||||
self.default(node)
|
self.default(node)
|
||||||
|
|
||||||
if not (node[2][0][0][0] == 'ifstmt' and node[2][0][0][0][1][0] == 'return_if_stmts') \
|
if (not (return_stmts_node[0][0][0] == 'ifstmt'
|
||||||
and not (node[2][0][-1][0] == 'ifstmt' and node[2][0][-1][0][1][0] == 'return_if_stmts'):
|
and return_stmts_node[0][0][0][1][0] == 'return_if_stmts')
|
||||||
|
and not (return_stmts_node[0][-1][0] == 'ifstmt'
|
||||||
|
and return_stmts_node[0][-1][0][1][0] == 'return_if_stmts')):
|
||||||
self.default(node)
|
self.default(node)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -739,13 +746,14 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
self.indentLess()
|
self.indentLess()
|
||||||
|
|
||||||
if_ret_at_end = False
|
if_ret_at_end = False
|
||||||
if len(node[2][0]) >= 3:
|
if len(return_stmts_node[0]) >= 3:
|
||||||
if node[2][0][-1][0] == 'ifstmt' and node[2][0][-1][0][1][0] == 'return_if_stmts':
|
if (return_stmts_node[0][-1][0] == 'ifstmt'
|
||||||
|
and return_stmts_node[0][-1][0][1][0] == 'return_if_stmts'):
|
||||||
if_ret_at_end = True
|
if_ret_at_end = True
|
||||||
|
|
||||||
past_else = False
|
past_else = False
|
||||||
prev_stmt_is_if_ret = True
|
prev_stmt_is_if_ret = True
|
||||||
for n in node[2][0]:
|
for n in return_stmts_node[0]:
|
||||||
if (n[0] == 'ifstmt' and n[0][1][0] == 'return_if_stmts'):
|
if (n[0] == 'ifstmt' and n[0][1][0] == 'return_if_stmts'):
|
||||||
if prev_stmt_is_if_ret:
|
if prev_stmt_is_if_ret:
|
||||||
n[0].type = 'elifstmt'
|
n[0].type = 'elifstmt'
|
||||||
@@ -760,9 +768,10 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
if not past_else or if_ret_at_end:
|
if not past_else or if_ret_at_end:
|
||||||
self.println(self.indent, 'else:')
|
self.println(self.indent, 'else:')
|
||||||
self.indentMore()
|
self.indentMore()
|
||||||
self.preorder(node[2][1])
|
self.preorder(return_stmts_node[1])
|
||||||
self.indentLess()
|
self.indentLess()
|
||||||
self.prune()
|
self.prune()
|
||||||
|
n_ifelsestmtr2 = n_ifelsestmtr
|
||||||
|
|
||||||
def n_elifelsestmtr(self, node):
|
def n_elifelsestmtr(self, node):
|
||||||
if len(node[2]) != 2:
|
if len(node[2]) != 2:
|
||||||
|
Reference in New Issue
Block a user