Skip to content

Commit 8755ab0

Browse files
Add qtil.python
1 parent 61d4af1 commit 8755ab0

18 files changed

Lines changed: 233 additions & 0 deletions

python/src/codeql-pack.lock.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
lockVersion: 1.0.0
3+
dependencies:
4+
codeql/dataflow:
5+
version: 1.1.6
6+
codeql/mad:
7+
version: 1.0.12
8+
codeql/python-all:
9+
version: 2.2.0
10+
codeql/regex:
11+
version: 1.0.12
12+
codeql/ssa:
13+
version: 1.0.12
14+
codeql/threat-models:
15+
version: 1.0.12
16+
codeql/tutorial:
17+
version: 1.0.12
18+
codeql/typetracking:
19+
version: 1.0.12
20+
codeql/util:
21+
version: 1.0.12
22+
codeql/xml:
23+
version: 1.0.12
24+
codeql/yaml:
25+
version: 1.0.12
26+
compiled: false

python/src/qlpack.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
name: mfairhurst/qtil-python
2+
library: true
3+
warnOnImplicitThis: false
4+
version: 0.0.1
5+
license: MIT
6+
dependencies:
7+
codeql/python-all: '>=0.0.1 <5.0.0'
8+
mfairhurst/qtil: 0.0.1

python/src/qtil/Python.qll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module Qtil {
2+
private import qtil.Qtil as Common
3+
// Importing qtil.Cpp should import all of Qtil.
4+
import Common::Qtil
5+
import qtil.python.ast.TwoOperands
6+
import qtil.python.format.QlFormat
7+
import qtil.python.graph.CustomPathProblem
8+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import python as python
2+
import qtil.parameterization.SignatureTypes
3+
import qtil.parameterization.Finalize
4+
5+
/**
6+
* A module for dealing with pairs of exclusive operands in C++ ASTs.
7+
*
8+
* For instance, to find cases where one operand is an integer and the other is a constant, you
9+
* will want to to perform checks on each operand separately and consistently without worrying about
10+
* order. This module makes this common pattern easy to implement.
11+
*
12+
* This module takes two type parameters:
13+
* - `Operand`: the type of the operands (e.g. `Expr`)
14+
* - `HasOperands`: a type that has operands of type `Operand` (e.g. `BinaryExpr`)
15+
*
16+
* ```ql
17+
* // Using this module:
18+
* predicate myBinaryTestNew(BinaryExpr e) {
19+
* exists(TwoOperands<BinaryExpr>::Set set |
20+
* set.getOperation() = e and
21+
* set.someOperand().isInteger() and
22+
* set.otherOperand().isConstant()
23+
* )
24+
* }
25+
*
26+
* // Is roughly equivalent to:
27+
* predicate myBinaryTestOld(BinaryExpr e) {
28+
* exists(Expr a, Expr b |
29+
* e.getAnOperand() = a and
30+
* e.getAnOperand() = b and
31+
* a != b and
32+
* a.isInteger() and
33+
* b.isConstant()
34+
* )
35+
* }
36+
* ```
37+
*
38+
* Some caution about using this module: for each use, two `Set` objects exst. If you do not
39+
* properly constrain the usage of `someOperand()` and `otherOperand()`, then these members could
40+
* hold for different `Set`s. Therefore, `someOperand()` and `otherOperand()` may be the same
41+
* operand. This will not happen if the `Set` is properly constrained across the two member
42+
* invocations.
43+
*
44+
* ```ql
45+
* predicate bug(BinaryExpr e) {
46+
* // Bad: the two sets are not constrained to the same instance, therefore the operands not
47+
* // guaranteed to be different.
48+
* TwoOperands<BinaryExpr>::getASet(e).someOperand().isInteger() and
49+
* TwoOperands<BinaryExpr>::getASet(e).otherOperand().isConstant()
50+
* }
51+
* ```
52+
*/
53+
module TwoOperands<Signature<python::BinaryExpr>::Type BinOp> {
54+
private import qtil.ast.TwoOperands as Make
55+
56+
// The `TwoOperands` module expects a `getAnOperand` member to be defined in the `BinOp` type, so
57+
// we define it here. The `TwoOperands` module should still work for any `BinaryExpr`.
58+
private class AddGetAnOperand extends Final<BinOp>::Type {
59+
python::Expr getAnOperand() { result = getLeft() or result = getRight() }
60+
}
61+
62+
import Make::TwoOperands<python::Expr, AddGetAnOperand>
63+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
private import qtil.format.QLFormat
2+
private import python
3+
private import qtil.python.locations.Locatable
4+
5+
import QlFormat<Location, PythonLocatableConfig>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
private import qtil.locations.CustomPathProblem
2+
private import qtil.python.locations.Locatable
3+
private import python
4+
5+
// Import the python specific configuration for making custom path problems.
6+
import PathProblem<Location, PythonLocatableConfig>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
private import qtil.locations.Locatable
2+
private import python as python
3+
4+
/**
5+
* A module to declare `Locatable`s specific to python for use in other qtil modules.
6+
*/
7+
module PythonLocatableConfig implements LocatableConfig<python::Location> {
8+
class Locatable = python::AstNode;
9+
}

python/test/codeql-pack.lock.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
lockVersion: 1.0.0
3+
dependencies:
4+
codeql/dataflow:
5+
version: 1.1.6
6+
codeql/mad:
7+
version: 1.0.12
8+
codeql/python-all:
9+
version: 2.2.0
10+
codeql/regex:
11+
version: 1.0.12
12+
codeql/ssa:
13+
version: 1.0.12
14+
codeql/threat-models:
15+
version: 1.0.12
16+
codeql/tutorial:
17+
version: 1.0.12
18+
codeql/typetracking:
19+
version: 1.0.12
20+
codeql/util:
21+
version: 1.0.12
22+
codeql/xml:
23+
version: 1.0.12
24+
codeql/yaml:
25+
version: 1.0.12
26+
compiled: false

python/test/qlpack.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
name: mfairhurst/qtil-python-test
2+
library: true
3+
warnOnImplicitThis: false
4+
version: 0.0.1
5+
license: MIT
6+
dependencies:
7+
mfairhurst/qtil-python: "*"
8+
extractor: python
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| test.py:3:5:3:9 | BinaryExpr | test.py:3:5:3:5 | a | test.py:3:9:3:9 | b |
2+
| test.py:4:5:4:9 | BinaryExpr | test.py:4:9:4:9 | a | test.py:4:5:4:5 | b |

0 commit comments

Comments
 (0)