From a6d8deae3efa53ac317147e7fdf9624b7aa3a783 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 30 Nov 2021 15:07:57 -0500 Subject: [PATCH 1/3] Add Fmt.Fprint to isVariadic tests We didn't have any tests involving a function in an imported package. --- .../semmle/go/Function/getParameter.expected | 2 +- .../semmle/go/Function/variadicFunctions.go | 11 +++++++---- .../go/Types/SignatureType_getNumParameter.expected | 6 +++--- .../go/Types/SignatureType_getNumResult.expected | 6 +++--- .../semmle/go/Types/variadicFunctions.go | 3 +++ 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/ql/test/library-tests/semmle/go/Function/getParameter.expected b/ql/test/library-tests/semmle/go/Function/getParameter.expected index 017a6e25615..f936c81bccb 100644 --- a/ql/test/library-tests/semmle/go/Function/getParameter.expected +++ b/ql/test/library-tests/semmle/go/Function/getParameter.expected @@ -9,4 +9,4 @@ | main.go:13:6:13:7 | f4 | 1 | main.go:13:16:13:16 | y | | main.go:15:6:15:7 | f5 | 0 | main.go:15:9:15:9 | x | | main.go:17:6:17:7 | f6 | 0 | main.go:17:9:17:9 | x | -| variadicFunctions.go:7:6:7:29 | variadicDeclaredFunction | 0 | variadicFunctions.go:7:31:7:31 | x | +| variadicFunctions.go:9:6:9:29 | variadicDeclaredFunction | 0 | variadicFunctions.go:9:31:9:31 | x | diff --git a/ql/test/library-tests/semmle/go/Function/variadicFunctions.go b/ql/test/library-tests/semmle/go/Function/variadicFunctions.go index e59d604c89f..3e67696fb9b 100644 --- a/ql/test/library-tests/semmle/go/Function/variadicFunctions.go +++ b/ql/test/library-tests/semmle/go/Function/variadicFunctions.go @@ -1,14 +1,17 @@ package main +import "fmt" + func testing() { variadicDeclaredFunction() // $ isVariadic } func variadicDeclaredFunction(x ...int) int { - a := make([]int, 0, 10) // $ isVariadic - y := append(x, a...) // $ isVariadic - print(x[0], x[1]) // $ isVariadic - println(x[0], x[1]) // $ isVariadic + a := make([]int, 0, 10) // $ isVariadic + y := append(x, a...) // $ isVariadic + print(x[0], x[1]) // $ isVariadic + println(x[0], x[1]) // $ isVariadic + fmt.Fprint(nil, nil, nil) // $ MISSING: isVariadic variadicFunctionLiteral := func(z ...int) int { return z[1] } return variadicFunctionLiteral(y...) } diff --git a/ql/test/library-tests/semmle/go/Types/SignatureType_getNumParameter.expected b/ql/test/library-tests/semmle/go/Types/SignatureType_getNumParameter.expected index 60da0aa607b..8f37acd169e 100644 --- a/ql/test/library-tests/semmle/go/Types/SignatureType_getNumParameter.expected +++ b/ql/test/library-tests/semmle/go/Types/SignatureType_getNumParameter.expected @@ -10,6 +10,6 @@ | pkg1/tst.go:37:1:37:26 | function declaration | 1 | | pkg1/tst.go:39:1:57:1 | function declaration | 2 | | unknownFunction.go:8:1:12:1 | function declaration | 0 | -| variadicFunctions.go:3:1:5:1 | function declaration | 0 | -| variadicFunctions.go:7:1:14:1 | function declaration | 1 | -| variadicFunctions.go:12:29:12:62 | function literal | 1 | +| variadicFunctions.go:5:1:7:1 | function declaration | 0 | +| variadicFunctions.go:9:1:17:1 | function declaration | 1 | +| variadicFunctions.go:15:29:15:62 | function literal | 1 | diff --git a/ql/test/library-tests/semmle/go/Types/SignatureType_getNumResult.expected b/ql/test/library-tests/semmle/go/Types/SignatureType_getNumResult.expected index ec710fe2877..d8ca39a591f 100644 --- a/ql/test/library-tests/semmle/go/Types/SignatureType_getNumResult.expected +++ b/ql/test/library-tests/semmle/go/Types/SignatureType_getNumResult.expected @@ -10,6 +10,6 @@ | pkg1/tst.go:37:1:37:26 | function declaration | 0 | | pkg1/tst.go:39:1:57:1 | function declaration | 0 | | unknownFunction.go:8:1:12:1 | function declaration | 0 | -| variadicFunctions.go:3:1:5:1 | function declaration | 0 | -| variadicFunctions.go:7:1:14:1 | function declaration | 1 | -| variadicFunctions.go:12:29:12:62 | function literal | 1 | +| variadicFunctions.go:5:1:7:1 | function declaration | 0 | +| variadicFunctions.go:9:1:17:1 | function declaration | 1 | +| variadicFunctions.go:15:29:15:62 | function literal | 1 | diff --git a/ql/test/library-tests/semmle/go/Types/variadicFunctions.go b/ql/test/library-tests/semmle/go/Types/variadicFunctions.go index fa356f95dcb..a90190d74ad 100644 --- a/ql/test/library-tests/semmle/go/Types/variadicFunctions.go +++ b/ql/test/library-tests/semmle/go/Types/variadicFunctions.go @@ -1,5 +1,7 @@ package main +import "fmt" + func testing() { variadicDeclaredFunction() } @@ -9,6 +11,7 @@ func variadicDeclaredFunction(x ...int) int { // $ isVariadic y := append(x, a...) print(x[0], x[1]) println(x[0], x[1]) + fmt.Fprint(nil, nil, nil) variadicFunctionLiteral := func(z ...int) int { return z[1] } // $ isVariadic return variadicFunctionLiteral(y...) } From acc5c4098a827d6ac8b3621eef9cdba8c49ef2b5 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 30 Nov 2021 15:11:34 -0500 Subject: [PATCH 2/3] Fix `Function.isVariadic` to work on external packages Going via `getFuncDecl()` didn't work as we don't function declarations from external packages. It works to use `getType()` instead. --- ql/lib/semmle/go/Scopes.qll | 2 +- ql/test/library-tests/semmle/go/Function/variadicFunctions.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ql/lib/semmle/go/Scopes.qll b/ql/lib/semmle/go/Scopes.qll index d10f5d80919..4553b66ea7c 100644 --- a/ql/lib/semmle/go/Scopes.qll +++ b/ql/lib/semmle/go/Scopes.qll @@ -380,7 +380,7 @@ class Function extends ValueEntity, @functionobject { predicate isVariadic() { this.(BuiltinFunction).getName() = ["append", "make", "print", "println"] or - this.(DeclaredFunction).getFuncDecl().isVariadic() + this.(DeclaredFunction).getType().(SignatureType).isVariadic() } /** Holds if this function has no observable side effects. */ diff --git a/ql/test/library-tests/semmle/go/Function/variadicFunctions.go b/ql/test/library-tests/semmle/go/Function/variadicFunctions.go index 3e67696fb9b..75c35aa96e3 100644 --- a/ql/test/library-tests/semmle/go/Function/variadicFunctions.go +++ b/ql/test/library-tests/semmle/go/Function/variadicFunctions.go @@ -11,7 +11,7 @@ func variadicDeclaredFunction(x ...int) int { y := append(x, a...) // $ isVariadic print(x[0], x[1]) // $ isVariadic println(x[0], x[1]) // $ isVariadic - fmt.Fprint(nil, nil, nil) // $ MISSING: isVariadic + fmt.Fprint(nil, nil, nil) // $ isVariadic variadicFunctionLiteral := func(z ...int) int { return z[1] } return variadicFunctionLiteral(y...) } From e08007b28737b5b888aaadbb476745d6d1b4eae4 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 30 Nov 2021 15:12:02 -0500 Subject: [PATCH 3/3] Add missing qldocs for two `isVariadic()` predicates --- ql/lib/semmle/go/Decls.qll | 1 + ql/lib/semmle/go/Scopes.qll | 1 + 2 files changed, 2 insertions(+) diff --git a/ql/lib/semmle/go/Decls.qll b/ql/lib/semmle/go/Decls.qll index ad439a4d7dd..3e3d5d1b831 100644 --- a/ql/lib/semmle/go/Decls.qll +++ b/ql/lib/semmle/go/Decls.qll @@ -137,6 +137,7 @@ class FuncDef extends @funcdef, StmtParent, ExprParent { */ DataFlow::CallNode getACall() { result.getACallee() = this } + /** Holds if this function is variadic. */ predicate isVariadic() { this.getType().isVariadic() } override string getAPrimaryQlClass() { result = "FuncDef" } diff --git a/ql/lib/semmle/go/Scopes.qll b/ql/lib/semmle/go/Scopes.qll index 4553b66ea7c..cb3468150f4 100644 --- a/ql/lib/semmle/go/Scopes.qll +++ b/ql/lib/semmle/go/Scopes.qll @@ -377,6 +377,7 @@ class Function extends ValueEntity, @functionobject { /** Gets the declaration of this function, if any. */ FuncDecl getFuncDecl() { none() } + /** Holds if this function is variadic. */ predicate isVariadic() { this.(BuiltinFunction).getName() = ["append", "make", "print", "println"] or