Skip to content

Commit 9f84653

Browse files
authored
Merge pull request github#15613 from smowton/smowton/fix/golang-map-range-read-dataflow
Golang: fix flow from a map value via a range statement
2 parents 5ea30e9 + a6480a4 commit 9f84653

File tree

5 files changed

+40
-8
lines changed

5 files changed

+40
-8
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: fix
3+
---
4+
* Fixed dataflow out of a `map` using a `range` statement.

go/ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ predicate containerStoreStep(Node node1, Node node2, Content c) {
4141
or
4242
c instanceof MapKeyContent and
4343
node2.getType() instanceof MapType and
44-
exists(Write w | w.writesElement(node2, node1, _))
44+
exists(Write w | w.writesElement(node2.(PostUpdateNode).getPreUpdateNode(), node1, _))
4545
or
4646
c instanceof MapValueContent and
4747
node2.getType() instanceof MapType and
48-
exists(Write w | w.writesElement(node2, _, node1))
48+
exists(Write w | w.writesElement(node2.(PostUpdateNode).getPreUpdateNode(), _, node1))
4949
}
5050

5151
/**
@@ -57,11 +57,11 @@ predicate containerStoreStep(Node node1, Node node2, Content c) {
5757
predicate containerReadStep(Node node1, Node node2, Content c) {
5858
c instanceof ArrayContent and
5959
(
60-
node2.(Read).readsElement(node1, _) and
61-
(
62-
node1.getType() instanceof ArrayType or
63-
node1.getType() instanceof SliceType
64-
)
60+
node1.getType() instanceof ArrayType or
61+
node1.getType() instanceof SliceType
62+
) and
63+
(
64+
node2.(Read).readsElement(node1, _)
6565
or
6666
node2.(RangeElementNode).getBase() = node1
6767
or
@@ -85,5 +85,5 @@ predicate containerReadStep(Node node1, Node node2, Content c) {
8585
or
8686
c instanceof MapValueContent and
8787
node1.getType() instanceof MapType and
88-
node2.(Read).readsElement(node1, _)
88+
(node2.(Read).readsElement(node1, _) or node2.(RangeElementNode).getBase() = node1)
8989
}

go/ql/test/library-tests/semmle/go/dataflow/MapReadsAndStores/Flows.expected

Whitespace-only changes.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import go
2+
import TestUtilities.InlineFlowTest
3+
import DefaultFlowTest
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package main
2+
3+
func source() string {
4+
return "untrusted data"
5+
}
6+
7+
func sink(any) {
8+
}
9+
10+
func main() {
11+
var someMap map[string]string = map[string]string{}
12+
someMap["someKey"] = source()
13+
14+
for _, val := range someMap {
15+
sink(val) // $ hasValueFlow="val"
16+
}
17+
}
18+
19+
func testLiteral() {
20+
someMap := map[string]string{"someKey": source()}
21+
22+
for _, val := range someMap {
23+
sink(val) // $ hasValueFlow="val"
24+
}
25+
}

0 commit comments

Comments
 (0)