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:
Owen Mansel-Chan
2024-09-26 16:42:25 +01:00
committed by GitHub
58 changed files with 1100 additions and 1 deletions

View File

@@ -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.

View File

@@ -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)

View File

@@ -0,0 +1,5 @@
module semmle.go.Packages
go 1.21
require github.com/nonexistent/test v0.0.0-20200203000000-0000000000000

View File

@@ -0,0 +1,3 @@
testFailures
invalidModelRow
failures

View File

@@ -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"]

View File

@@ -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 = ""
)
}
}

View File

@@ -0,0 +1,3 @@
testFailures
invalidModelRow
failures

View File

@@ -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"]

View File

@@ -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 = ""
)
}
}

View File

@@ -0,0 +1,3 @@
testFailures
invalidModelRow
failures

View File

@@ -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"]

View File

@@ -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 = ""
)
}
}

View File

@@ -0,0 +1,3 @@
testFailures
invalidModelRow
failures

View File

@@ -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"]

View File

@@ -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 = ""
)
}
}

View File

@@ -0,0 +1,3 @@
testFailures
invalidModelRow
failures

View File

@@ -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"]

View File

@@ -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 = ""
)
}
}

View File

@@ -0,0 +1,3 @@
testFailures
invalidModelRow
failures

View File

@@ -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"]

View File

@@ -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 = ""
)
}
}

View File

@@ -0,0 +1,3 @@
testFailures
invalidModelRow
failures

View File

@@ -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"]

View File

@@ -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 = ""
)
}
}

View File

@@ -0,0 +1,3 @@
testFailures
invalidModelRow
failures

View File

@@ -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"]

View File

@@ -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 = ""
)
}
}

View File

@@ -0,0 +1,3 @@
testFailures
invalidModelRow
failures

View File

@@ -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"]

View File

@@ -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 = ""
)
}
}

View File

@@ -0,0 +1,3 @@
testFailures
invalidModelRow
failures

View File

@@ -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"]

View File

@@ -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 = ""
)
}
}

View File

@@ -0,0 +1,3 @@
testFailures
invalidModelRow
failures

View File

@@ -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"]

View File

@@ -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 = ""
)
}
}

View File

@@ -0,0 +1,3 @@
testFailures
invalidModelRow
failures

View File

@@ -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"]

View File

@@ -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 = ""
)
}
}

View File

@@ -0,0 +1,3 @@
testFailures
invalidModelRow
failures

View File

@@ -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"]

View File

@@ -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 = ""
)
}
}

View File

@@ -0,0 +1,3 @@
testFailures
invalidModelRow
failures

View File

@@ -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"]

View File

@@ -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 = ""
)
}
}

View File

@@ -0,0 +1,3 @@
testFailures
invalidModelRow
failures

View File

@@ -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"]

View File

@@ -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 = ""
)
}
}

View File

@@ -0,0 +1,3 @@
testFailures
invalidModelRow
failures

View File

@@ -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"]

View File

@@ -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 = ""
)
}
}

View File

@@ -0,0 +1,3 @@
testFailures
invalidModelRow
failures

View File

@@ -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) }
}

View File

@@ -0,0 +1,3 @@
testFailures
invalidModelRow
failures

View File

@@ -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) }
}

View File

@@ -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]
}

View 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() {}

View File

@@ -0,0 +1,3 @@
# github.com/nonexistent/test v0.0.0-20200203000000-0000000000000
## explicit
github.com/nonexistent/test