mirror of
https://github.com/github/codeql.git
synced 2026-04-29 10:45:15 +02:00
Refine Method.implements so that interface methods only implement themselves.
Without this restriction, the two `m`s in the following example are considered to implement each other, even though they aren't logically related:
```go
type I interface {
m()
}
type J interface {
m()
}
type K struct {
I
J
}
```
Previously, interface methods would sometimes implement themselves and sometimes not (see changes to test output for examples).
This commit is contained in:
@@ -406,6 +406,9 @@ class Method extends Function {
|
||||
result = this.getReceiverType().getPackage()
|
||||
}
|
||||
|
||||
/** Holds if this method is declared in an interface. */
|
||||
predicate isInterfaceMethod() { getReceiverType().getUnderlyingType() instanceof InterfaceType }
|
||||
|
||||
/** Gets the receiver variable of this method. */
|
||||
Variable getReceiver() { result = receiver }
|
||||
|
||||
@@ -464,8 +467,14 @@ class Method extends Function {
|
||||
* Holds if this method implements the method `m`, that is, if `m` is a method
|
||||
* on an interface, and this is a method with the same name on a type that
|
||||
* implements that interface.
|
||||
*
|
||||
* Note that all methods implement themselves, and interface methods _only_
|
||||
* implement themselves.
|
||||
*/
|
||||
predicate implements(Method m) {
|
||||
this = m
|
||||
or
|
||||
not isInterfaceMethod() and
|
||||
exists(Type t |
|
||||
this = t.getMethod(m.getName()) and
|
||||
t.implements(m.getReceiverType().getUnderlyingType())
|
||||
|
||||
@@ -23,3 +23,5 @@
|
||||
| types.go:33:16:33:20 | meth1 | types.go:33:16:33:20 | meth1 |
|
||||
| types.go:33:22:33:22 | a | types.go:33:22:33:22 | a |
|
||||
| types.go:37:16:37:20 | meth2 | types.go:37:16:37:20 | meth2 |
|
||||
| types.go:41:6:41:27 | iHaveARedeclaredMethod | types.go:41:6:41:27 | iHaveARedeclaredMethod |
|
||||
| types.go:43:2:43:5 | meth | types.go:43:2:43:5 | meth |
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
| file://:0:0:0:0 | int | <library> | types.go:27:25:27:27 | int |
|
||||
| file://:0:0:0:0 | int | <library> | types.go:33:24:33:26 | int |
|
||||
| file://:0:0:0:0 | int | <library> | types.go:37:24:37:26 | int |
|
||||
| file://:0:0:0:0 | int | <library> | types.go:43:9:43:11 | int |
|
||||
| main.go:5:6:5:6 | t | main.go@5:6:5:6 | main.go:5:6:5:6 | t |
|
||||
| main.go:5:6:5:6 | t | main.go@5:6:5:6 | main.go:13:13:13:13 | t |
|
||||
| main.go:5:6:5:6 | t | main.go@5:6:5:6 | main.go:17:29:17:29 | t |
|
||||
@@ -42,6 +43,7 @@
|
||||
| main.go:23:16:23:19 | bump | main.go@23:16:23:19 | main.go:23:16:23:19 | bump |
|
||||
| types.go:3:6:3:17 | iHaveAMethod | types.go@3:6:3:17 | main.go:17:12:17:23 | iHaveAMethod |
|
||||
| types.go:3:6:3:17 | iHaveAMethod | types.go@3:6:3:17 | types.go:3:6:3:17 | iHaveAMethod |
|
||||
| types.go:3:6:3:17 | iHaveAMethod | types.go@3:6:3:17 | types.go:42:2:42:13 | iHaveAMethod |
|
||||
| types.go:4:2:4:5 | meth | types.go@4:2:4:5 | main.go:18:2:18:7 | selection of meth |
|
||||
| types.go:4:2:4:5 | meth | types.go@4:2:4:5 | main.go:18:4:18:7 | meth |
|
||||
| types.go:4:2:4:5 | meth | types.go@4:2:4:5 | types.go:4:2:4:5 | meth |
|
||||
@@ -65,3 +67,5 @@
|
||||
| types.go:33:22:33:22 | a | types.go@33:22:33:22 | types.go:33:22:33:22 | a |
|
||||
| types.go:33:22:33:22 | a | types.go@33:22:33:22 | types.go:34:9:34:9 | a |
|
||||
| types.go:37:16:37:20 | meth2 | types.go@37:16:37:20 | types.go:37:16:37:20 | meth2 |
|
||||
| types.go:41:6:41:27 | iHaveARedeclaredMethod | types.go@41:6:41:27 | types.go:41:6:41:27 | iHaveARedeclaredMethod |
|
||||
| types.go:43:2:43:5 | meth | types.go@43:2:43:5 | types.go:43:2:43:5 | meth |
|
||||
|
||||
@@ -23,3 +23,5 @@
|
||||
| types.go:33:16:33:20 | meth1 | func(int) bool |
|
||||
| types.go:33:22:33:22 | a | int |
|
||||
| types.go:37:16:37:20 | meth2 | func() int |
|
||||
| types.go:41:6:41:27 | iHaveARedeclaredMethod | iHaveARedeclaredMethod |
|
||||
| types.go:43:2:43:5 | meth | func() int |
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
| iHaveAMethod | meth | iHaveAMethod | meth |
|
||||
| iHaveARedeclaredMethod | meth | iHaveARedeclaredMethod | meth |
|
||||
| meth1Iface | meth1 | meth1Iface | meth1 |
|
||||
| meth1Iface | meth1 | twoMethods | meth1 |
|
||||
| notImpl | meth1 | notImpl | meth1 |
|
||||
| notImpl | meth2 | notImpl | meth2 |
|
||||
| pointer type | bump | pointer type | bump |
|
||||
| pointer type | meth | iHaveAMethod | meth |
|
||||
| pointer type | meth | iHaveARedeclaredMethod | meth |
|
||||
| pointer type | meth | pointer type | meth |
|
||||
| pointer type | meth1 | meth1Iface | meth1 |
|
||||
| pointer type | meth1 | pointer type | meth1 |
|
||||
| pointer type | meth1 | twoMethods | meth1 |
|
||||
| starImpl | meth2 | starImpl | meth2 |
|
||||
| starImpl | meth2 | twoMethods | meth2 |
|
||||
| twoMethods | meth1 | meth1Iface | meth1 |
|
||||
| twoMethods | meth1 | twoMethods | meth1 |
|
||||
| twoMethods | meth2 | twoMethods | meth2 |
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
| iHaveAMethod | meth | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | iHaveAMethod | meth |
|
||||
| iHaveARedeclaredMethod | meth | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | iHaveARedeclaredMethod | meth |
|
||||
| meth1Iface | meth1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | meth1Iface | meth1 |
|
||||
| meth1Iface | meth1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | twoMethods | meth1 |
|
||||
| meth1Iface | meth1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | twoMethodsEmbedded | meth1 |
|
||||
| notImpl | meth1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | notImpl | meth1 |
|
||||
| notImpl | meth2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | notImpl | meth2 |
|
||||
| pointer type | bump | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | t | bump |
|
||||
| pointer type | meth | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | iHaveAMethod | meth |
|
||||
| pointer type | meth | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | iHaveARedeclaredMethod | meth |
|
||||
| pointer type | meth | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | t | meth |
|
||||
| pointer type | meth1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | meth1Iface | meth1 |
|
||||
| pointer type | meth1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | starImpl | meth1 |
|
||||
| pointer type | meth1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | twoMethods | meth1 |
|
||||
| pointer type | meth1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | twoMethodsEmbedded | meth1 |
|
||||
| starImpl | meth2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | starImpl | meth2 |
|
||||
| starImpl | meth2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | twoMethods | meth2 |
|
||||
| starImpl | meth2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | twoMethodsEmbedded | meth2 |
|
||||
| twoMethods | meth1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | meth1Iface | meth1 |
|
||||
| twoMethods | meth1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | twoMethods | meth1 |
|
||||
| twoMethods | meth1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | twoMethodsEmbedded | meth1 |
|
||||
| twoMethods | meth2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | twoMethods | meth2 |
|
||||
| twoMethods | meth2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes | twoMethodsEmbedded | meth2 |
|
||||
|
||||
@@ -10,3 +10,4 @@
|
||||
| types.go:27:17:27:21 | meth2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes.starImpl.meth2 | file://:0:0:0:0 | | starImpl |
|
||||
| types.go:33:16:33:20 | meth1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes.notImpl.meth1 | file://:0:0:0:0 | | notImpl |
|
||||
| types.go:37:16:37:20 | meth2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes.notImpl.meth2 | file://:0:0:0:0 | | notImpl |
|
||||
| types.go:43:2:43:5 | meth | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Scopes.iHaveARedeclaredMethod.meth | file://:0:0:0:0 | | iHaveARedeclaredMethod |
|
||||
|
||||
@@ -2,12 +2,17 @@
|
||||
| * starImpl | twoMethods |
|
||||
| * starImpl | twoMethodsEmbedded |
|
||||
| * t | iHaveAMethod |
|
||||
| * t | iHaveARedeclaredMethod |
|
||||
| iHaveAMethod | iHaveAMethod |
|
||||
| iHaveAMethod | iHaveARedeclaredMethod |
|
||||
| iHaveARedeclaredMethod | iHaveAMethod |
|
||||
| iHaveARedeclaredMethod | iHaveARedeclaredMethod |
|
||||
| interface { meth1 func() bool } | meth1Iface |
|
||||
| interface { meth1 func() bool; meth2 func() int } | meth1Iface |
|
||||
| interface { meth1 func() bool; meth2 func() int } | twoMethods |
|
||||
| interface { meth1 func() bool; meth2 func() int } | twoMethodsEmbedded |
|
||||
| interface { meth func() int } | iHaveAMethod |
|
||||
| interface { meth func() int } | iHaveARedeclaredMethod |
|
||||
| meth1Iface | meth1Iface |
|
||||
| twoMethods | meth1Iface |
|
||||
| twoMethods | twoMethods |
|
||||
|
||||
@@ -37,3 +37,8 @@ func (notImpl) meth1(a int) bool {
|
||||
func (notImpl) meth2() int {
|
||||
return -42
|
||||
}
|
||||
|
||||
type iHaveARedeclaredMethod interface {
|
||||
iHaveAMethod
|
||||
meth() int
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ edges
|
||||
| ReflectedXss.go:11:15:11:20 | selection of Form : Values | ReflectedXss.go:14:44:14:51 | username |
|
||||
| contenttype.go:11:11:11:16 | selection of Form : Values | contenttype.go:17:11:17:22 | type conversion |
|
||||
| contenttype.go:49:11:49:16 | selection of Form : Values | contenttype.go:53:34:53:37 | data |
|
||||
| tst.go:13:15:13:20 | selection of Form : Values | tst.go:17:12:17:39 | type conversion |
|
||||
| tst.go:47:14:47:19 | selection of Form : Values | tst.go:52:12:52:26 | type conversion |
|
||||
| tst.go:14:15:14:20 | selection of Form : Values | tst.go:18:12:18:39 | type conversion |
|
||||
| tst.go:48:14:48:19 | selection of Form : Values | tst.go:53:12:53:26 | type conversion |
|
||||
nodes
|
||||
| ReflectedXss.go:11:15:11:20 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| ReflectedXss.go:14:44:14:51 | username | semmle.label | username |
|
||||
@@ -11,13 +11,13 @@ nodes
|
||||
| contenttype.go:17:11:17:22 | type conversion | semmle.label | type conversion |
|
||||
| contenttype.go:49:11:49:16 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| contenttype.go:53:34:53:37 | data | semmle.label | data |
|
||||
| tst.go:13:15:13:20 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| tst.go:17:12:17:39 | type conversion | semmle.label | type conversion |
|
||||
| tst.go:47:14:47:19 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| tst.go:52:12:52:26 | type conversion | semmle.label | type conversion |
|
||||
| tst.go:14:15:14:20 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| tst.go:18:12:18:39 | type conversion | semmle.label | type conversion |
|
||||
| tst.go:48:14:48:19 | selection of Form : Values | semmle.label | selection of Form : Values |
|
||||
| tst.go:53:12:53:26 | type conversion | semmle.label | type conversion |
|
||||
#select
|
||||
| ReflectedXss.go:14:44:14:51 | username | ReflectedXss.go:11:15:11:20 | selection of Form : Values | ReflectedXss.go:14:44:14:51 | username | Cross-site scripting vulnerability due to $@. | ReflectedXss.go:11:15:11:20 | selection of Form | user-provided value |
|
||||
| contenttype.go:17:11:17:22 | type conversion | contenttype.go:11:11:11:16 | selection of Form : Values | contenttype.go:17:11:17:22 | type conversion | Cross-site scripting vulnerability due to $@. | contenttype.go:11:11:11:16 | selection of Form | user-provided value |
|
||||
| contenttype.go:53:34:53:37 | data | contenttype.go:49:11:49:16 | selection of Form : Values | contenttype.go:53:34:53:37 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:49:11:49:16 | selection of Form | user-provided value |
|
||||
| tst.go:17:12:17:39 | type conversion | tst.go:13:15:13:20 | selection of Form : Values | tst.go:17:12:17:39 | type conversion | Cross-site scripting vulnerability due to $@. | tst.go:13:15:13:20 | selection of Form | user-provided value |
|
||||
| tst.go:52:12:52:26 | type conversion | tst.go:47:14:47:19 | selection of Form : Values | tst.go:52:12:52:26 | type conversion | Cross-site scripting vulnerability due to $@. | tst.go:47:14:47:19 | selection of Form | user-provided value |
|
||||
| tst.go:18:12:18:39 | type conversion | tst.go:14:15:14:20 | selection of Form : Values | tst.go:18:12:18:39 | type conversion | Cross-site scripting vulnerability due to $@. | tst.go:14:15:14:20 | selection of Form | user-provided value |
|
||||
| tst.go:53:12:53:26 | type conversion | tst.go:48:14:48:19 | selection of Form : Values | tst.go:53:12:53:26 | type conversion | Cross-site scripting vulnerability due to $@. | tst.go:48:14:48:19 | selection of Form | user-provided value |
|
||||
|
||||
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
@@ -52,5 +53,19 @@ func serve8() {
|
||||
w.Write([]byte(service))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type mix struct {
|
||||
io.Writer
|
||||
http.ResponseWriter
|
||||
}
|
||||
|
||||
func serve9(log io.Writer) {
|
||||
http.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
username := r.Form.Get("username")
|
||||
// OK: not a ResponseWriter
|
||||
log.Write(username)
|
||||
})
|
||||
http.ListenAndServe(":80", nil)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user