diff --git a/go/ql/lib/ext/maps.model.yml b/go/ql/lib/ext/maps.model.yml new file mode 100644 index 000000000000..90961c782214 --- /dev/null +++ b/go/ql/lib/ext/maps.model.yml @@ -0,0 +1,17 @@ +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"] + # DeleteFunc does not need to be modeled since it only removes key/value pairs from m in place and does not return a value + # Equal does not need to be modeled since it returns a bool + # EqualFunc does not need to be modeled since it returns a bool + # 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-10-01-model-maps-package.md b/go/ql/src/change-notes/2026-10-01-model-maps-package.md new file mode 100644 index 000000000000..a99a8c1c40ae --- /dev/null +++ b/go/ql/src/change-notes/2026-10-01-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..08c2ffc00e5b --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Maps.go @@ -0,0 +1,60 @@ +package main + +import ( + "maps" +) + +func TaintStepTest_MapsCloneValue(fromString string) string { + m := map[string]string{"key": fromString} + clone := maps.Clone(m) + return clone["key"] +} + +func TaintStepTest_MapsCloneKey(fromString string) string { + m := map[string]string{fromString: "value"} + clone := maps.Clone(m) + for k := range clone { + return k + } + return "" +} + +func TaintStepTest_MapsCopyValue(fromString string) string { + src := map[string]string{"key": fromString} + dst := map[string]string{} + maps.Copy(dst, src) + return dst["key"] +} + +func TaintStepTest_MapsCopyKey(fromString string) string { + src := map[string]string{fromString: "value"} + dst := map[string]string{} + maps.Copy(dst, src) + for k := range dst { + return k + } + return "" +} + +func RunAllTaints_Maps() { + { + source := newSource(0).(string) + out := TaintStepTest_MapsCloneValue(source) + sink(0, out) + } + { + source := newSource(1).(string) + out := TaintStepTest_MapsCloneKey(source) + sink(1, out) + } + { + source := newSource(2).(string) + out := TaintStepTest_MapsCopyValue(source) + sink(2, out) + } + { + source := newSource(3).(string) + out := TaintStepTest_MapsCopyKey(source) + sink(3, out) + } +}