Skip to content

Commit d94f20f

Browse files
authored
Merge pull request #5194 from RasmusWL/type-tracking-snippets
Approved by tausbn
2 parents 88263cb + 0cdb5c4 commit d94f20f

File tree

2 files changed

+6
-206
lines changed

2 files changed

+6
-206
lines changed

python/.vscode/ql.code-snippets

Lines changed: 4 additions & 204 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@
105105
"scope": "ql",
106106
"prefix": "type tracking",
107107
"body": [
108-
"/** Gets a reference to a ${3:thing}. */",
109-
"private DataFlow::Node ${1:myType}(DataFlow::TypeTracker t) {",
108+
"/** Gets a reference to ${3:a thing}. */",
109+
"private DataFlow::LocalSourceNode ${1:myType}(DataFlow::TypeTracker t) {",
110110
" t.start() and",
111111
" result = ${2:value}",
112112
" or",
@@ -115,100 +115,14 @@
115115
" )",
116116
"}",
117117
"",
118-
"/** Gets a reference to a ${3:thing}. */",
118+
"/** Gets a reference to $3. */",
119119
"DataFlow::Node $1() {",
120-
" result = $1(DataFlow::TypeTracker::end())",
120+
" $1(DataFlow::TypeTracker::end()).flowsTo(result)",
121121
"}"
122122
],
123123
"description": "Type tracking predicate",
124124
},
125125

126-
"Type tracking module": {
127-
"scope": "ql",
128-
"prefix": "type tracking module",
129-
"body": [
130-
"// ---------------------------------------------------------------------------",
131-
"// ${1:modulename}",
132-
"// ---------------------------------------------------------------------------",
133-
"/** Gets a reference to the `$1` module. */",
134-
"private DataFlow::Node $1(DataFlow::TypeTracker t) {",
135-
" t.start() and",
136-
" result = DataFlow::importNode(\"$1\")",
137-
" or",
138-
" exists(DataFlow::TypeTracker t2 | result = $1(t2).track(t2, t))",
139-
"}",
140-
"",
141-
"/** Gets a reference to the `$1` module. */",
142-
"DataFlow::Node $1() { result = $1(DataFlow::TypeTracker::end()) }",
143-
"",
144-
"/**",
145-
" * Gets a reference to the attribute `attr_name` of the `$1` module.",
146-
" * WARNING: Only holds for a few predefined attributes.",
147-
" */",
148-
"private DataFlow::Node $1_attr(DataFlow::TypeTracker t, string attr_name) {",
149-
" attr_name in [\"${2:name}\"] and",
150-
" (",
151-
" t.start() and",
152-
" result = DataFlow::importNode(\"$1\" + \".\" + attr_name)",
153-
" or",
154-
" t.startInAttr(attr_name) and",
155-
" result = $1()",
156-
" )",
157-
" or",
158-
" // Due to bad performance when using normal setup with `$1_attr(t2, attr_name).track(t2, t)`",
159-
" // we have inlined that code and forced a join",
160-
" exists(DataFlow::TypeTracker t2 |",
161-
" exists(DataFlow::StepSummary summary |",
162-
" $1_attr_first_join(t2, attr_name, result, summary) and",
163-
" t = t2.append(summary)",
164-
" )",
165-
" )",
166-
"}",
167-
"",
168-
"pragma[nomagic]",
169-
"private predicate $1_attr_first_join(",
170-
" DataFlow::TypeTracker t2, string attr_name, DataFlow::Node res, DataFlow::StepSummary summary",
171-
") {",
172-
" DataFlow::StepSummary::step($1_attr(t2, attr_name), res, summary)",
173-
"}",
174-
"",
175-
"/**",
176-
" * Gets a reference to the attribute `attr_name` of the `$1` module.",
177-
" * WARNING: Only holds for a few predefined attributes.",
178-
" */",
179-
"private DataFlow::Node $1_attr(string attr_name) {",
180-
" result = $1_attr(DataFlow::TypeTracker::end(), attr_name)",
181-
"}",
182-
"",
183-
"/** Provides models for the `$1` module. */",
184-
"module $1 {",
185-
"",
186-
"}",
187-
],
188-
"description": "Type tracking module",
189-
},
190-
191-
"Type tracking module member": {
192-
"scope": "ql",
193-
"prefix": "type tracking module member",
194-
"body": [
195-
"/** Gets a reference to the `${1:module}.${2:member}` ${3:object/class}. */",
196-
"private DataFlow::Node ${4:$2}(DataFlow::TypeTracker t) {",
197-
" t.start() and",
198-
" result = DataFlow::importNode(\"$1.$2\")",
199-
" or",
200-
" t.startInAttr(\"$2\") and",
201-
" result = $1()",
202-
" or",
203-
" exists(DataFlow::TypeTracker t2 | result = $4(t2).track(t2, t))",
204-
"}",
205-
" ",
206-
"/** Gets a reference to the `$1.$2` $3. */",
207-
"DataFlow::Node $4() { result = $4(DataFlow::TypeTracker::end()) }",
208-
],
209-
"description": "Type tracking module member",
210-
},
211-
212126
"Taint tracking configuration": {
213127
"scope": "ql",
214128
"prefix": "taint tracking",
@@ -238,118 +152,4 @@
238152
]
239153
},
240154

