mirror of
https://github.com/syssec-utd/pylingual.git
synced 2026-05-10 18:39:03 -07:00
Merge branch 'cflow-refactor' into cflow-refactor
This commit is contained in:
@@ -52,6 +52,8 @@ def edit_pyc_lines(pyc: PYCFile, src_lines: list[str]):
|
||||
line_insts[0].starts_line = lno
|
||||
for inst in line_insts[1:]:
|
||||
inst.starts_line = None
|
||||
if lno is not None and lno + 1 not in lno_bytecodes and pyc.version <= (3, 7) and src_lines[lno - 1].strip().startswith('@'):
|
||||
bc.instructions[line_insts[0].offset // 2 + 1].starts_line = lno + 1
|
||||
|
||||
|
||||
def run(file: Path, out_dir: Path, version: PythonVersion, print=False):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from ..cft import ControlFlowTemplate, EdgeKind, register_template
|
||||
from ..utils import T, N, defer_source_to, run_is, starting_instructions, to_indented_source, make_try_match, without_top_level_instructions
|
||||
from ..utils import T, N, defer_source_to, run_is, with_instructions, has_instval, starting_instructions, to_indented_source, make_try_match, without_top_level_instructions
|
||||
|
||||
|
||||
@register_template(1, 40)
|
||||
@@ -46,7 +46,7 @@ class IfThen(ControlFlowTemplate):
|
||||
class Assertion(ControlFlowTemplate):
|
||||
template = T(
|
||||
assertion=~N("fail", "tail"),
|
||||
fail=+N().with_cond(starting_instructions("LOAD_ASSERTION_ERROR")),
|
||||
fail=+N().with_cond(starting_instructions("LOAD_ASSERTION_ERROR"), has_instval("LOAD_GLOBAL", argval = "AssertionError")),
|
||||
tail=N.tail(),
|
||||
)
|
||||
|
||||
|
||||
@@ -295,6 +295,21 @@ class TryFinally3_11(ControlFlowTemplate):
|
||||
|
||||
return list(chain(s, self.line("finally:"), in_finally, after))
|
||||
|
||||
|
||||
|
||||
class Except3_9(ControlFlowTemplate):
|
||||
@classmethod
|
||||
@override
|
||||
def try_match(cls, cfg, node) -> ControlFlowTemplate | None:
|
||||
if [x.opname for x in node.get_instructions()] == ["RERAISE"]:
|
||||
return node
|
||||
if x := ExceptExc3_9.try_match(cfg, node):
|
||||
return x
|
||||
if x := BareExcept3_9.try_match(cfg, node):
|
||||
return x
|
||||
if isinstance(node, Except3_9):
|
||||
return node
|
||||
|
||||
|
||||
class Except3_9(ControlFlowTemplate):
|
||||
@classmethod
|
||||
@@ -531,7 +546,7 @@ class Except3_6(ControlFlowTemplate):
|
||||
@classmethod
|
||||
@override
|
||||
def try_match(cls, cfg, node) -> ControlFlowTemplate | None:
|
||||
if [x.opname for x in node.get_instructions()] == ["END_FINALLY"]:
|
||||
if [x.opname for x in node.get_instructions()[:1]] == ["END_FINALLY"]:
|
||||
return node
|
||||
if x := ExceptExc3_6.try_match(cfg, node):
|
||||
return x
|
||||
@@ -544,7 +559,7 @@ class Except3_6(ControlFlowTemplate):
|
||||
class Try3_6(ControlFlowTemplate):
|
||||
template = T(
|
||||
try_header=~N("try_body").with_cond(without_top_level_instructions("SETUP_WITH")),
|
||||
try_body=N("try_footer", None, "except_body"),
|
||||
try_body=N("try_footer.", None, "except_body"),
|
||||
try_footer=~N("tail."),
|
||||
except_body=~N("tail.").with_in_deg(1).of_subtemplate(Except3_6),
|
||||
tail=N.tail(),
|
||||
@@ -583,10 +598,10 @@ class ExcBody3_6(ControlFlowTemplate):
|
||||
|
||||
class NamedExc3_6(ExcBody3_6):
|
||||
template = T(
|
||||
header=~N("body", None).with_cond(starting_instructions("POP_TOP", "STORE_FAST"), with_instructions("POP_TOP", "STORE_NAME")),
|
||||
header=~N("body", None).with_cond(with_instructions("POP_TOP", "STORE_FAST"), with_instructions("POP_TOP", "STORE_NAME")),
|
||||
body=N("normal_cleanup.", None, "exception_cleanup"),
|
||||
normal_cleanup=~N("exception_cleanup."),
|
||||
exception_cleanup=~N("tail.").with_cond(with_instructions("LOAD_CONST", "STORE_FAST"), with_instructions("LOAD_CONST", "STORE_NAME")),
|
||||
exception_cleanup=~N("tail.").with_cond(with_instructions("STORE_FAST", "DELETE_FAST"), with_instructions("STORE_NAME", "DELETE_NAME")),
|
||||
tail=N.tail()
|
||||
)
|
||||
|
||||
@@ -694,7 +709,7 @@ class ReturnFinally3_6(ControlFlowTemplate):
|
||||
|
||||
class BareExcept3_6(Except3_6):
|
||||
template = T(
|
||||
except_body=~N("tail."),
|
||||
except_body=~N("tail.").with_cond(starting_instructions("POP_TOP", "POP_TOP", "POP_TOP")),
|
||||
tail=~N.tail(),
|
||||
)
|
||||
|
||||
@@ -763,4 +778,5 @@ class TryFinally3_6(ControlFlowTemplate):
|
||||
after = []
|
||||
|
||||
return list(chain(header, self.line("try:"), body, self.line("finally:"), in_finally, after))
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -118,6 +118,17 @@ def has_incoming_edge_of_categories(*categories: str):
|
||||
return False
|
||||
return check
|
||||
|
||||
|
||||
def has_instval(opname: str, argval : Any):
|
||||
def check_instructions(cfg: CFG, node: ControlFlowTemplate | None) -> bool:
|
||||
for x in node.get_instructions():
|
||||
if x.opname == opname and x.argval == argval:
|
||||
return True
|
||||
return False
|
||||
|
||||
return check_instructions
|
||||
|
||||
|
||||
def run_is(n: int):
|
||||
def check_run(cfg: CFG, node: ControlFlowTemplate | None) -> bool:
|
||||
return cfg.run == n
|
||||
|
||||
+410
-236
@@ -1,216 +1,11 @@
|
||||
def TryExcept():
|
||||
def a_TryExcept():
|
||||
try:
|
||||
print(1)
|
||||
except:
|
||||
print(2)
|
||||
print(3)
|
||||
|
||||
def TryExceptMulti():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
except b:
|
||||
print(3)
|
||||
except c:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def TryExceptMultiFallback():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
except b:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def TryExceptMultiNamed():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
except B as b:
|
||||
print(3)
|
||||
except C as c:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def TryExceptMultiNamedFallback():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
except B as b:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def TryExceptMultiNamedAndUnnamed():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
except b:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def TryExceptElseBare():
|
||||
try:
|
||||
print(1)
|
||||
except:
|
||||
print(2)
|
||||
else:
|
||||
print(3)
|
||||
print(4)
|
||||
|
||||
def TryExceptElseMulti():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
except b:
|
||||
print(3)
|
||||
else:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def TryExceptElseMultiFallback():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
except b:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
else:
|
||||
print(5)
|
||||
print(6)
|
||||
|
||||
def TryExceptElseNamed():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
except B as b:
|
||||
print(3)
|
||||
else:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def TryExceptElseMultiNamedAndUnnamed():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
except b:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
else:
|
||||
print(5)
|
||||
print(6)
|
||||
|
||||
def TryFinallyBare():
|
||||
try:
|
||||
print(1)
|
||||
finally:
|
||||
print(2)
|
||||
print(3)
|
||||
|
||||
def TryExceptFinallyBare():
|
||||
try:
|
||||
print(1)
|
||||
except:
|
||||
print(2)
|
||||
finally:
|
||||
print(3)
|
||||
print(4)
|
||||
|
||||
def TryExceptFinallyBareSpecific():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
finally:
|
||||
print(3)
|
||||
print(4)
|
||||
|
||||
def TryExceptMultiFinally():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
except b:
|
||||
print(3)
|
||||
finally:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def TryExceptMultiFallbackFinally():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
except:
|
||||
print(3)
|
||||
finally:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def TryExceptMultiNamedFinally():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
except B as b:
|
||||
print(3)
|
||||
finally:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def TryExceptMultiNamedFallbackFinally():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
except:
|
||||
print(3)
|
||||
finally:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def TryExceptMultiNamedAndUnnamedFinally():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
except b:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
finally:
|
||||
print(5)
|
||||
print(6)
|
||||
|
||||
def TryExceptElseFinallyBare():
|
||||
try:
|
||||
print(1)
|
||||
except:
|
||||
print(2)
|
||||
else:
|
||||
print(3)
|
||||
finally:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def TryExceptBareNested():
|
||||
def b_TryExceptBareNested():
|
||||
try:
|
||||
print(1)
|
||||
except:
|
||||
@@ -220,46 +15,41 @@ def TryExceptBareNested():
|
||||
except:
|
||||
print(4)
|
||||
|
||||
def TryExceptReturn():
|
||||
try:
|
||||
print(1)
|
||||
return 2
|
||||
except:
|
||||
print(2)
|
||||
|
||||
def TryExceptRaise():
|
||||
def b1_TryExceptBareNestedFallthrough():
|
||||
try:
|
||||
print(1)
|
||||
except:
|
||||
print(2)
|
||||
raise Exc
|
||||
|
||||
def TryExceptRaiseNamed():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
raise Exc
|
||||
|
||||
|
||||
def TryExceptBareNestedNamed():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
try:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def TryExceptReturnNamed():
|
||||
def b2_TryExceptBareNestedEarlyFallthrough():
|
||||
try:
|
||||
print(1)
|
||||
return 2
|
||||
except A as a:
|
||||
except:
|
||||
print(2)
|
||||
try:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def TryExceptBareNestedMulti():
|
||||
def b3_TryExceptBareNestedDoubleFallthrough():
|
||||
try:
|
||||
print(1)
|
||||
except:
|
||||
print(2)
|
||||
try:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
print(5)
|
||||
print(6)
|
||||
|
||||
def c_TryExceptBareMultiNested():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
@@ -275,7 +65,358 @@ def TryExceptBareNestedMulti():
|
||||
except:
|
||||
print(7)
|
||||
|
||||
def TryExceptReturnMulti():
|
||||
def c1_TryExceptBareMultiNestedFallthrough():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
try:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
print(5)
|
||||
except b:
|
||||
print(6)
|
||||
try:
|
||||
print(7)
|
||||
except:
|
||||
print(8)
|
||||
|
||||
def c2_TryExceptBareMultiNestedFallthrough2():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
try:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
print(5)
|
||||
except b:
|
||||
print(6)
|
||||
try:
|
||||
print(7)
|
||||
except:
|
||||
print(8)
|
||||
print(9)
|
||||
|
||||
def c3_TryExceptBareMultiNestedEarlyFallthrough():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
try:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
except b:
|
||||
print(5)
|
||||
try:
|
||||
print(6)
|
||||
except:
|
||||
print(7)
|
||||
print(8)
|
||||
|
||||
def c4_TryExceptBareMultiNestedAllFallthrough():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
try:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
print(5)
|
||||
except b:
|
||||
print(6)
|
||||
try:
|
||||
print(7)
|
||||
except:
|
||||
print(8)
|
||||
print(9)
|
||||
print(10)
|
||||
|
||||
def d_TryExceptBareNestedNamed():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
try:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
|
||||
def d1_TryExceptBareNestedNamedFallthrough():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
try:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def d2_TryExceptBareNestedNamedEarlyFallthrough():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
try:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def d3_TryExceptBareNestedNamedDoubleFallthrough():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
try:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
print(5)
|
||||
print(6)
|
||||
|
||||
def e_TryExceptElseBare():
|
||||
try:
|
||||
print(1)
|
||||
except:
|
||||
print(2)
|
||||
else:
|
||||
print(3)
|
||||
print(4)
|
||||
|
||||
def f_TryExceptElseFinallyBare():
|
||||
try:
|
||||
print(1)
|
||||
except:
|
||||
print(2)
|
||||
else:
|
||||
print(3)
|
||||
finally:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def g_TryExceptElseMulti():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
except b:
|
||||
print(3)
|
||||
else:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def h_TryExceptElseMultiFallback():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
except b:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
else:
|
||||
print(5)
|
||||
print(6)
|
||||
|
||||
def i_TryExceptElseMultiNamedAndUnnamed():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
except b:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
else:
|
||||
print(5)
|
||||
print(6)
|
||||
|
||||
def j_TryExceptElseNamed():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
except B as b:
|
||||
print(3)
|
||||
else:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def k_TryExceptFinallyBare():
|
||||
try:
|
||||
print(1)
|
||||
except:
|
||||
print(2)
|
||||
finally:
|
||||
print(3)
|
||||
print(4)
|
||||
|
||||
def l_TryExceptFinallyBareSpecific():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
finally:
|
||||
print(3)
|
||||
print(4)
|
||||
|
||||
def m_TryExceptMulti():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
except b:
|
||||
print(3)
|
||||
except c:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def n_TryExceptMultiFallback():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
except b:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def o_TryExceptMultiFallbackFinally():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
except:
|
||||
print(3)
|
||||
finally:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def p_TryExceptMultiNamed():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
except B as b:
|
||||
print(3)
|
||||
except C as c:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def q_TryExceptMultiNamedAndUnnamed():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
except b:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def r_TryExceptMultiNamedAndUnnamedFinally():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
except b:
|
||||
print(3)
|
||||
except:
|
||||
print(4)
|
||||
finally:
|
||||
print(5)
|
||||
print(6)
|
||||
|
||||
def s_TryExceptMultiNamedFallback():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
except:
|
||||
print(3)
|
||||
print(4)
|
||||
|
||||
def t_TryExceptMultiNamedFallbackFinally():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
except:
|
||||
print(3)
|
||||
finally:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def u_TryExceptMultiNamedFinally():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
except B as b:
|
||||
print(3)
|
||||
finally:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def v_TryExceptMultiFinally():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
except b:
|
||||
print(3)
|
||||
finally:
|
||||
print(4)
|
||||
print(5)
|
||||
|
||||
def w_TryExceptRaise():
|
||||
try:
|
||||
print(1)
|
||||
except:
|
||||
print(2)
|
||||
raise Exc
|
||||
|
||||
|
||||
def x_TryExceptRaiseMulti():
|
||||
try:
|
||||
print(1)
|
||||
except a:
|
||||
print(2)
|
||||
raise Exc
|
||||
except b:
|
||||
print(3)
|
||||
raise Exc
|
||||
|
||||
def y_TryExceptRaiseNamed():
|
||||
try:
|
||||
print(1)
|
||||
except A as a:
|
||||
print(2)
|
||||
raise Exc
|
||||
|
||||
def z_TryExceptReturn():
|
||||
try:
|
||||
print(1)
|
||||
return 2
|
||||
except:
|
||||
print(2)
|
||||
|
||||
def z1_TryExceptReturn():
|
||||
try:
|
||||
print(1)
|
||||
return 2
|
||||
except:
|
||||
print(2)
|
||||
return 3
|
||||
|
||||
def aa_TryExceptReturnMulti():
|
||||
try:
|
||||
print(1)
|
||||
return 2
|
||||
@@ -284,10 +425,21 @@ def TryExceptReturnMulti():
|
||||
except b:
|
||||
print(3)
|
||||
|
||||
def TryExceptRaiseMulti():
|
||||
def aa1_TryExceptReturnMulti():
|
||||
try:
|
||||
print(1)
|
||||
return 2
|
||||
except a:
|
||||
print(2)
|
||||
return 3
|
||||
except b:
|
||||
print(3)
|
||||
|
||||
def ab_TryExceptReturnNamed():
|
||||
try:
|
||||
print(1)
|
||||
return 2
|
||||
except A as a:
|
||||
print(2)
|
||||
raise Exc
|
||||
except b:
|
||||
@@ -382,3 +534,25 @@ def TryFinallyRaise():
|
||||
raise Exception()
|
||||
'''
|
||||
|
||||
|
||||
def ab1_TryExceptReturnNamed():
|
||||
try:
|
||||
print(1)
|
||||
return 2
|
||||
except A as a:
|
||||
print(2)
|
||||
return 3
|
||||
|
||||
def ac_TryFinallyBareFallthrough():
|
||||
try:
|
||||
print(1)
|
||||
finally:
|
||||
print(2)
|
||||
print(3)
|
||||
|
||||
def ad_TryFinallyBare():
|
||||
try:
|
||||
print(1)
|
||||
finally:
|
||||
print(2)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user