зеркало из https://github.com/github/codeql-go.git
Add data flow tests for generic structs, methods and functions
This commit is contained in:
Родитель
4e71ab5cfc
Коммит
7a7ca619b3
|
@ -0,0 +1,2 @@
|
|||
import go
|
||||
import TestUtilities.InlineFlowTest
|
|
@ -0,0 +1,49 @@
|
|||
package main
|
||||
|
||||
func genericSource[T any](t T) string {
|
||||
x := source()
|
||||
return x
|
||||
}
|
||||
|
||||
func genericIdentity[T any](t T) T {
|
||||
return t
|
||||
}
|
||||
|
||||
func genericSink1[T any](t T, u string) {
|
||||
sink(u) // $ hasValueFlow="u"
|
||||
}
|
||||
|
||||
func genericSink2[T any](t T, u string) {
|
||||
sink(u) // $ hasValueFlow="u"
|
||||
}
|
||||
|
||||
func test() {
|
||||
var x struct {
|
||||
x1 int
|
||||
x2 string
|
||||
}
|
||||
{
|
||||
s := genericSource(x)
|
||||
sink(s) // $ hasValueFlow="s"
|
||||
}
|
||||
{
|
||||
s := genericSource[int8](2)
|
||||
sink(s) // $ hasValueFlow="s"
|
||||
}
|
||||
{
|
||||
s := genericIdentity(source())
|
||||
sink(s) // $ hasValueFlow="s"
|
||||
}
|
||||
{
|
||||
s := genericIdentity[string](source())
|
||||
sink(s) // $ hasValueFlow="s"
|
||||
}
|
||||
{
|
||||
s := source()
|
||||
genericSink1(x, s)
|
||||
}
|
||||
{
|
||||
s := source()
|
||||
genericSink2[uint16](3, s)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package main
|
||||
|
||||
func source() string {
|
||||
return "untrusted data"
|
||||
}
|
||||
|
||||
func sink(string) {
|
||||
}
|
||||
|
||||
type GenericStruct1[T any] struct {
|
||||
Field T
|
||||
}
|
||||
|
||||
func (g GenericStruct1[U]) Identity(u U) U { return u }
|
||||
func (g GenericStruct1[U]) Getter() U { return g.Field }
|
||||
func (g GenericStruct1[U]) Setter(u U) { g.Field = u }
|
||||
|
||||
type GenericStruct2[S, T any] struct {
|
||||
Field1 S
|
||||
Field2 T
|
||||
}
|
||||
|
||||
func (g GenericStruct2[U, _]) Identity1(u U) U { return u }
|
||||
func (g GenericStruct2[U, _]) Getter1() U { return g.Field1 }
|
||||
func (g GenericStruct2[U, _]) Setter1(u U) { g.Field1 = u }
|
||||
|
||||
func (g GenericStruct2[_, V]) Identity2(v V) V { return v }
|
||||
func (g GenericStruct2[_, V]) Getter2() V { return g.Field2 }
|
||||
func (g GenericStruct2[_, V]) Setter2(v V) { g.Field2 = v }
|
||||
|
||||
func main() {
|
||||
{
|
||||
gs1 := GenericStruct1[string]{source()}
|
||||
sink(gs1.Field) // $ hasValueFlow="selection of Field"
|
||||
}
|
||||
{
|
||||
gs1 := GenericStruct1[string]{""}
|
||||
sink(gs1.Identity(source())) // $ hasValueFlow="call to Identity"
|
||||
}
|
||||
{
|
||||
gs1 := GenericStruct1[string]{""}
|
||||
gs1.Field = source()
|
||||
sink(gs1.Getter()) // $ hasValueFlow="call to Getter"
|
||||
}
|
||||
{
|
||||
gs1 := GenericStruct1[string]{""}
|
||||
gs1.Setter(source())
|
||||
sink(gs1.Field) // $ hasValueFlow="selection of Field"
|
||||
}
|
||||
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{source(), ""}
|
||||
sink(gs2.Field1) // $ hasValueFlow="selection of Field1"
|
||||
}
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", ""}
|
||||
sink(gs2.Identity1(source())) // $ hasValueFlow="call to Identity1"
|
||||
}
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", ""}
|
||||
gs2.Field1 = source()
|
||||
sink(gs2.Getter1()) // $ hasValueFlow="call to Getter1"
|
||||
}
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", ""}
|
||||
gs2.Setter1(source())
|
||||
sink(gs2.Field1) // $ hasValueFlow="selection of Field1"
|
||||
}
|
||||
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", source()}
|
||||
sink(gs2.Field2) // $ hasValueFlow="selection of Field2"
|
||||
}
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", ""}
|
||||
sink(gs2.Identity2(source())) // $ hasValueFlow="call to Identity2"
|
||||
}
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", ""}
|
||||
gs2.Field2 = source()
|
||||
sink(gs2.Getter2()) // $ hasValueFlow="call to Getter2"
|
||||
}
|
||||
{
|
||||
gs2 := GenericStruct2[string, string]{"", ""}
|
||||
gs2.Setter2(source())
|
||||
sink(gs2.Field2) // $ hasValueFlow="selection of Field2"
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче