mirror of
https://github.com/github/codeql.git
synced 2026-07-21 03:08:25 +02:00
Merge pull request #17505 from owen-mc/go/inheritance-tests
Go: Add tests for model inheritance and fix bug in promoted methods
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* A method in the method set of an embedded field of a struct should not be promoted to the method set of the struct if the struct has a method with the same name. This was not being enforced, which meant that there were two methods with the same qualified name, and models were sometimes being applied when they shouldn't have been. This has now been fixed.
|
||||
@@ -1011,7 +1011,7 @@ class NamedType extends @namedtype, CompositeType {
|
||||
s.hasOwnField(_, _, embedded, true) and
|
||||
// ensure `m` can be promoted
|
||||
not s.hasOwnField(_, m, _, _) and
|
||||
not exists(Method m2 | m2.getReceiverType() = this and m2.getName() = m)
|
||||
not exists(Method m2 | m2.getReceiverBaseType() = this and m2.getName() = m)
|
||||
|
|
||||
// If S contains an embedded field T, the method set of S includes promoted methods with receiver T
|
||||
result = embedded.getMethod(m)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
module semmle.go.Packages
|
||||
|
||||
go 1.21
|
||||
|
||||
require github.com/nonexistent/test v0.0.0-20200203000000-0000000000000
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,16 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "IEmbedI1", True, "Source", "", "", "ReturnValue", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "IEmbedI1", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "IEmbedI1", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
@@ -0,0 +1,28 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "IEmbedI1[t]" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "IEmbedI1[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 = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,16 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "IEmbedI2", True, "Source", "", "", "ReturnValue", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "IEmbedI2", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "IEmbedI2", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
@@ -0,0 +1,28 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "IEmbedI2[t]" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "IEmbedI2[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 = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,16 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SEmbedI1", True, "Source", "", "", "ReturnValue", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SEmbedI1", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SEmbedI1", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
@@ -0,0 +1,28 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "SEmbedI1[t]" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "SEmbedI1[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 = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,16 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SEmbedI2", True, "Source", "", "", "ReturnValue", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SEmbedI2", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SEmbedI2", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
@@ -0,0 +1,28 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "SEmbedI2[t]" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "SEmbedI2[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 = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,16 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SEmbedS1", True, "Source", "", "", "ReturnValue", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SEmbedS1", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SEmbedS1", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
@@ -0,0 +1,28 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "SEmbedS1[t]" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "SEmbedS1[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 = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,16 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SEmbedS2", True, "Source", "", "", "ReturnValue", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SEmbedS2", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SEmbedS2", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
@@ -0,0 +1,28 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "SEmbedS2[t]" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "SEmbedS2[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 = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,16 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SImplEmbedI1", True, "Source", "", "", "ReturnValue", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SImplEmbedI1", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SImplEmbedI1", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
@@ -0,0 +1,28 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "SImplEmbedI1[t]" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "SImplEmbedI1[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 = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,16 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SImplEmbedI2", True, "Source", "", "", "ReturnValue", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SImplEmbedI2", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SImplEmbedI2", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
@@ -0,0 +1,28 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "SImplEmbedI2[t]" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "SImplEmbedI2[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 = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,16 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SImplEmbedS1", True, "Source", "", "", "ReturnValue", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SImplEmbedS1", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SImplEmbedS1", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
@@ -0,0 +1,28 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "SImplEmbedS1[t]" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "SImplEmbedS1[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 = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,16 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SImplEmbedS2", True, "Source", "", "", "ReturnValue", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SImplEmbedS2", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "SImplEmbedS2", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
@@ -0,0 +1,28 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "SImplEmbedS2[t]" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "SImplEmbedS2[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 = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,16 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "I1", False, "Source", "", "", "ReturnValue", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "I1", False, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "I1", False, "Sink", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
@@ -0,0 +1,28 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "I1[f]" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "I1[f]" 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 = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,16 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "I1", True, "Source", "", "", "ReturnValue", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "I1", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "I1", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
@@ -0,0 +1,28 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "I1[t]" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "I1[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 = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,16 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "I2", False, "Source", "", "", "ReturnValue", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "I2", False, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "I2", False, "Sink", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
@@ -0,0 +1,28 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "I2[f]" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "I2[f]" 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 = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,16 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "I2", True, "Source", "", "", "ReturnValue", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "I2", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "I2", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
@@ -0,0 +1,28 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "I2[t]" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "I2[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 = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,16 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "S1", False, "Source", "", "", "ReturnValue", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "S1", False, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "S1", False, "Sink", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
@@ -0,0 +1,28 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "S1[f]" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "S1[f]" 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 = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,16 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "S1", True, "Source", "", "", "ReturnValue", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "S1", True, "Step", "", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["github.com/nonexistent/test", "S1", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"]
|
||||
@@ -0,0 +1,28 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "S1[t]" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "S1[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 = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,56 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "ql_I1" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "ql_I1" 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 MySource extends RemoteFlowSource::Range instanceof DataFlow::Node {
|
||||
MySource() {
|
||||
exists(Method m |
|
||||
m.hasQualifiedName("github.com/nonexistent/test", "I1", "Source") and
|
||||
this = m.getACall().getResult()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class MyStep extends DataFlow::FunctionModel, Method {
|
||||
MyStep() { this.hasQualifiedName("github.com/nonexistent/test", "I1", "Step") }
|
||||
|
||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||
input.isParameter(0) and output.isResult()
|
||||
}
|
||||
}
|
||||
|
||||
class MySink extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
MySink() {
|
||||
exists(Method m |
|
||||
m.hasQualifiedName("github.com/nonexistent/test", "I1", "Sink") and
|
||||
this = m.getACall()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getArgument(0) }
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
testFailures
|
||||
invalidModelRow
|
||||
failures
|
||||
@@ -0,0 +1,56 @@
|
||||
import go
|
||||
import semmle.go.dataflow.ExternalFlow
|
||||
import ModelValidation
|
||||
import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import MakeTest<FlowTest>
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
module FlowTest implements TestSig {
|
||||
string getARelevantTag() { result = "ql_S1" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "ql_S1" 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 MySource extends RemoteFlowSource::Range instanceof DataFlow::Node {
|
||||
MySource() {
|
||||
exists(Method m |
|
||||
m.hasQualifiedName("github.com/nonexistent/test", "S1", "Source") and
|
||||
this = m.getACall().getResult()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class MyStep extends DataFlow::FunctionModel, Method {
|
||||
MyStep() { this.hasQualifiedName("github.com/nonexistent/test", "S1", "Step") }
|
||||
|
||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||
input.isParameter(0) and output.isResult()
|
||||
}
|
||||
}
|
||||
|
||||
class MySink extends FileSystemAccess::Range, DataFlow::CallNode {
|
||||
MySink() {
|
||||
exists(Method m |
|
||||
m.hasQualifiedName("github.com/nonexistent/test", "S1", "Sink") and
|
||||
this = m.getACall()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getArgument(0) }
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/nonexistent/test"
|
||||
)
|
||||
|
||||
func TestI1(t test.I1) {
|
||||
x := t.Source()
|
||||
y := t.Step(x)
|
||||
t.Sink(y) // $ I1[f] I1[t] ql_I1 SPURIOUS: IEmbedI1[t] SEmbedI1[t] ql_S1
|
||||
}
|
||||
|
||||
func TestI2(t test.I2) {
|
||||
x := t.Source()
|
||||
y := t.Step(x)
|
||||
t.Sink(y) // $ I1[t] I2[f] I2[t] SPURIOUS: IEmbedI1[t] IEmbedI2[t] SEmbedI1[t] SEmbedI2[t]
|
||||
}
|
||||
|
||||
func TestS1(t test.S1) {
|
||||
x := t.Source()
|
||||
y := t.Step(x)
|
||||
t.Sink(y) // $ I1[t] S1[f] S1[t] ql_S1 SPURIOUS: IEmbedI1[t] SEmbedI1[t]
|
||||
}
|
||||
|
||||
func TestS2(t test.S2) {
|
||||
x := t.Source()
|
||||
y := t.Step(x)
|
||||
t.Sink(y) // $ I1[t] I2[t] SPURIOUS: IEmbedI1[t] IEmbedI2[t] SEmbedI1[t] SEmbedI2[t]
|
||||
}
|
||||
|
||||
func TestSEmbedI1(t test.SEmbedI1) {
|
||||
x := t.Source()
|
||||
y := t.Step(x)
|
||||
t.Sink(y) // $ I1[t] SEmbedI1[t] ql_I1 SPURIOUS: I1[f] IEmbedI1[t] ql_S1
|
||||
}
|
||||
|
||||
func TestSEmbedI2(t test.SEmbedI2) {
|
||||
x := t.Source()
|
||||
y := t.Step(x)
|
||||
t.Sink(y) // $ I1[t] I2[t] SEmbedI2[t] SPURIOUS: I2[f] IEmbedI1[t] IEmbedI2[t] SEmbedI1[t]
|
||||
}
|
||||
|
||||
func TestIEmbedI1(t test.IEmbedI1) {
|
||||
x := t.Source()
|
||||
y := t.Step(x)
|
||||
t.Sink(y) // $ I1[t] IEmbedI1[t] ql_I1 SPURIOUS: I1[f] SEmbedI1[t] ql_S1
|
||||
}
|
||||
|
||||
func TestIEmbedI2(t test.IEmbedI2) {
|
||||
x := t.Source()
|
||||
y := t.Step(x)
|
||||
t.Sink(y) // $ I1[t] I2[t] IEmbedI2[t] SPURIOUS: I2[f] IEmbedI1[t] SEmbedI1[t] SEmbedI2[t]
|
||||
}
|
||||
|
||||
func TestSImplEmbedI1(t test.SImplEmbedI1) {
|
||||
x := t.Source()
|
||||
y := t.Step(x)
|
||||
t.Sink(y) // $ I1[t] SImplEmbedI1[t] SPURIOUS: IEmbedI1[t] SEmbedI1[t]
|
||||
}
|
||||
|
||||
func TestSImplEmbedI2(t test.SImplEmbedI2) {
|
||||
x := t.Source()
|
||||
y := t.Step(x)
|
||||
t.Sink(y) // $ I1[t] I2[t] SImplEmbedI2[t] SPURIOUS: IEmbedI1[t] IEmbedI2[t] SEmbedI1[t] SEmbedI2[t]
|
||||
}
|
||||
|
||||
func TestSEmbedS1(t test.SEmbedS1) {
|
||||
x := t.Source()
|
||||
y := t.Step(x)
|
||||
t.Sink(y) // $ I1[t] S1[t] ql_S1 SPURIOUS: IEmbedI1[t] S1[f] SEmbedI1[t]
|
||||
}
|
||||
|
||||
func TestSEmbedS2(t test.SEmbedS2) {
|
||||
x := t.Source()
|
||||
y := t.Step(x)
|
||||
t.Sink(y) // $ I1[t] I2[t] SPURIOUS: IEmbedI1[t] IEmbedI2[t] SEmbedI1[t] SEmbedI2[t]
|
||||
}
|
||||
|
||||
func TestSImplEmbedS1(t test.SImplEmbedS1) {
|
||||
x := t.Source()
|
||||
y := t.Step(x)
|
||||
t.Sink(y) // $ I1[t] SImplEmbedS1[t] SPURIOUS: IEmbedI1[t] SEmbedI1[t]
|
||||
}
|
||||
|
||||
func TestSImplEmbedS2(t test.SImplEmbedS2) {
|
||||
x := t.Source()
|
||||
y := t.Step(x)
|
||||
t.Sink(y) // $ I1[t] I2[t] SImplEmbedS2[t] SPURIOUS: IEmbedI1[t] IEmbedI2[t] SEmbedI1[t] SEmbedI2[t]
|
||||
}
|
||||
128
go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/vendor/github.com/nonexistent/test/stub.go
generated
vendored
Normal file
128
go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/vendor/github.com/nonexistent/test/stub.go
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
package test
|
||||
|
||||
// An interface
|
||||
type I1 interface {
|
||||
Source() interface{}
|
||||
Step(interface{}) interface{}
|
||||
Sink(interface{})
|
||||
}
|
||||
|
||||
// An interface which is a subtype of I1
|
||||
type I2 interface {
|
||||
Source() interface{}
|
||||
Step(interface{}) interface{}
|
||||
Sink(interface{})
|
||||
ExtraMethodI2()
|
||||
}
|
||||
|
||||
// A struct type implementing I1
|
||||
type S1 struct{}
|
||||
|
||||
func (t *S1) Source() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *S1) Sink(interface{}) {}
|
||||
|
||||
func (t *S1) Step(val interface{}) interface{} {
|
||||
return val
|
||||
}
|
||||
|
||||
// A struct type implementing I2
|
||||
type S2 struct{}
|
||||
|
||||
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 embedding I1
|
||||
type SEmbedI1 struct{ I1 }
|
||||
|
||||
// A struct type embedding I2
|
||||
type SEmbedI2 struct{ I2 }
|
||||
|
||||
// An interface type embedding I1
|
||||
type IEmbedI1 interface {
|
||||
I1
|
||||
ExtraMethodIEmbedI1()
|
||||
}
|
||||
|
||||
// An interface type embedding I2
|
||||
type IEmbedI2 interface {
|
||||
I2
|
||||
ExtraMethodIEmbedI2()
|
||||
}
|
||||
|
||||
// A struct type embedding I1 and separately implementing its methods, so the
|
||||
// methods of the embedded field are not promoted.
|
||||
type SImplEmbedI1 struct{ I1 }
|
||||
|
||||
func (t *SImplEmbedI1) Source() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *SImplEmbedI1) Sink(interface{}) {}
|
||||
|
||||
func (t *SImplEmbedI1) 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 SImplEmbedI2 struct{ I2 }
|
||||
|
||||
func (t *SImplEmbedI2) Source() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *SImplEmbedI2) Sink(interface{}) {}
|
||||
|
||||
func (t *SImplEmbedI2) Step(val interface{}) interface{} {
|
||||
return val
|
||||
}
|
||||
|
||||
func (t *SImplEmbedI2) ExtraMethodI2() {}
|
||||
|
||||
// A struct type embedding S1
|
||||
type SEmbedS1 struct{ S1 }
|
||||
|
||||
// A struct type embedding S2
|
||||
type SEmbedS2 struct{ S2 }
|
||||
|
||||
// A struct type embedding S1 and separately implementing I1's methods, so the
|
||||
// methods of the embedded field are not promoted.
|
||||
type SImplEmbedS1 struct{ S1 }
|
||||
|
||||
func (t *SImplEmbedS1) Source() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *SImplEmbedS1) Sink(interface{}) {}
|
||||
|
||||
func (t *SImplEmbedS1) Step(val interface{}) interface{} {
|
||||
return val
|
||||
}
|
||||
|
||||
// A struct type embedding S2 and separately implementing I2's methods, so the
|
||||
// methods of the embedded field are not promoted.
|
||||
type SImplEmbedS2 struct{ S2 }
|
||||
|
||||
func (t *SImplEmbedS2) Source() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *SImplEmbedS2) Sink(interface{}) {}
|
||||
|
||||
func (t *SImplEmbedS2) Step(val interface{}) interface{} {
|
||||
return val
|
||||
}
|
||||
|
||||
func (t *SImplEmbedS2) ExtraMethodI2() {}
|
||||
3
go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/vendor/modules.txt
vendored
Normal file
3
go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/vendor/modules.txt
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# github.com/nonexistent/test v0.0.0-20200203000000-0000000000000
|
||||
## explicit
|
||||
github.com/nonexistent/test
|
||||
Reference in New Issue
Block a user