Skip to content

Commit 1b67035

Browse files
committed
Python: Add tests for extended iterable unpacking
1 parent 781024d commit 1b67035

File tree

4 files changed

+75
-0
lines changed

4 files changed

+75
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import python
2+
import semmle.python.security.TaintTracking
3+
import semmle.python.security.strings.Untrusted
4+
5+
class SimpleSource extends TaintSource {
6+
SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" }
7+
8+
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
9+
10+
override string toString() { result = "taint source" }
11+
}
12+
13+
class ListSource extends TaintSource {
14+
ListSource() { this.(NameNode).getId() = "TAINTED_LIST" }
15+
16+
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind }
17+
18+
override string toString() { result = "list taint source" }
19+
}
20+
21+
class DictSource extends TaintSource {
22+
DictSource() { this.(NameNode).getId() = "TAINTED_DICT" }
23+
24+
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind }
25+
26+
override string toString() { result = "dict taint source" }
27+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
| test.py:11 | extended_unpacking | first | externally controlled string |
2+
| test.py:11 | extended_unpacking | last | externally controlled string |
3+
| test.py:11 | extended_unpacking | rest | NO TAINT |
4+
| test.py:16 | also_allowed | a | NO TAINT |
5+
| test.py:24 | also_allowed | b | NO TAINT |
6+
| test.py:24 | also_allowed | c | NO TAINT |
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import python
2+
import semmle.python.security.TaintTracking
3+
import Taint
4+
5+
from Call call, Expr arg, string taint_string
6+
where
7+
call.getLocation().getFile().getShortName() = "test.py" and
8+
call.getFunc().(Name).getId() = "test" and
9+
arg = call.getAnArg() and
10+
(
11+
not exists(TaintedNode tainted | tainted.getAstNode() = arg) and
12+
taint_string = "NO TAINT"
13+
or
14+
exists(TaintedNode tainted | tainted.getAstNode() = arg |
15+
taint_string = tainted.getTaintKind().toString()
16+
)
17+
)
18+
select arg.getLocation().toString(), call.getScope().(Function).getName(), arg.toString(), taint_string
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Extended Iterable Unpacking -- PEP 3132
2+
# https://www.python.org/dev/peps/pep-3132/
3+
4+
5+
def test(*args):
6+
pass
7+
8+
9+
def extended_unpacking():
10+
first, *rest, last = TAINTED_LIST
11+
test(first, rest, last) # TODO: mark `rest` as [taint]
12+
13+
14+
def also_allowed():
15+
*a, = TAINTED_LIST
16+
test(a) # TODO: mark `a` as [taint]
17+
18+
# for b, *c in [(1, 2, 3), (4, 5, 6, 7)]:
19+
# print(c)
20+
# i=0; c=[2,3]
21+
# i=1; c=[5,6,7]
22+
23+
for b, *c in [TAINTED_LIST, TAINTED_LIST]:
24+
test(b, c) # TODO: mark `c` as [taint]

0 commit comments

Comments
 (0)