diff --git a/go/ql/lib/ext/maps.model.yml b/go/ql/lib/ext/maps.model.yml new file mode 100644 index 000000000000..ce772ae31a46 --- /dev/null +++ b/go/ql/lib/ext/maps.model.yml @@ -0,0 +1,14 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + # All should be modeled when we have a way to model iterators + - ["maps", "", False, "Clone", "", "", "Argument[0].MapKey", "ReturnValue.MapKey", "value", "manual"] + - ["maps", "", False, "Clone", "", "", "Argument[0].MapValue", "ReturnValue.MapValue", "value", "manual"] + # Collect should be modeled when we have a way to model iterators + - ["maps", "", False, "Copy", "", "", "Argument[1].MapKey", "Argument[0].MapKey", "value", "manual"] + - ["maps", "", False, "Copy", "", "", "Argument[1].MapValue", "Argument[0].MapValue", "value", "manual"] + # Insert should be modeled when we have a way to model iterators + # Keys should be modeled when we have a way to model iterators + # Values should be modeled when we have a way to model iterators diff --git a/go/ql/src/change-notes/2026-09-30-model-maps-package.md b/go/ql/src/change-notes/2026-09-30-model-maps-package.md new file mode 100644 index 000000000000..a99a8c1c40ae --- /dev/null +++ b/go/ql/src/change-notes/2026-09-30-model-maps-package.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added value flow models for functions in the `maps` package which do not involve the `iter` package. diff --git a/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Maps.go b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Maps.go new file mode 100644 index 000000000000..45d62fac36db --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Maps.go @@ -0,0 +1,54 @@ +package main + +import "maps" + +func TaintStepTest_MapsCloneKey(fromString string) string { + toMap := maps.Clone(map[string]int{fromString: 0}) + for key := range toMap { + return key + } + return "" +} + +func TaintStepTest_MapsCloneValue(fromString string) string { + toMap := maps.Clone(map[string]string{"key": fromString}) + return toMap["key"] +} + +func TaintStepTest_MapsCopyKey(fromString string) string { + toMap := map[string]int{} + maps.Copy(toMap, map[string]int{fromString: 0}) + for key := range toMap { + return key + } + return "" +} + +func TaintStepTest_MapsCopyValue(fromString string) string { + toMap := map[string]string{} + maps.Copy(toMap, map[string]string{"key": fromString}) + return toMap["key"] +} + +func RunAllTaints_Maps() { + { + source := newSource(0).(string) + out := TaintStepTest_MapsCloneKey(source) + sink(0, out) + } + { + source := newSource(1).(string) + out := TaintStepTest_MapsCloneValue(source) + sink(1, out) + } + { + source := newSource(2).(string) + out := TaintStepTest_MapsCopyKey(source) + sink(2, out) + } + { + source := newSource(3).(string) + out := TaintStepTest_MapsCopyValue(source) + sink(3, out) + } +}