Skip to content

Commit 5f6e4d4

Browse files
committed
Python: Add CodeExecution concept
1 parent bec33b7 commit 5f6e4d4

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

python/ql/src/experimental/semmle/python/Concepts.qll

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,32 @@ module SystemCommandExecution {
3838
abstract DataFlow::Node getCommand();
3939
}
4040
}
41+
42+
/**
43+
* A data-flow node that dynamically executes Python code.
44+
*
45+
* Extend this class to refine existing API models. If you want to model new APIs,
46+
* extend `CodeExecution::Range` instead.
47+
*/
48+
class CodeExecution extends DataFlow::Node {
49+
CodeExecution::Range range;
50+
51+
CodeExecution() { this = range }
52+
53+
/** Gets the argument that specifies the code to be executed. */
54+
DataFlow::Node getCode() { result = range.getCode() }
55+
}
56+
57+
/** Provides a class for modeling new dynamic code execution APIs. */
58+
module CodeExecution {
59+
/**
60+
* A data-flow node that dynamically executes Python code.
61+
*
62+
* Extend this class to model new APIs. If you want to refine existing API models,
63+
* extend `CodeExecution` instead.
64+
*/
65+
abstract class Range extends DataFlow::Node {
66+
/** Gets the argument that specifies the code to be executed. */
67+
abstract DataFlow::Node getCode();
68+
}
69+
}

python/ql/test/experimental/meta/ConceptsTest.qll

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,20 @@ class SystemCommandExecutionTest extends InlineExpectationsTest {
3232
)
3333
}
3434
}
35+
36+
class CodeExecutionTest extends InlineExpectationsTest {
37+
CodeExecutionTest() { this = "CodeExecutionTest" }
38+
39+
override string getARelevantTag() { result = "getCode" }
40+
41+
override predicate hasActualResult(Location location, string element, string tag, string value) {
42+
exists(CodeExecution ce, DataFlow::Node code |
43+
exists(location.getFile().getRelativePath()) and
44+
code = ce.getCode() and
45+
location = code.getLocation() and
46+
element = code.toString() and
47+
value = value_from_expr(code.asExpr()) and
48+
tag = "getCode"
49+
)
50+
}
51+
}

0 commit comments

Comments
 (0)