Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit aa28167

Browse files
committed
Python: Add malloc nodes
1 parent 27b2556 commit aa28167

6 files changed

Lines changed: 217 additions & 121 deletions

File tree

python/ql/src/experimental/dataflow/internal/DataFlowPrivate.qll

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@ class DataFlowCfgNode extends ControlFlowNode {
1717
}
1818

1919
/** A data flow node which should have an associated post-update node. */
20-
abstract class PreUpdateNode extends Node { }
20+
abstract class PreUpdateNode extends Node {
21+
abstract string label();
22+
}
2123

2224
/** An argument might have its value changed as a result of a call. */
23-
class ArgumentPreUpdateNode extends PreUpdateNode, ArgumentNode { }
25+
class ArgumentPreUpdateNode extends PreUpdateNode, ExplicitArgumentNode {
26+
override string label() { result = "arg" }
27+
}
2428

2529
/** An object might have its value changed after a store. */
2630
class StorePreUpdateNode extends PreUpdateNode, CfgNode {
@@ -30,6 +34,8 @@ class StorePreUpdateNode extends PreUpdateNode, CfgNode {
3034
a.getCtx() instanceof Store
3135
)
3236
}
37+
38+
override string label() { result = "store" }
3339
}
3440

3541
/** A node marking the state change of an object after a read. */
@@ -40,6 +46,17 @@ class ReadPreUpdateNode extends PreUpdateNode, CfgNode {
4046
a.getCtx() instanceof Load
4147
)
4248
}
49+
50+
override string label() { result = "read" }
51+
}
52+
53+
class MallocNode extends PreUpdateNode, ImplicitSelfArgumentNode {
54+
// ObjectCreationNode() { exists(ClassValue c | this.asCfgNode() = c.getACall()) }
55+
override string toString() {
56+
result = "malloc " + this.asCfgNode().(CallNode).getNode().(Call).toString()
57+
}
58+
59+
override string label() { result = "malloc" }
4360
}
4461

4562
/**
@@ -61,7 +78,7 @@ class PostUpdateNode extends Node, TPostUpdateNode {
6178
/** Gets the node before the state update. */
6279
Node getPreUpdateNode() { result = pre }
6380

64-
override string toString() { result = "[post] " + pre.toString() }
81+
override string toString() { result = "[post " + pre.label() + "] " + pre.toString() }
6582

6683
override Scope getScope() { result = pre.getScope() }
6784

@@ -297,14 +314,33 @@ class SpecialCall extends DataFlowCall, TSpecialCall {
297314
}
298315

299316
/** A data flow node that represents a call argument. */
300-
class ArgumentNode extends CfgNode {
301-
ArgumentNode() { exists(DataFlowCall call, int pos | node = call.getArg(pos)) }
317+
abstract class ArgumentNode extends CfgNode {
318+
/** Holds if this argument occurs at the given position in the given call. */
319+
abstract predicate argumentOf(DataFlowCall call, int pos);
320+
321+
/** Gets the call in which this node is an argument. */
322+
abstract DataFlowCall getCall();
323+
}
324+
325+
/** A data flow node that represents a call argument. */
326+
class ExplicitArgumentNode extends ArgumentNode {
327+
ExplicitArgumentNode() { exists(DataFlowCall call, int pos | node = call.getArg(pos)) }
328+
329+
/** Holds if this argument occurs at the given position in the given call. */
330+
override predicate argumentOf(DataFlowCall call, int pos) { node = call.getArg(pos) }
331+
332+
/** Gets the call in which this node is an argument. */
333+
final override DataFlowCall getCall() { this.argumentOf(result, _) }
334+
}
335+
336+
class ImplicitSelfArgumentNode extends ArgumentNode {
337+
ImplicitSelfArgumentNode() { exists(ClassValue cv | node = cv.getACall()) }
302338

303339
/** Holds if this argument occurs at the given position in the given call. */
304-
predicate argumentOf(DataFlowCall call, int pos) { node = call.getArg(pos) }
340+
override predicate argumentOf(DataFlowCall call, int pos) { call = TCallNode(node) and pos = -1 }
305341

306342
/** Gets the call in which this node is an argument. */
307-
final DataFlowCall getCall() { this.argumentOf(result, _) }
343+
final override DataFlowCall getCall() { result = TCallNode(node) }
308344
}
309345

310346
/** Gets a viable run-time target for the call `call`. */

python/ql/test/experimental/dataflow/fieldflow/allLocalFlow.expected

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,31 @@
1414
| test.py:21:12:21:14 | SSA variable obj | test.py:23:5:23:11 | SSA variable obj |
1515
| test.py:21:17:21:17 | SSA variable x | test.py:23:15:23:15 | ControlFlowNode for x |
1616
| test.py:22:12:22:14 | ControlFlowNode for obj | test.py:23:5:23:7 | ControlFlowNode for obj |
17-
| test.py:22:12:22:14 | [post] ControlFlowNode for obj | test.py:23:5:23:7 | ControlFlowNode for obj |
17+
| test.py:22:12:22:14 | [post read] ControlFlowNode for obj | test.py:23:5:23:7 | ControlFlowNode for obj |
1818
| test.py:27:5:27:9 | SSA variable myobj | test.py:29:5:29:25 | SSA variable myobj |
1919
| test.py:27:5:27:9 | SSA variable myobj | test.py:29:12:29:16 | ControlFlowNode for myobj |
20-
| test.py:27:13:27:23 | ControlFlowNode for MyObj() | test.py:27:5:27:9 | SSA variable myobj |
20+
| test.py:27:13:27:23 | [post malloc] malloc MyObj() | test.py:27:5:27:9 | SSA variable myobj |
21+
| test.py:27:13:27:23 | malloc MyObj() | test.py:27:5:27:9 | SSA variable myobj |
2122
| test.py:29:12:29:16 | ControlFlowNode for myobj | test.py:30:10:30:14 | ControlFlowNode for myobj |
22-
| test.py:29:12:29:16 | [post] ControlFlowNode for myobj | test.py:30:10:30:14 | ControlFlowNode for myobj |
23+
| test.py:29:12:29:16 | [post arg] ControlFlowNode for myobj | test.py:30:10:30:14 | ControlFlowNode for myobj |
2324
| test.py:34:5:34:5 | SSA variable x | test.py:38:17:38:17 | ControlFlowNode for x |
2425
| test.py:34:9:34:14 | ControlFlowNode for SOURCE | test.py:34:5:34:5 | SSA variable x |
2526
| test.py:36:5:36:5 | SSA variable a | test.py:38:5:38:5 | ControlFlowNode for a |
2627
| test.py:36:5:36:5 | SSA variable a | test.py:39:5:39:14 | SSA variable a |
27-
| test.py:36:9:36:19 | ControlFlowNode for NestedObj() | test.py:36:5:36:5 | SSA variable a |
28+
| test.py:36:9:36:19 | [post malloc] malloc NestedObj() | test.py:36:5:36:5 | SSA variable a |
29+
| test.py:36:9:36:19 | malloc NestedObj() | test.py:36:5:36:5 | SSA variable a |
2830
| test.py:38:5:38:5 | ControlFlowNode for a | test.py:39:5:39:5 | ControlFlowNode for a |
29-
| test.py:38:5:38:5 | [post] ControlFlowNode for a | test.py:39:5:39:5 | ControlFlowNode for a |
31+
| test.py:38:5:38:5 | [post read] ControlFlowNode for a | test.py:39:5:39:5 | ControlFlowNode for a |
3032
| test.py:38:17:38:17 | ControlFlowNode for x | test.py:39:22:39:22 | ControlFlowNode for x |
3133
| test.py:39:5:39:5 | ControlFlowNode for a | test.py:41:10:41:10 | ControlFlowNode for a |
32-
| test.py:39:5:39:5 | [post] ControlFlowNode for a | test.py:41:10:41:10 | ControlFlowNode for a |
34+
| test.py:39:5:39:5 | [post read] ControlFlowNode for a | test.py:41:10:41:10 | ControlFlowNode for a |
3335
| test.py:45:5:45:7 | SSA variable obj | test.py:46:10:46:12 | ControlFlowNode for obj |
34-
| test.py:45:11:45:23 | ControlFlowNode for MyObj() | test.py:45:5:45:7 | SSA variable obj |
36+
| test.py:45:11:45:23 | [post malloc] malloc MyObj() | test.py:45:5:45:7 | SSA variable obj |
37+
| test.py:45:11:45:23 | malloc MyObj() | test.py:45:5:45:7 | SSA variable obj |
3538
| test.py:49:28:49:28 | SSA variable x | test.py:50:11:50:18 | SSA variable x |
3639
| test.py:49:28:49:28 | SSA variable x | test.py:50:17:50:17 | ControlFlowNode for x |
3740
| test.py:50:5:50:7 | SSA variable obj | test.py:51:9:51:11 | ControlFlowNode for obj |
38-
| test.py:50:11:50:18 | ControlFlowNode for MyObj() | test.py:50:5:50:7 | SSA variable obj |
41+
| test.py:50:11:50:18 | [post malloc] malloc MyObj() | test.py:50:5:50:7 | SSA variable obj |
42+
| test.py:50:11:50:18 | malloc MyObj() | test.py:50:5:50:7 | SSA variable obj |
3943
| test.py:51:5:51:5 | SSA variable a | test.py:52:12:52:12 | ControlFlowNode for a |
4044
| test.py:51:9:51:15 | ControlFlowNode for Attribute | test.py:51:5:51:5 | SSA variable a |

python/ql/test/experimental/dataflow/fieldflow/dataflow.expected

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
edges
2-
| test.py:29:12:29:16 | [post] ControlFlowNode for myobj [Attribute foo] | test.py:30:10:30:14 | ControlFlowNode for myobj [Attribute foo] |
3-
| test.py:29:19:29:24 | ControlFlowNode for SOURCE | test.py:29:12:29:16 | [post] ControlFlowNode for myobj [Attribute foo] |
2+
| test.py:29:12:29:16 | [post arg] ControlFlowNode for myobj [Attribute foo] | test.py:30:10:30:14 | ControlFlowNode for myobj [Attribute foo] |
3+
| test.py:29:19:29:24 | ControlFlowNode for SOURCE | test.py:29:12:29:16 | [post arg] ControlFlowNode for myobj [Attribute foo] |
44
| test.py:30:10:30:14 | ControlFlowNode for myobj [Attribute foo] | test.py:30:10:30:18 | ControlFlowNode for Attribute |
55
| test.py:34:9:34:14 | ControlFlowNode for SOURCE | test.py:38:17:38:17 | ControlFlowNode for x |
6-
| test.py:38:5:38:5 | [post] ControlFlowNode for a [Attribute obj, Attribute foo] | test.py:41:10:41:10 | ControlFlowNode for a [Attribute obj, Attribute foo] |
7-
| test.py:38:5:38:9 | [post] ControlFlowNode for Attribute [Attribute foo] | test.py:38:5:38:5 | [post] ControlFlowNode for a [Attribute obj, Attribute foo] |
8-
| test.py:38:17:38:17 | ControlFlowNode for x | test.py:38:5:38:9 | [post] ControlFlowNode for Attribute [Attribute foo] |
6+
| test.py:38:5:38:5 | [post read] ControlFlowNode for a [Attribute obj, Attribute foo] | test.py:41:10:41:10 | ControlFlowNode for a [Attribute obj, Attribute foo] |
7+
| test.py:38:5:38:9 | [post store] ControlFlowNode for Attribute [Attribute foo] | test.py:38:5:38:5 | [post read] ControlFlowNode for a [Attribute obj, Attribute foo] |
8+
| test.py:38:17:38:17 | ControlFlowNode for x | test.py:38:5:38:9 | [post store] ControlFlowNode for Attribute [Attribute foo] |
99
| test.py:41:10:41:10 | ControlFlowNode for a [Attribute obj, Attribute foo] | test.py:41:10:41:14 | ControlFlowNode for Attribute [Attribute foo] |
1010
| test.py:41:10:41:14 | ControlFlowNode for Attribute [Attribute foo] | test.py:41:10:41:18 | ControlFlowNode for Attribute |
1111
nodes
12-
| test.py:29:12:29:16 | [post] ControlFlowNode for myobj [Attribute foo] | semmle.label | [post] ControlFlowNode for myobj [Attribute foo] |
12+
| test.py:29:12:29:16 | [post arg] ControlFlowNode for myobj [Attribute foo] | semmle.label | [post arg] ControlFlowNode for myobj [Attribute foo] |
1313
| test.py:29:19:29:24 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
1414
| test.py:30:10:30:14 | ControlFlowNode for myobj [Attribute foo] | semmle.label | ControlFlowNode for myobj [Attribute foo] |
1515
| test.py:30:10:30:18 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
1616
| test.py:34:9:34:14 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
17-
| test.py:38:5:38:5 | [post] ControlFlowNode for a [Attribute obj, Attribute foo] | semmle.label | [post] ControlFlowNode for a [Attribute obj, Attribute foo] |
18-
| test.py:38:5:38:9 | [post] ControlFlowNode for Attribute [Attribute foo] | semmle.label | [post] ControlFlowNode for Attribute [Attribute foo] |
17+
| test.py:38:5:38:5 | [post read] ControlFlowNode for a [Attribute obj, Attribute foo] | semmle.label | [post read] ControlFlowNode for a [Attribute obj, Attribute foo] |
18+
| test.py:38:5:38:9 | [post store] ControlFlowNode for Attribute [Attribute foo] | semmle.label | [post store] ControlFlowNode for Attribute [Attribute foo] |
1919
| test.py:38:17:38:17 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
2020
| test.py:41:10:41:10 | ControlFlowNode for a [Attribute obj, Attribute foo] | semmle.label | ControlFlowNode for a [Attribute obj, Attribute foo] |
2121
| test.py:41:10:41:14 | ControlFlowNode for Attribute [Attribute foo] | semmle.label | ControlFlowNode for Attribute [Attribute foo] |

0 commit comments

Comments
 (0)