python-security/pyt

VarsVisitor RuntimeError on code like f(g(a)(b))

bcaller opened this issue · 3 comments

If you run pyt on code like x = f(g(a)(b)), it will raise an Exception

  File "/pack/pyt/pyt/cfg/stmt_visitor.py", line 83, in stmt_star_handler
    node = self.visit(stmt)
  File "/usr/lib/python3.7/ast.py", line 262, in visit
    return visitor(node)
  File "/pack/pyt/pyt/cfg/stmt_visitor.py", line 452, in visit_Assign
    return self.assignment_call_node(label.result, node)
  File "/pack/pyt/pyt/cfg/stmt_visitor.py", line 485, in assignment_call_node
    vars_visitor.visit(ast_node.value)
  File "/usr/lib/python3.7/ast.py", line 262, in visit
    return visitor(node)
  File "/pack/pyt/pyt/helper_visitors/vars_visitor.py", line 106, in visit_Call
    raise

Test case:

    def test_curried_function(self):
        vars = self.perform_vars_on_expression('f(g(a)(b)(c))')
        self.assertEqual(vars.result, ???)

What should the result be? ['a', 'b', 'c']? I'm not exactly sure what the function on VarsVisitor is.

@KevinHock Do you have any ideas?

That is interesting, I'll play around with it more today but it might be [ret_g, b, c] or just [ret_g] depending on if b and c get passed to g() or f(). https://github.com/python-security/pyt/blob/master/tests/helper_visitors/vars_visitor_test.py#L43-L46

So this is difficult, we probably wouldn't generate a "proper" CFG for curried code, (the calling what is returned part). For now we can make it [ret_g, b, c] which means false-positives but definitely acceptable given how rare code like this is.