Skip to content

False-negative when function call follows ControlFlowNode #65

Closed

Description

@KevinHock

Just moved to SF! Figured I would talk to myself in a GitHub issue to reacquaint myself with what I was doing.

This issue was the only test to fail on #63, similar to the [-1] issue it only happens with function calls because it is the only place in the codebase where we "artificially" create nodes.

The reason why the test passed in master and not on the #63 PR was because in master only user-defined functions were turned into more than 1 node, and in the #63 PR blackbox calls are supported as well. (The test only has blackbox calls.)
(
Before it was something like

  param = request.args.get('param', 'not set')

Now it is something like

  ¤call_1 = ret_request.args.get('param', 'not set')
  param = ¤call_1

)

So if master had tests like below but with say outer() being user-defined and replacing scrypt.outer below, the same problem occurs.

import scrypt

image_name = request.args.get('image_name')
for x in range(0, 10):
  print(x)
# print('if this print statement is here everything works')
foo = scrypt.outer(image_name) # Any call after ControlFlowNode causes the problem
send_file(foo)
import scrypt

image_name = request.args.get('image_name')
if not image_name:
    image_name = 'foo'
# print('if this print statement is here everything works')
foo = scrypt.outer(image_name) # Any call after ControlFlowNode causes the problem
send_file(foo)

I gave 2 examples here because it is not specific to if or for, but any ControlFlowNode followed by a function call.

Where and why does this occur though?

In stmt_star_handler in base_cfg.py we have a call to connect_nodes self.connect_nodes(cfg_statements).
The purpose is to connect one node to the next node. (n->n+1 on and on.)

The problem is that foo = ¤call_2 is connected to both the if statement and last statement of it's body, instead of the first node of the call.
In the first example, this is ¤call_1 = ret_request.args.get('param', 'not set') rather than param = ¤call_1.

You might say, what's so bad? You already made a new node type BBnode, just set a first_statement attribute as e.g. ¤call_1 = ret_request.args.get('param', 'not set') and you'd kind of be right.
Except nested function calls make that a pain, because I'll need to follow a chain of "What's your first node?" "What's your first node?".
e.g. if it was ``¤call_2 = ret_request.args.get(¤call_1, 'not set')` we would need first_statement to be the first_statement of ¤call_1.
I think this is the way forward, but I don't feel good about it.

Activity

  1. KevinHock commented on Sep 24, 2017

    @KevinHock
    CollaboratorAuthor

    Also, being that the problem exist for user-defined function calls, I'm pretty sure we'll need to make a new node type for them too.

  2. KevinHock commented on Sep 25, 2017

    @KevinHock
    CollaboratorAuthor

    Alright, so I solved this easily c90a14e with BBorBInode's, user-defined functions shouldn't be that more difficult.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions