From 46a1a4e010b7f90b0e53456f02c4f6d0554fffb4 Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Wed, 25 Mar 2020 20:34:34 +0000 Subject: [PATCH] Add a test. --- .../go/dataflow/CallGraph/getACallee.expected | 3 +++ .../semmle/go/dataflow/CallGraph/main.go | 20 +++++++++++++- .../dataflow/CallGraph/viableCallee.expected | 2 ++ .../go/dataflow/CallGraph/viableCallee.ql | 26 +++++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 ql/test/library-tests/semmle/go/dataflow/CallGraph/viableCallee.expected create mode 100644 ql/test/library-tests/semmle/go/dataflow/CallGraph/viableCallee.ql diff --git a/ql/test/library-tests/semmle/go/dataflow/CallGraph/getACallee.expected b/ql/test/library-tests/semmle/go/dataflow/CallGraph/getACallee.expected index 381d576a20b..d097ea413bf 100644 --- a/ql/test/library-tests/semmle/go/dataflow/CallGraph/getACallee.expected +++ b/ql/test/library-tests/semmle/go/dataflow/CallGraph/getACallee.expected @@ -1,2 +1,5 @@ missingCallee spuriousCallee +| main.go:44:3:44:7 | call to m | main.go:17:1:17:17 | function declaration | +| main.go:44:3:44:7 | call to m | main.go:21:1:21:20 | function declaration | +| main.go:56:2:56:6 | call to m | main.go:21:1:21:20 | function declaration | diff --git a/ql/test/library-tests/semmle/go/dataflow/CallGraph/main.go b/ql/test/library-tests/semmle/go/dataflow/CallGraph/main.go index 1a10877b80a..3047f79e9d6 100644 --- a/ql/test/library-tests/semmle/go/dataflow/CallGraph/main.go +++ b/ql/test/library-tests/semmle/go/dataflow/CallGraph/main.go @@ -35,5 +35,23 @@ func test(x *s1, y s2, z s3, b mybool, i I) { } func test2(v interface{}) { - v.(interface{ m(int) }).m(0) // callee: s3.m + v.(interface{ m(int) }).m(0) // callee: s3.m +} + +func test3(v I) { + if v == nil { + v = s1{} + v.m() // callee: s1.m + } + v.m() // callee: s1.m callee: s2.m callee: mybool.m +} + +func test4(b bool) { + var v I + if b { + v = s1{} + } else { + v = &s2{} + } + v.m() // callee: s1.m callee: s2.m } diff --git a/ql/test/library-tests/semmle/go/dataflow/CallGraph/viableCallee.expected b/ql/test/library-tests/semmle/go/dataflow/CallGraph/viableCallee.expected new file mode 100644 index 00000000000..381d576a20b --- /dev/null +++ b/ql/test/library-tests/semmle/go/dataflow/CallGraph/viableCallee.expected @@ -0,0 +1,2 @@ +missingCallee +spuriousCallee diff --git a/ql/test/library-tests/semmle/go/dataflow/CallGraph/viableCallee.ql b/ql/test/library-tests/semmle/go/dataflow/CallGraph/viableCallee.ql new file mode 100644 index 00000000000..132cbf36e4e --- /dev/null +++ b/ql/test/library-tests/semmle/go/dataflow/CallGraph/viableCallee.ql @@ -0,0 +1,26 @@ +import go +import semmle.go.dataflow.internal.DataFlowDispatch + +/** + * Gets a string `val` such that there is a comment on the same line as `l` + * that contains the substring `key: val`. + */ +string metadata(Locatable l, string key) { + exists(string f, int line, Comment c, string kv | + l.hasLocationInfo(f, line, _, _, _) and + c.hasLocationInfo(f, line, _, _, _) and + kv = c.getText().regexpFind("\\b(\\w+: \\S+)", _, _) and + key = kv.regexpCapture("(\\w+): (\\S+)", 1) and + result = kv.regexpCapture("(\\w+): (\\S+)", 2) + ) +} + +query predicate missingCallee(DataFlow::CallNode call, FuncDef callee) { + metadata(call.asExpr(), "callee") = metadata(callee, "name") and + not viableCallable(call.asExpr()) = callee +} + +query predicate spuriousCallee(DataFlow::CallNode call, FuncDef callee) { + viableCallable(call.asExpr()) = callee and + not metadata(call.asExpr(), "callee") = metadata(callee, "name") +}