Add tests for promoted methods

We need implicit field reads for calls to promoted methods.
False negative flags have been added to make this pass on main.
This commit is contained in:
Owen Mansel-Chan
2021-03-24 15:27:54 +00:00
parent 42300819a5
commit 770c770a8f
3 changed files with 120 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
import go
import TestUtilities.InlineExpectationsTest
class SourceFunction extends Function {
SourceFunction() { this.getName() = "source" }
}
class SinkFunction extends Function {
SinkFunction() { this.getName() = "sink" }
}
class TestConfig extends DataFlow::Configuration {
TestConfig() { this = "testconfig" }
override predicate isSource(DataFlow::Node source) {
source = any(SourceFunction f).getACall().getAResult()
}
override predicate isSink(DataFlow::Node sink) {
sink = any(SinkFunction f).getACall().getAnArgument()
}
}
class PromotedMethodsTest extends InlineExpectationsTest {
PromotedMethodsTest() { this = "PromotedMethodsTest" }
override string getARelevantTag() { result = "promotedmethods" }
override predicate hasActualResult(string file, int line, string element, string tag, string value) {
exists(TestConfig config, DataFlow::Node source, DataFlow::Node sink |
config.hasFlow(source, sink)
|
sink.hasLocationInfo(file, line, _, _, _) and
element = sink.toString() and
value = source.getEnclosingCallable().getName() and
tag = "promotedmethods"
)
}
}

View File

@@ -0,0 +1,81 @@
package main
func source() string {
return "hello world"
}
func sink(s string) {}
type Embedded struct {
field string
}
type Base1 struct {
Embedded
}
type Base2 struct {
*Embedded
}
func (e Embedded) sinkFieldOnEmbeddedNonPointerReceiver() {
sink(e.field) // $promotedmethods=nonPointerSender1 $promotedmethods=pointerSender1 $promotedmethods=nonPointerSender2 $promotedmethods=pointerSender2
}
func (e *Embedded) sinkFieldOnEmbeddedPointerReceiver() {
sink(e.field) // $f-:promotedmethods=nonPointerSender1 $f-:promotedmethods=pointerSender1 $f-:promotedmethods=nonPointerSender2 $f-:promotedmethods=pointerSender2
}
func (base1 Base1) sinkFieldOnBase1NonPointerReceiver() {
sink(base1.field) // $promotedmethods=nonPointerSender1 $promotedmethods=pointerSender1
}
func (base1 *Base1) sinkFieldOnBase1PointerReceiver() {
sink(base1.field) // $f-:promotedmethods=nonPointerSender1 $promotedmethods=pointerSender1
}
func (base2 Base2) sinkFieldOnBase2NonPointerReceiver() {
sink(base2.field) // $promotedmethods=nonPointerSender2 $promotedmethods=pointerSender2
}
func (base2 *Base2) sinkFieldOnBase2PointerReceiver() {
sink(base2.field) // $f-:promotedmethods=nonPointerSender2 $promotedmethods=pointerSender2
}
func nonPointerSender1() {
var base1 Base1
base1.field = source()
base1.sinkFieldOnEmbeddedNonPointerReceiver()
base1.sinkFieldOnEmbeddedPointerReceiver()
base1.sinkFieldOnBase1NonPointerReceiver()
base1.sinkFieldOnBase1PointerReceiver()
}
func pointerSender1() {
var base1 Base1
base1.field = source()
base1p := &base1
base1p.sinkFieldOnEmbeddedNonPointerReceiver()
base1p.sinkFieldOnEmbeddedPointerReceiver()
base1p.sinkFieldOnBase1NonPointerReceiver()
base1p.sinkFieldOnBase1PointerReceiver()
}
func nonPointerSender2() {
var base2 Base2
base2.field = source()
base2.sinkFieldOnEmbeddedNonPointerReceiver()
base2.sinkFieldOnEmbeddedPointerReceiver()
base2.sinkFieldOnBase2NonPointerReceiver()
base2.sinkFieldOnBase2PointerReceiver()
}
func pointerSender2() {
var base2 Base2
base2.field = source()
base2p := &base2
base2p.sinkFieldOnEmbeddedNonPointerReceiver()
base2p.sinkFieldOnEmbeddedPointerReceiver()
base2p.sinkFieldOnBase2NonPointerReceiver()
base2p.sinkFieldOnBase2PointerReceiver()
}