241-
"Type tracking submodule": {
242-
"scope": "ql",
243-
"prefix": "type tracking submodule",
244-
"body": [
245-
" // -------------------------------------------------------------------------",
246-
" // ${1:parent}.${2:submodule}",
247-
" // -------------------------------------------------------------------------",
248-
" /** Gets a reference to the `$1.$2` module. */",
249-
" DataFlow::Node $2() { result = $1_attr(\"$2\") }",
250-
"",
251-
" /** Provides models for the `$1.$2` module */",
252-
" module $2 {",
253-
" /**",
254-
" * Gets a reference to the attribute `attr_name` of the `$1.$2` module.",
255-
" * WARNING: Only holds for a few predefined attributes.",
256-
" */",
257-
" private DataFlow::Node $2_attr(DataFlow::TypeTracker t, string attr_name) {",
258-
" attr_name in [\"$3\"] and",
259-
" (",
260-
" t.start() and",
261-
" result = DataFlow::importNode(\"$1.$2\" + \".\" + attr_name)",
262-
" or",
263-
" t.startInAttr(attr_name) and",
264-
" result = $2()",
265-
" )",
266-
" or",
267-
" // Due to bad performance when using normal setup with `$2_attr(t2, attr_name).track(t2, t)`",
268-
" // we have inlined that code and forced a join",
269-
" exists(DataFlow::TypeTracker t2 |",
270-
" exists(DataFlow::StepSummary summary |",
271-
" $2_attr_first_join(t2, attr_name, result, summary) and",
272-
" t = t2.append(summary)",
273-
" )",
274-
" )",
275-
" }",
276-
"",
277-
" pragma[nomagic]",
278-
" private predicate $2_attr_first_join(",
279-
" DataFlow::TypeTracker t2, string attr_name, DataFlow::Node res,",
280-
" DataFlow::StepSummary summary",
281-
" ) {",
282-
" DataFlow::StepSummary::step($2_attr(t2, attr_name), res, summary)",
283-
" }",
284-
"",
285-
" /**",
286-
" * Gets a reference to the attribute `attr_name` of the `$1.$2` module.",
287-
" * WARNING: Only holds for a few predefined attributes.",
288-
" */",
289-
" private DataFlow::Node $2_attr(string attr_name) {",
290-
" result = $2_attr(DataFlow::TypeTracker::end(), attr_name)",
291-
" }",
292-
" }",
293-
],
294-
"description": "Type tracking submodule",
295-
},
296-
297-
"Type tracking class": {
298-
"scope": "ql",
299-
"prefix": "type tracking class",
300-
"body": [
301-
" /**",
302-
" * Provides models for the `${1:module}.${2:classname}` class",
303-
" *",
304-
" * See ${6:apiref}.",
305-
" */",
306-
" module $2 {",
307-
" /** Gets a reference to the `$1.$2` class. */",
308-
" private DataFlow::Node classRef(DataFlow::TypeTracker t) {",
309-
" t.start() and",
310-
" result = ${4:module}_attr(\"$2\")",
311-
" or",
312-
" // TODO: remove/expand this part of the template as needed",
313-
" // Handle `${5:toplevel}.$2` alias",
314-
" t.start() and",
315-
" result = $5_attr(\"$2\")",
316-
" or",
317-
" exists(DataFlow::TypeTracker t2 | result = classRef(t2).track(t2, t))",
318-
" }",
319-
"",
320-
" /** Gets a reference to the `$1.$2` class. */",
321-
" DataFlow::Node classRef() { result = classRef(DataFlow::TypeTracker::end()) }",
322-
"",
323-
" /**",
324-
" * A source of instances of `$1.$2`, extend this class to model new instances.",
325-
" *",
326-
" * This can include instantiations of the class, return values from function",
327-
" * calls, or a special parameter that will be set when functions are called by an external",
328-
" * library.",
329-
" *",
330-
" * Use the predicate `$2::instance()` to get references to instances of `$1.$2`.",
331-
" */",
332-
" abstract class InstanceSource extends DataFlow::Node { }",
333-
"",
334-
" /** A direct instantiation of `$1.$2`. */",
335-
" private class ClassInstantiation extends InstanceSource, DataFlow::CfgNode {",
336-
" override CallNode node;",
337-
"",
338-
" ClassInstantiation() { node.getFunction() = classRef().asCfgNode() }",
339-
" }",
340-
"",
341-
" /** Gets a reference to an instance of `$1.$2`. */",
342-
" private DataFlow::Node instance(DataFlow::TypeTracker t) {",
343-
" t.start() and",
344-
" result instanceof InstanceSource",
345-
" or",
346-
" exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t))",
347-
" }",
348-
"",
349-
" /** Gets a reference to an instance of `$1.$2`. */",
350-
" DataFlow::Node instance() { result = instance(DataFlow::TypeTracker::end()) }",
351-
" }",
352-
],
353-
"description": "Type tracking class",
354-
},
355155
}

python/ql/src/semmle/python/dataflow/new/TypeTracker.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ private newtype TTypeTracker = MkTypeTracker(Boolean hasCall, OptionalAttributeN
180180
* It is recommended that all uses of this type are written in the following form,
181181
* for tracking some type `myType`:
182182
* ```
183-
* DataFlow::Node myType(DataFlow::TypeTracker t) {
183+
* DataFlow::LocalSourceNode myType(DataFlow::TypeTracker t) {
184184
* t.start() and
185185
* result = < source of myType >
186186
* or
@@ -189,7 +189,7 @@ private newtype TTypeTracker = MkTypeTracker(Boolean hasCall, OptionalAttributeN
189189
* )
190190
* }
191191
*
192-
* DataFlow::Node myType() { result = myType(DataFlow::TypeTracker::end()) }
192+
* DataFlow::Node myType() { myType(DataFlow::TypeTracker::end()).flowsTo(result) }
193193
* ```
194194
*
195195
* Instead of `result = myType(t2).track(t2, t)`, you can also use the equivalent

0 commit comments

Comments
 (0)