From 57192e8154f49eaa8e216d34979521e0e1d09dfd Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Tue, 29 Oct 2024 15:59:14 +0000 Subject: [PATCH] Add even more tests --- .../mad_PImplEmbedI1_subtypes_true.expected | 3 + .../mad_PImplEmbedI1_subtypes_true.ext.yml | 18 +++ .../mad_PImplEmbedI1_subtypes_true.ql | 26 ++++ .../mad_PImplEmbedI2_subtypes_true.expected | 3 + .../mad_PImplEmbedI2_subtypes_true.ext.yml | 16 +++ .../mad_PImplEmbedI2_subtypes_true.ql | 26 ++++ .../mad_SEmbedP1_subtypes_true.expected | 3 + .../mad_SEmbedP1_subtypes_true.ext.yml | 18 +++ .../mad_SEmbedP1_subtypes_true.ql | 26 ++++ .../mad_SEmbedP2_subtypes_true.expected | 3 + .../mad_SEmbedP2_subtypes_true.ext.yml | 16 +++ .../mad_SEmbedP2_subtypes_true.ql | 26 ++++ .../mad_SEmbedPtrP1_subtypes_true.expected | 3 + .../mad_SEmbedPtrP1_subtypes_true.ext.yml | 18 +++ .../mad_SEmbedPtrP1_subtypes_true.ql | 26 ++++ .../mad_SEmbedPtrP2_subtypes_true.expected | 3 + .../mad_SEmbedPtrP2_subtypes_true.ext.yml | 16 +++ .../mad_SEmbedPtrP2_subtypes_true.ql | 26 ++++ .../mad_SEmbedPtrS1_subtypes_true.expected | 3 + .../mad_SEmbedPtrS1_subtypes_true.ext.yml | 18 +++ .../mad_SEmbedPtrS1_subtypes_true.ql | 26 ++++ .../mad_SEmbedPtrS2_subtypes_true.expected | 3 + .../mad_SEmbedPtrS2_subtypes_true.ext.yml | 16 +++ .../mad_SEmbedPtrS2_subtypes_true.ql | 26 ++++ .../ExternalFlowInheritance/ql_P1.expected | 3 + .../dataflow/ExternalFlowInheritance/ql_P1.ql | 54 ++++++++ .../ExternalFlowInheritance/test_fields.go | 48 ++++++- .../ExternalFlowInheritance/test_methods.go | 74 ++++++++++- .../github.com/nonexistent/test/stub.go | 124 +++++++++++++++--- 29 files changed, 646 insertions(+), 25 deletions(-) create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI1_subtypes_true.expected create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI1_subtypes_true.ext.yml create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI1_subtypes_true.ql create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI2_subtypes_true.expected create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI2_subtypes_true.ext.yml create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI2_subtypes_true.ql create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP1_subtypes_true.expected create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP1_subtypes_true.ext.yml create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP1_subtypes_true.ql create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP2_subtypes_true.expected create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP2_subtypes_true.ext.yml create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP2_subtypes_true.ql create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP1_subtypes_true.expected create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP1_subtypes_true.ext.yml create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP1_subtypes_true.ql create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP2_subtypes_true.expected create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP2_subtypes_true.ext.yml create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP2_subtypes_true.ql create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS1_subtypes_true.expected create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS1_subtypes_true.ext.yml create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS1_subtypes_true.ql create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS2_subtypes_true.expected create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS2_subtypes_true.ext.yml create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS2_subtypes_true.ql create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_P1.expected create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_P1.ql diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI1_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI1_subtypes_true.expected new file mode 100644 index 000000000000..db33d6d2504a --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI1_subtypes_true.expected @@ -0,0 +1,3 @@ +testFailures +invalidModelRow +failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI1_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI1_subtypes_true.ext.yml new file mode 100644 index 000000000000..b7a7badf0979 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI1_subtypes_true.ext.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: sourceModel + data: + - ["github.com/nonexistent/test", "PImplEmbedI1", True, "Source", "", "", "ReturnValue", "qltest", "manual"] + - ["github.com/nonexistent/test", "PImplEmbedI1", True, "SourceField", "", "", "", "qltest", "manual"] + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/nonexistent/test", "PImplEmbedI1", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["github.com/nonexistent/test", "PImplEmbedI1", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] + - ["github.com/nonexistent/test", "PImplEmbedI1", True, "SinkField", "", "", "", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI1_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI1_subtypes_true.ql new file mode 100644 index 000000000000..6e84bbe2ffbf --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI1_subtypes_true.ql @@ -0,0 +1,26 @@ +import go +import ModelValidation +import TestUtilities.InlineExpectationsTest +import MakeTest + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } + + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } +} + +module Flow = TaintTracking::Global; + +module FlowTest implements TestSig { + string getARelevantTag() { result = "PImplEmbedI1[t]" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "PImplEmbedI1[t]" and + exists(DataFlow::Node sink | Flow::flowTo(sink) | + sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = sink.toString() and + value = "" + ) + } +} diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI2_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI2_subtypes_true.expected new file mode 100644 index 000000000000..db33d6d2504a --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI2_subtypes_true.expected @@ -0,0 +1,3 @@ +testFailures +invalidModelRow +failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI2_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI2_subtypes_true.ext.yml new file mode 100644 index 000000000000..2a10c84a20fa --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI2_subtypes_true.ext.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: sourceModel + data: + - ["github.com/nonexistent/test", "PImplEmbedI2", True, "Source", "", "", "ReturnValue", "qltest", "manual"] + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/nonexistent/test", "PImplEmbedI2", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["github.com/nonexistent/test", "PImplEmbedI2", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI2_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI2_subtypes_true.ql new file mode 100644 index 000000000000..63a829d1ac4e --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_PImplEmbedI2_subtypes_true.ql @@ -0,0 +1,26 @@ +import go +import ModelValidation +import TestUtilities.InlineExpectationsTest +import MakeTest + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } + + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } +} + +module Flow = TaintTracking::Global; + +module FlowTest implements TestSig { + string getARelevantTag() { result = "PImplEmbedI2[t]" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "PImplEmbedI2[t]" and + exists(DataFlow::Node sink | Flow::flowTo(sink) | + sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = sink.toString() and + value = "" + ) + } +} diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP1_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP1_subtypes_true.expected new file mode 100644 index 000000000000..db33d6d2504a --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP1_subtypes_true.expected @@ -0,0 +1,3 @@ +testFailures +invalidModelRow +failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP1_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP1_subtypes_true.ext.yml new file mode 100644 index 000000000000..8a927bde1adf --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP1_subtypes_true.ext.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: sourceModel + data: + - ["github.com/nonexistent/test", "SEmbedP1", True, "Source", "", "", "ReturnValue", "qltest", "manual"] + - ["github.com/nonexistent/test", "SEmbedP1", True, "SourceField", "", "", "", "qltest", "manual"] + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/nonexistent/test", "SEmbedP1", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["github.com/nonexistent/test", "SEmbedP1", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] + - ["github.com/nonexistent/test", "SEmbedP1", True, "SinkField", "", "", "", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP1_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP1_subtypes_true.ql new file mode 100644 index 000000000000..35c780f603d0 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP1_subtypes_true.ql @@ -0,0 +1,26 @@ +import go +import ModelValidation +import TestUtilities.InlineExpectationsTest +import MakeTest + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } + + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } +} + +module Flow = TaintTracking::Global; + +module FlowTest implements TestSig { + string getARelevantTag() { result = "SEmbedP1[t]" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "SEmbedP1[t]" and + exists(DataFlow::Node sink | Flow::flowTo(sink) | + sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = sink.toString() and + value = "" + ) + } +} diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP2_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP2_subtypes_true.expected new file mode 100644 index 000000000000..db33d6d2504a --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP2_subtypes_true.expected @@ -0,0 +1,3 @@ +testFailures +invalidModelRow +failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP2_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP2_subtypes_true.ext.yml new file mode 100644 index 000000000000..6357f141b117 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP2_subtypes_true.ext.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: sourceModel + data: + - ["github.com/nonexistent/test", "SEmbedP2", True, "Source", "", "", "ReturnValue", "qltest", "manual"] + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/nonexistent/test", "SEmbedP2", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["github.com/nonexistent/test", "SEmbedP2", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP2_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP2_subtypes_true.ql new file mode 100644 index 000000000000..6b5cad78d8bc --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedP2_subtypes_true.ql @@ -0,0 +1,26 @@ +import go +import ModelValidation +import TestUtilities.InlineExpectationsTest +import MakeTest + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } + + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } +} + +module Flow = TaintTracking::Global; + +module FlowTest implements TestSig { + string getARelevantTag() { result = "SEmbedP2[t]" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "SEmbedP2[t]" and + exists(DataFlow::Node sink | Flow::flowTo(sink) | + sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = sink.toString() and + value = "" + ) + } +} diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP1_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP1_subtypes_true.expected new file mode 100644 index 000000000000..db33d6d2504a --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP1_subtypes_true.expected @@ -0,0 +1,3 @@ +testFailures +invalidModelRow +failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP1_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP1_subtypes_true.ext.yml new file mode 100644 index 000000000000..e34aa2af5351 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP1_subtypes_true.ext.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: sourceModel + data: + - ["github.com/nonexistent/test", "SEmbedPtrP1", True, "Source", "", "", "ReturnValue", "qltest", "manual"] + - ["github.com/nonexistent/test", "SEmbedPtrP1", True, "SourceField", "", "", "", "qltest", "manual"] + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/nonexistent/test", "SEmbedPtrP1", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["github.com/nonexistent/test", "SEmbedPtrP1", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] + - ["github.com/nonexistent/test", "SEmbedPtrP1", True, "SinkField", "", "", "", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP1_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP1_subtypes_true.ql new file mode 100644 index 000000000000..344dc37e41a4 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP1_subtypes_true.ql @@ -0,0 +1,26 @@ +import go +import ModelValidation +import TestUtilities.InlineExpectationsTest +import MakeTest + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } + + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } +} + +module Flow = TaintTracking::Global; + +module FlowTest implements TestSig { + string getARelevantTag() { result = "SEmbedPtrP1[t]" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "SEmbedPtrP1[t]" and + exists(DataFlow::Node sink | Flow::flowTo(sink) | + sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = sink.toString() and + value = "" + ) + } +} diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP2_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP2_subtypes_true.expected new file mode 100644 index 000000000000..db33d6d2504a --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP2_subtypes_true.expected @@ -0,0 +1,3 @@ +testFailures +invalidModelRow +failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP2_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP2_subtypes_true.ext.yml new file mode 100644 index 000000000000..7c03fc22bcbb --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP2_subtypes_true.ext.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: sourceModel + data: + - ["github.com/nonexistent/test", "SEmbedPtrP2", True, "Source", "", "", "ReturnValue", "qltest", "manual"] + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/nonexistent/test", "SEmbedPtrP2", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["github.com/nonexistent/test", "SEmbedPtrP2", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP2_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP2_subtypes_true.ql new file mode 100644 index 000000000000..a7c2e497f556 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrP2_subtypes_true.ql @@ -0,0 +1,26 @@ +import go +import ModelValidation +import TestUtilities.InlineExpectationsTest +import MakeTest + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } + + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } +} + +module Flow = TaintTracking::Global; + +module FlowTest implements TestSig { + string getARelevantTag() { result = "SEmbedPtrP2[t]" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "SEmbedPtrP2[t]" and + exists(DataFlow::Node sink | Flow::flowTo(sink) | + sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = sink.toString() and + value = "" + ) + } +} diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS1_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS1_subtypes_true.expected new file mode 100644 index 000000000000..db33d6d2504a --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS1_subtypes_true.expected @@ -0,0 +1,3 @@ +testFailures +invalidModelRow +failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS1_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS1_subtypes_true.ext.yml new file mode 100644 index 000000000000..81a3500562d3 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS1_subtypes_true.ext.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: sourceModel + data: + - ["github.com/nonexistent/test", "SEmbedPtrS1", True, "Source", "", "", "ReturnValue", "qltest", "manual"] + - ["github.com/nonexistent/test", "SEmbedPtrS1", True, "SourceField", "", "", "", "qltest", "manual"] + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/nonexistent/test", "SEmbedPtrS1", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["github.com/nonexistent/test", "SEmbedPtrS1", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] + - ["github.com/nonexistent/test", "SEmbedPtrS1", True, "SinkField", "", "", "", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS1_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS1_subtypes_true.ql new file mode 100644 index 000000000000..cf847c781bcc --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS1_subtypes_true.ql @@ -0,0 +1,26 @@ +import go +import ModelValidation +import TestUtilities.InlineExpectationsTest +import MakeTest + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } + + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } +} + +module Flow = TaintTracking::Global; + +module FlowTest implements TestSig { + string getARelevantTag() { result = "SEmbedPtrS1[t]" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "SEmbedPtrS1[t]" and + exists(DataFlow::Node sink | Flow::flowTo(sink) | + sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = sink.toString() and + value = "" + ) + } +} diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS2_subtypes_true.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS2_subtypes_true.expected new file mode 100644 index 000000000000..db33d6d2504a --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS2_subtypes_true.expected @@ -0,0 +1,3 @@ +testFailures +invalidModelRow +failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS2_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS2_subtypes_true.ext.yml new file mode 100644 index 000000000000..50c72d96ce18 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS2_subtypes_true.ext.yml @@ -0,0 +1,16 @@ +extensions: + - addsTo: + pack: codeql/go-all + extensible: sourceModel + data: + - ["github.com/nonexistent/test", "SEmbedPtrS2", True, "Source", "", "", "ReturnValue", "qltest", "manual"] + - addsTo: + pack: codeql/go-all + extensible: summaryModel + data: + - ["github.com/nonexistent/test", "SEmbedPtrS2", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"] + - addsTo: + pack: codeql/go-all + extensible: sinkModel + data: + - ["github.com/nonexistent/test", "SEmbedPtrS2", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS2_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS2_subtypes_true.ql new file mode 100644 index 000000000000..0c7b05dd3ff8 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedPtrS2_subtypes_true.ql @@ -0,0 +1,26 @@ +import go +import ModelValidation +import TestUtilities.InlineExpectationsTest +import MakeTest + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } + + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } +} + +module Flow = TaintTracking::Global; + +module FlowTest implements TestSig { + string getARelevantTag() { result = "SEmbedPtrS2[t]" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "SEmbedPtrS2[t]" and + exists(DataFlow::Node sink | Flow::flowTo(sink) | + sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = sink.toString() and + value = "" + ) + } +} diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_P1.expected b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_P1.expected new file mode 100644 index 000000000000..db33d6d2504a --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_P1.expected @@ -0,0 +1,3 @@ +testFailures +invalidModelRow +failures diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_P1.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_P1.ql new file mode 100644 index 000000000000..3022e13ff749 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_P1.ql @@ -0,0 +1,54 @@ +import go +import ModelValidation +import TestUtilities.InlineExpectationsTest +import MakeTest + +module Config implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { + exists(Method m | + m.hasQualifiedName("github.com/nonexistent/test", "P1", "Source") and + source = m.getACall().getResult() + ) + or + exists(Field f | + f.hasQualifiedName("github.com/nonexistent/test", "P1", "SourceField") and + source = f.getARead() + ) + } + + predicate isSink(DataFlow::Node sink) { + exists(Method m | + m.hasQualifiedName("github.com/nonexistent/test", "P1", "Sink") and + sink = m.getACall().getArgument(0) + ) + or + exists(Field f | + f.hasQualifiedName("github.com/nonexistent/test", "P1", "SinkField") and + any(DataFlow::Write w).writesField(_, f, sink) + ) + } +} + +module Flow = TaintTracking::Global; + +module FlowTest implements TestSig { + string getARelevantTag() { result = "ql_P1" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "ql_P1" and + exists(DataFlow::Node sink | Flow::flowTo(sink) | + sink.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(), + location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and + element = sink.toString() and + value = "" + ) + } +} + +class MyStep extends DataFlow::FunctionModel, Method { + MyStep() { this.hasQualifiedName("github.com/nonexistent/test", "P1", "Step") } + + override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { + input.isParameter(0) and output.isResult() + } +} diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/test_fields.go b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/test_fields.go index 4b6972d67917..86d5828ce120 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/test_fields.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/test_fields.go @@ -4,9 +4,14 @@ import ( "github.com/nonexistent/test" ) +func TestFieldsP1(t test.P1) { + a := t.SourceField + t.SinkField = a // $ P1[f] P1[t] ql_P1 SPURIOUS: ql_S1 +} + func TestFieldsS1(t test.S1) { a := t.SourceField - t.SinkField = a // $ S1[f] S1[t] ql_S1 + t.SinkField = a // $ S1[f] S1[t] ql_S1 SPURIOUS: ql_P1 } func TestFieldsSEmbedI1(t test.SEmbedI1) { @@ -19,9 +24,29 @@ func TestFieldsSImplEmbedI1(t test.SImplEmbedI1) { t.SinkField = a // $ SImplEmbedI1[t] } +func TestFieldsPImplEmbedI1(t test.PImplEmbedI1) { + a := t.SourceField + t.SinkField = a // $ PImplEmbedI1[t] +} + +func TestFieldsSEmbedP1(t test.SEmbedP1) { + a := t.SourceField + t.SinkField = a // $ P1[t] SEmbedP1[t] ql_P1 SPURIOUS: ql_S1 +} + func TestFieldsSEmbedS1(t test.SEmbedS1) { a := t.SourceField - t.SinkField = a // $ S1[t] SEmbedS1[t] ql_S1 + t.SinkField = a // $ S1[t] SEmbedS1[t] ql_S1 SPURIOUS: ql_P1 +} + +func TestFieldsSEmbedPtrP1(t test.SEmbedPtrP1) { + a := t.SourceField + t.SinkField = a // $ P1[t] SEmbedPtrP1[t] ql_P1 SPURIOUS: ql_S1 +} + +func TestFieldsSEmbedPtrS1(t test.SEmbedPtrS1) { + a := t.SourceField + t.SinkField = a // $ S1[t] SEmbedPtrS1[t] ql_S1 SPURIOUS: ql_P1 } func TestFieldsSImplEmbedS1(t test.SImplEmbedS1) { @@ -36,10 +61,25 @@ func TestFieldsSEmbedSEmbedI1(t test.SEmbedSEmbedI1) { func TestFieldsSEmbedSEmbedS1(t test.SEmbedSEmbedS1) { a := t.SourceField - t.SinkField = a // $ S1[t] ql_S1 SEmbedS1[t] + t.SinkField = a // $ S1[t] SEmbedS1[t] ql_S1 SPURIOUS: ql_P1 +} + +func TestFieldsSEmbedSEmbedPtrS1(t test.SEmbedSEmbedPtrS1) { + a := t.SourceField + t.SinkField = a // $ S1[t] SEmbedPtrS1[t] ql_S1 SPURIOUS: ql_P1 +} + +func TestFieldsSEmbedPtrSEmbedS1(t test.SEmbedPtrSEmbedS1) { + a := t.SourceField + t.SinkField = a // $ S1[t] SEmbedS1[t] ql_S1 SPURIOUS: ql_P1 +} + +func TestFieldsSEmbedPtrSEmbedPtrS1(t test.SEmbedPtrSEmbedPtrS1) { + a := t.SourceField + t.SinkField = a // $ S1[t] SEmbedPtrS1[t] ql_S1 SPURIOUS: ql_P1 } func TestFieldsSEmbedS1AndSEmbedS1(t test.SEmbedS1AndSEmbedS1) { a := t.SourceField - t.SinkField = a // $ S1[t] ql_S1 + t.SinkField = a // $ S1[t] ql_S1 SPURIOUS: ql_P1 } diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/test_methods.go b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/test_methods.go index a106e4ee9d69..8d4c592e0cd1 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/test_methods.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/test_methods.go @@ -7,7 +7,7 @@ import ( func TestMethodsI1(t test.I1) { x := t.Source() y := t.Step(x) - t.Sink(y) // $ I1[f] I1[t] ql_I1 SPURIOUS: ql_S1 + t.Sink(y) // $ I1[f] I1[t] ql_I1 SPURIOUS: ql_P1 ql_S1 } func TestMethodsI2(t test.I2) { @@ -22,16 +22,28 @@ func TestMethodsS1(t test.S1) { t.Sink(y) // $ I1[t] S1[f] S1[t] ql_S1 } +func TestMethodsP1(t test.P1) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] P1[f] P1[t] ql_P1 +} + func TestMethodsS2(t test.S2) { x := t.Source() y := t.Step(x) t.Sink(y) // $ I1[t] I2[t] } +func TestMethodsP2(t test.P2) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] I2[t] +} + func TestMethodsSEmbedI1(t test.SEmbedI1) { x := t.Source() y := t.Step(x) - t.Sink(y) // $ I1[t] SEmbedI1[t] ql_I1 SPURIOUS: ql_S1 + t.Sink(y) // $ I1[t] SEmbedI1[t] ql_I1 SPURIOUS: ql_P1 ql_S1 } func TestMethodsSEmbedI2(t test.SEmbedI2) { @@ -43,7 +55,7 @@ func TestMethodsSEmbedI2(t test.SEmbedI2) { func TestMethodsIEmbedI1(t test.IEmbedI1) { x := t.Source() y := t.Step(x) - t.Sink(y) // $ I1[t] IEmbedI1[t] ql_I1 SPURIOUS: ql_S1 + t.Sink(y) // $ I1[t] IEmbedI1[t] ql_I1 SPURIOUS: ql_P1 ql_S1 } func TestMethodsIEmbedI2(t test.IEmbedI2) { @@ -64,6 +76,18 @@ func TestMethodsSImplEmbedI2(t test.SImplEmbedI2) { t.Sink(y) // $ I1[t] I2[t] SImplEmbedI2[t] } +func TestMethodsPImplEmbedI1(t test.PImplEmbedI1) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] PImplEmbedI1[t] +} + +func TestMethodsPImplEmbedI2(t test.PImplEmbedI2) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] I2[t] PImplEmbedI2[t] +} + func TestMethodsSEmbedS1(t test.SEmbedS1) { x := t.Source() y := t.Step(x) @@ -76,6 +100,30 @@ func TestMethodsSEmbedS2(t test.SEmbedS2) { t.Sink(y) // $ I1[t] I2[t] SEmbedS2[t] } +func TestMethodsSEmbedPtrS1(t test.SEmbedPtrS1) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] S1[t] SEmbedPtrS1[t] ql_S1 +} + +func TestMethodsSEmbedPtrS2(t test.SEmbedPtrS2) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] I2[t] SEmbedPtrS2[t] +} + +func TestMethodsSEmbedP1(t *test.SEmbedP1) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] P1[t] SEmbedP1[t] ql_P1 +} + +func TestMethodsSEmbedP2(t *test.SEmbedP2) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] I2[t] SEmbedP2[t] +} + func TestMethodsSImplEmbedS1(t test.SImplEmbedS1) { x := t.Source() y := t.Step(x) @@ -91,7 +139,7 @@ func TestMethodsSImplEmbedS2(t test.SImplEmbedS2) { func TestMethodsSEmbedSEmbedI1(t test.SEmbedSEmbedI1) { x := t.Source() y := t.Step(x) - t.Sink(y) // $ I1[t] SEmbedI1[t] ql_I1 SPURIOUS: ql_S1 + t.Sink(y) // $ I1[t] SEmbedI1[t] ql_I1 SPURIOUS: ql_P1 ql_S1 } func TestMethodsSEmbedSEmbedS1(t test.SEmbedSEmbedS1) { @@ -100,6 +148,24 @@ func TestMethodsSEmbedSEmbedS1(t test.SEmbedSEmbedS1) { t.Sink(y) // $ I1[t] S1[t] SEmbedS1[t] ql_S1 } +func TestMethodsSEmbedSEmbedPtrS1(t test.SEmbedSEmbedPtrS1) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] S1[t] SEmbedPtrS1[t] ql_S1 +} + +func TestMethodsSEmbedPtrSEmbedS1(t test.SEmbedPtrSEmbedS1) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] S1[t] SEmbedS1[t] ql_S1 +} + +func TestMethodsSEmbedPtrSEmbedPtrS1(t test.SEmbedPtrSEmbedPtrS1) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] S1[t] SEmbedPtrS1[t] ql_S1 +} + func TestMethodsSEmbedS1AndSEmbedS1(t test.SEmbedS1AndSEmbedS1) { x := t.Source() y := t.Step(x) diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/vendor/github.com/nonexistent/test/stub.go b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/vendor/github.com/nonexistent/test/stub.go index f2ee55d438ea..093c24eab9d9 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/vendor/github.com/nonexistent/test/stub.go +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/vendor/github.com/nonexistent/test/stub.go @@ -21,30 +21,61 @@ type S1 struct { SinkField string } -func (t *S1) Source() interface{} { +func (t S1) Source() interface{} { return nil } -func (t *S1) Sink(interface{}) {} +func (t S1) Sink(interface{}) {} -func (t *S1) Step(val interface{}) interface{} { +func (t S1) Step(val interface{}) interface{} { + return val +} + +// A struct type whose pointer type implements I1 +type P1 struct { + SourceField string + SinkField string +} + +func (t *P1) Source() interface{} { + return nil +} + +func (t *P1) Sink(interface{}) {} + +func (t *P1) Step(val interface{}) interface{} { return val } // A struct type implementing I2 type S2 struct{} -func (t *S2) Source() interface{} { +func (t S2) Source() interface{} { + return nil +} + +func (t S2) Sink(interface{}) {} + +func (t S2) Step(val interface{}) interface{} { + return val +} + +func (t S2) ExtraMethodI2() {} + +// A struct type whose pointer type implements I2 +type P2 struct{} + +func (t *P2) Source() interface{} { return nil } -func (t *S2) Sink(interface{}) {} +func (t *P2) Sink(interface{}) {} -func (t *S2) Step(val interface{}) interface{} { +func (t *P2) Step(val interface{}) interface{} { return val } -func (t *S2) ExtraMethodI2() {} +func (t *P2) ExtraMethodI2() {} // A struct type embedding I1 type SEmbedI1 struct { @@ -76,13 +107,13 @@ type SImplEmbedI1 struct { SinkField string } -func (t *SImplEmbedI1) Source() interface{} { +func (t SImplEmbedI1) Source() interface{} { return nil } -func (t *SImplEmbedI1) Sink(interface{}) {} +func (t SImplEmbedI1) Sink(interface{}) {} -func (t *SImplEmbedI1) Step(val interface{}) interface{} { +func (t SImplEmbedI1) Step(val interface{}) interface{} { return val } @@ -90,26 +121,76 @@ func (t *SImplEmbedI1) Step(val interface{}) interface{} { // methods of the embedded field are not promoted. type SImplEmbedI2 struct{ I2 } -func (t *SImplEmbedI2) Source() interface{} { +func (t SImplEmbedI2) Source() interface{} { return nil } -func (t *SImplEmbedI2) Sink(interface{}) {} +func (t SImplEmbedI2) Sink(interface{}) {} -func (t *SImplEmbedI2) Step(val interface{}) interface{} { +func (t SImplEmbedI2) Step(val interface{}) interface{} { return val } -func (t *SImplEmbedI2) ExtraMethodI2() {} +func (t SImplEmbedI2) ExtraMethodI2() {} -// A struct type embedding S1 -type SEmbedS1 struct { - S1 +// A struct type embedding I1 and separately implementing its methods on its +// pointer type, so the methods of the embedded field are not promoted. +type PImplEmbedI1 struct { + I1 + SourceField string + SinkField string +} + +func (t *PImplEmbedI1) Source() interface{} { + return nil } +func (t *PImplEmbedI1) Sink(interface{}) {} + +func (t *PImplEmbedI1) Step(val interface{}) interface{} { + return val +} + +// A struct type embedding I2 and separately implementing its methods, so the +// methods of the embedded field are not promoted. +type PImplEmbedI2 struct{ I2 } + +func (t *PImplEmbedI2) Source() interface{} { + return nil +} + +func (t *PImplEmbedI2) Sink(interface{}) {} + +func (t *PImplEmbedI2) Step(val interface{}) interface{} { + return val +} + +func (t *PImplEmbedI2) ExtraMethodI2() {} + +// A struct type embedding S1 +type SEmbedS1 struct{ S1 } + // A struct type embedding S2 type SEmbedS2 struct{ S2 } +// A struct type embedding P1 +type SEmbedP1 struct{ P1 } + +// A struct type embedding P2 +type SEmbedP2 struct{ P2 } + +// A struct type embedding *S1 +type SEmbedPtrS1 struct{ *S1 } + +// A struct type embedding *S2 +type SEmbedPtrS2 struct{ *S2 } + +// A struct type embedding *P1 +type SEmbedPtrP1 struct{ *P1 } + +// A struct type embedding *P2 +type SEmbedPtrP2 struct{ *P2 } + // A struct type embedding S1 and separately implementing I1's methods and // fields, so the methods and fields of the embedded field are not promoted. type SImplEmbedS1 struct { @@ -154,6 +235,15 @@ type SEmbedSEmbedI1 struct { // A struct type embedding SEmbedS1 type SEmbedSEmbedS1 struct{ SEmbedS1 } +// A struct type embedding SEmbedPtrS1 +type SEmbedSEmbedPtrS1 struct{ SEmbedPtrS1 } + +// A struct type embedding SEmbedS1 +type SEmbedPtrSEmbedS1 struct{ *SEmbedS1 } + +// A struct type embedding SEmbedPtrS1 +type SEmbedPtrSEmbedPtrS1 struct{ *SEmbedPtrS1 } + // A struct type embedding S1 and SEmbedS1 type SEmbedS1AndSEmbedS1 struct { S1