Skip to content

Commit 1f1b1b7

Browse files
authored
Merge pull request #17653 from yoff/python/typetracking-through-comprehensions
2 parents 3c1a19c + 6d486f9 commit 1f1b1b7

File tree

4 files changed

+14
-3
lines changed

4 files changed

+14
-3
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Type tracking, and hence the API graph, is now able to correctly trace trough comprehensions.

python/ql/lib/semmle/python/ApiGraphs.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,13 @@ module API {
843843
ref = pred.getSubscript(_) and
844844
ref.asCfgNode().isLoad()
845845
or
846+
// Subscript via comprehension
847+
lbl = Label::subscript() and
848+
exists(PY::Comp comp |
849+
pred.asExpr() = comp.getIterable() and
850+
ref.asExpr() = comp.getNthInnerLoop(0).getTarget()
851+
)
852+
or
846853
// Subclassing a node
847854
lbl = Label::subclass() and
848855
exists(PY::ClassExpr clsExpr, DataFlow::Node superclass | pred.flowsTo(superclass) |

python/ql/lib/semmle/python/dataflow/new/internal/TypeTrackingImpl.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ module TypeTrackingInput implements Shared::TypeTrackingInput {
304304
var.hasDefiningNode(def)
305305
|
306306
nodeTo.(DataFlowPublic::ScopeEntryDefinitionNode).getDefinition() = e and
307-
nodeFrom.asCfgNode() = def.getValue() and
307+
nodeFrom.asCfgNode() = def and
308308
var.getScope().getScope*() = nodeFrom.getScope()
309309
)
310310
}

python/ql/test/library-tests/frameworks/stdlib/http_server.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def test_cgi_FieldStorage_taint():
3030
form['key'][0].value, # $ tainted
3131
form['key'][0].file, # $ tainted
3232
form['key'][0].filename, # $ tainted
33-
[field.value for field in form['key']], # $ MISSING: tainted
33+
[field.value for field in form['key']], # $ tainted
3434

3535
# `form.getvalue('key')` will be a list, if multiple fields named "key" are provided
3636
form.getvalue('key'), # $ tainted
@@ -40,7 +40,7 @@ def test_cgi_FieldStorage_taint():
4040

4141
form.getlist('key'), # $ tainted
4242
form.getlist('key')[0], # $ tainted
43-
[field.value for field in form.getlist('key')], # $ MISSING: tainted
43+
[field.value for field in form.getlist('key')], # $ tainted
4444
)
4545

4646

0 commit comments

Comments
 (0)