CFG with try-catch blocks is missing some code
Closed this issue ยท 3 comments
Hi,
First of all, thanks for sharing this framework, this offers great opportunities for Python static analysis :)
I am building a tool that uses the CFG part of Scalpel, and I think I found a bug. When extracting the CFG of a function containing a try-catch-except-finally
block, the CFG does not take the code in the finally or after the try-except
blocks into account.
Here is an example showing the behaviour I am describing:
import textwrap
import scalpel.cfg as scfg
src = textwrap.dedent(
"""
def f():
try:
a = open("test.txt", "r")
v = a.read()
a.close()
except IOError:
v = "ioError"
except:
v = "otherError"
finally:
a = 123
return v + str(a)
"""
)
f_name = "f"
cfg_top_level: scfg.CFG = cast(
type(scfg.CFGBuilder),
scfg.CFGBuilder().build_from_src(name="top_level", src=src),
)
cfg_function = cast(
type(scfg.CFGBuilder),
CFGHelper.get_fct_block(cfg_top_level, f_name),
)
cfg_helper_without_ret = CFGHelper(cfg_function_without_ret)
cfg_function.build_visual("png")
Running this code outputs this CFG as png:
As we can see, a block is missing after the 3 blocks of the try-except
part. There is not other blocks in the CFG object, it does not seem to be a rendering bug.
I am available for any missing information or to try out stuff :)
Thanks a lot!
This is indeed an important issue as cfg is a core component of the framework. Thanks for raising this test case, it will be given top priority.
Great! You're fast :)
I am looking into the code, I'll open a PR if I can fix the bug!
This example works as intended:
"""
src = textwrap.dedent("""
def f():
x = 1
try:
a = open("a.txt", "r")
x = 2
a.close()
except IOError:
x = 3
except:
x = 4
finally:
y = 1
y += 6
return x + y
""")
(it is to keep track, I'm working on a fix)