From da5268d16528828620aec0fee58b2406439972dc Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Fri, 27 Sep 2024 19:47:41 +0100 Subject: [PATCH] Fix MaD inheritance --- go/ql/lib/semmle/go/dataflow/ExternalFlow.qll | 25 ++- .../go/dataflow/internal/FlowSummaryImpl.qll | 146 +++++++++++++++++- .../mad_IEmbedI1_subtypes_true.ext.yml | 4 +- .../mad_IEmbedI1_subtypes_true.ql | 6 +- .../mad_IEmbedI2_subtypes_true.ext.yml | 4 +- .../mad_IEmbedI2_subtypes_true.ql | 6 +- .../mad_SEmbedI1_subtypes_true.ext.yml | 6 +- .../mad_SEmbedI1_subtypes_true.ql | 6 +- .../mad_SEmbedI2_subtypes_true.ext.yml | 4 +- .../mad_SEmbedI2_subtypes_true.ql | 6 +- .../mad_SEmbedS1_subtypes_true.ext.yml | 6 +- .../mad_SEmbedS1_subtypes_true.ql | 6 +- .../mad_SEmbedS2_subtypes_true.ext.yml | 4 +- .../mad_SEmbedS2_subtypes_true.ql | 6 +- .../mad_SImplEmbedI1_subtypes_true.ext.yml | 6 +- .../mad_SImplEmbedI1_subtypes_true.ql | 6 +- .../mad_SImplEmbedI2_subtypes_true.ext.yml | 4 +- .../mad_SImplEmbedI2_subtypes_true.ql | 6 +- .../mad_SImplEmbedS1_subtypes_true.ext.yml | 6 +- .../mad_SImplEmbedS1_subtypes_true.ql | 6 +- .../mad_SImplEmbedS2_subtypes_true.ext.yml | 4 +- .../mad_SImplEmbedS2_subtypes_true.ql | 6 +- .../mad_i1_subtypes_false.ext.yml | 4 +- .../mad_i1_subtypes_false.ql | 6 +- .../mad_i1_subtypes_true.ext.yml | 4 +- .../mad_i1_subtypes_true.ql | 6 +- .../mad_i2_subtypes_false.ext.yml | 4 +- .../mad_i2_subtypes_false.ql | 6 +- .../mad_i2_subtypes_true.ext.yml | 4 +- .../mad_i2_subtypes_true.ql | 6 +- .../mad_s1_subtypes_false.ext.yml | 6 +- .../mad_s1_subtypes_false.ql | 6 +- .../mad_s1_subtypes_true.ext.yml | 6 +- .../mad_s1_subtypes_true.ql | 6 +- .../dataflow/ExternalFlowInheritance/ql_I1.ql | 36 ++--- .../dataflow/ExternalFlowInheritance/ql_S1.ql | 46 +++--- .../dataflow/ExternalFlowInheritance/test.go | 89 ----------- .../ExternalFlowInheritance/test_fields.go | 62 ++++++++ .../ExternalFlowInheritance/test_methods.go | 123 +++++++++++++++ .../github.com/nonexistent/test/stub.go | 41 ++++- 40 files changed, 486 insertions(+), 254 deletions(-) delete mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/test.go create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/test_fields.go create mode 100644 go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/test_methods.go diff --git a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll index 1dffde971510..68a876deaea6 100644 --- a/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/ExternalFlow.qll @@ -474,17 +474,30 @@ SourceSinkInterpretationInput::SourceOrSinkElement interpretElement( elementSpec(pkg, type, subtypes, name, signature, ext) and // Go does not need to distinguish functions with signature signature = "" and - ( - exists(Field f | f.hasQualifiedName(interpretPackage(pkg), type, name) | result.asEntity() = f) + exists(string p | p = interpretPackage(pkg) | + exists(Field f | f.hasQualifiedName(p, type, name) | + result.asEntity() = f and + result.hasTypeInfo(p, type, subtypes) + ) or - exists(Method m | m.hasQualifiedName(interpretPackage(pkg), type, name) | - result.asEntity() = m + exists(Method m | m.hasQualifiedName(p, type, name) | + result.asEntity() = m and + result.hasTypeInfo(p, type, subtypes) or - subtypes = true and result.asEntity().(Method).implementsIncludingInterfaceMethods(m) + subtypes = true and + // p.type is an interface and we include types which implement it + exists(Method m2, string pkg2, string type2 | + m2.getReceiverType().implements(p, type) and + m2.getName() = name and + m2.getReceiverBaseType().hasQualifiedName(pkg2, type2) + | + result.asEntity() = m2 and + result.hasTypeInfo(pkg2, type2, subtypes) + ) ) or type = "" and - exists(Entity e | e.hasQualifiedName(interpretPackage(pkg), name) | result.asEntity() = e) + exists(Entity e | e.hasQualifiedName(p, name) | result.asEntity() = e) ) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index 211974f75a56..14a92748d526 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -150,20 +150,50 @@ module SourceSinkInterpretationInput implements } private newtype TSourceOrSinkElement = - TEntityElement(Entity e) or + TMethodEntityElement(Method m, string pkg, string type, boolean subtypes) { + m.hasQualifiedName(pkg, type, _) and subtypes = [true, false] + } or + TFieldEntityElement(Field f, string pkg, string type, boolean subtypes) { + f.hasQualifiedName(pkg, type, _) and subtypes = [true, false] + } or + TOtherEntityElement(Entity e) { + not e instanceof Method and + not e instanceof Field + } or TAstElement(AstNode n) /** An element representable by CSV modeling. */ class SourceOrSinkElement extends TSourceOrSinkElement { /** Gets this source or sink element as an entity, if it is one. */ - Entity asEntity() { this = TEntityElement(result) } + Entity asEntity() { + this = TMethodEntityElement(result, _, _, _) or + this = TFieldEntityElement(result, _, _, _) or + this = TOtherEntityElement(result) + } /** Gets this source or sink element as an AST node, if it is one. */ AstNode asAstNode() { this = TAstElement(result) } + /** + * Holds if this source or sink element is a method that was specified + * with the given values for `pkg`, `type` and `subtypes`. + */ + predicate hasTypeInfo(string pkg, string type, boolean subtypes) { + this = TMethodEntityElement(_, pkg, type, subtypes) or + this = TFieldEntityElement(_, pkg, type, subtypes) + } + /** Gets a textual representation of this source or sink element. */ string toString() { + not this.hasTypeInfo(_, _, _) and result = "element representing " + [this.asEntity().toString(), this.asAstNode().toString()] + or + exists(string pkg, string name, boolean subtypes | + this.hasTypeInfo(pkg, name, subtypes) and + result = + "element representing " + this.asEntity().toString() + " with receiver type " + pkg + "." + + name + " and subtypes=" + subtypes + ) } /** Gets the location of this element. */ @@ -203,7 +233,17 @@ module SourceSinkInterpretationInput implements /** Gets the target of this call, if any. */ SourceOrSinkElement getCallTarget() { - result.asEntity() = this.asCall().getNode().(DataFlow::CallNode).getTarget() + exists(DataFlow::CallNode cn, Function callTarget | + cn = this.asCall().getNode() and + callTarget = cn.getTarget() + | + result.asEntity() = callTarget and + ( + not callTarget instanceof Method + or + ensureCorrectTypeInfo(result, cn.getReceiver()) + ) + ) } /** Gets a textual representation of this node. */ @@ -228,6 +268,90 @@ module SourceSinkInterpretationInput implements } } + private predicate ensureCorrectTypeInfo(SourceOrSinkElement sse, DataFlow::Node recv) { + ( + exists(DataFlow::CallNode cn | cn.getReceiver() = recv and cn.getTarget() = sse.asEntity()) + or + exists(DataFlow::FieldReadNode frn | frn.getBase() = recv and frn.getField() = sse.asEntity()) + or + exists(DataFlow::Write fw | fw.writesField(recv, sse.asEntity(), _)) + ) and + exists(string pkg, string typename, boolean subtypes, Type syntacticRecvBaseType | + sse.hasTypeInfo(pkg, typename, subtypes) and + syntacticRecvBaseType = lookThroughPointerType(getSyntacticRecv(recv).getType()) + | + subtypes = [true, false] and + syntacticRecvBaseType.hasQualifiedName(pkg, typename) + or + subtypes = true and + ( + // `syntacticRecvBaseType`'s underlying type might be an interface type and `sse` + // might be a method defined on an interface which is a subtype of it. + exists(Type t | + t = syntacticRecvBaseType.getUnderlyingType().(InterfaceType).getAnEmbeddedInterface() and + t.hasQualifiedName(pkg, typename) and + sse.asEntity().(Method).hasQualifiedName(pkg, typename, _) + ) + or + // `syntacticRecvBaseType`'s underlying type might be a struct type and `sse` + // might be a promoted method or field. + exists(StructType st, Field field1, Field field2, int depth1, int depth2, Type t1, Type t2 | + st = syntacticRecvBaseType.getUnderlyingType() and + field1 = st.getFieldAtDepth(_, depth1) and + field2 = st.getFieldAtDepth(_, depth2) and + t1 = lookThroughPointerType(field1.getType()) and + t2 = lookThroughPointerType(field2.getType()) and + ( + field1 = field2 + or + field2 = t1.getUnderlyingType().(StructType).getFieldAtDepth(_, depth2 - depth1 - 1) + ) and + matchTypeInfo(sse, t1) + | + sse.asEntity().(Method).getReceiverBaseType() = t2 + or + sse.asEntity().(Field).getDeclaringType() = t2.getUnderlyingType() + ) + ) + ) + } + + private DataFlow::Node getSyntacticRecv(DataFlow::Node n) { + exists(DataFlow::Node n2 | + // look through implicit dereference, if there is one + not exists(n.asInstruction().(IR::EvalImplicitDerefInstruction).getOperand()) and + n2 = n + or + n2.asExpr() = n.asInstruction().(IR::EvalImplicitDerefInstruction).getOperand() + | + result = skipImplicitFieldReads(n2) + ) + } + + private DataFlow::Node skipImplicitFieldReads(DataFlow::Node n) { + not exists(getImplicitFieldReadInstruction(n)) and result = n + or + result = skipImplicitFieldReads(getImplicitFieldReadInstruction(n)) + } + + pragma[inline] + private DataFlow::Node getImplicitFieldReadInstruction(DataFlow::Node n) { + result.asInstruction() = + n.(DataFlow::InstructionNode) + .asInstruction() + .(IR::ImplicitFieldReadInstruction) + .getBaseInstruction() + } + + bindingset[sse, t] + pragma[inline_late] + private predicate matchTypeInfo(SourceOrSinkElement sse, Type t) { + exists(string pkg, string typename | + sse.hasTypeInfo(pkg, typename, true) and + t.hasQualifiedName(pkg, typename) + ) + } + /** Provides additional sink specification logic. */ bindingset[c] predicate interpretOutput(string c, InterpretNode mid, InterpretNode node) { @@ -244,8 +368,11 @@ module SourceSinkInterpretationInput implements (c = "Parameter" or c = "") and node.asNode().asParameter() = e.asEntity() or - c = "" and - n.(DataFlow::FieldReadNode).getField() = e.asEntity() + exists(DataFlow::FieldReadNode frn | frn = n | + c = "" and + frn.getField() = e.asEntity() and + ensureCorrectTypeInfo(e, frn.getBase()) + ) ) } @@ -259,10 +386,13 @@ module SourceSinkInterpretationInput implements mid.asCallable() = getNodeEnclosingCallable(ret) ) or - exists(DataFlow::Write fw, Field f | + exists(SourceOrSinkElement e, DataFlow::Write fw, DataFlow::Node base, Field f | + e = mid.asElement() and + f = e.asEntity() + | c = "" and - f = mid.asElement().asEntity() and - fw.writesField(_, f, node.asNode()) + fw.writesField(base, f, node.asNode()) and + ensureCorrectTypeInfo(e, base) ) } } diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI1_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI1_subtypes_true.ext.yml index 7d2e45d89f31..faf2e6ba6063 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI1_subtypes_true.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI1_subtypes_true.ext.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/go-all extensible: sourceModel data: - - ["github.com/nonexistent/test", "IEmbedI1", True, "Source", "", "", "ReturnValue", "remote", "manual"] + - ["github.com/nonexistent/test", "IEmbedI1", True, "Source", "", "", "ReturnValue", "qltest", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel @@ -13,4 +13,4 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["github.com/nonexistent/test", "IEmbedI1", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"] + - ["github.com/nonexistent/test", "IEmbedI1", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI1_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI1_subtypes_true.ql index 7af5b7795b9f..e4d35a2d1830 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI1_subtypes_true.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI1_subtypes_true.ql @@ -1,14 +1,12 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation -import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineExpectationsTest import MakeTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } - predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } } module Flow = TaintTracking::Global; diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI2_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI2_subtypes_true.ext.yml index b723867e3e79..066e1846fbf6 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI2_subtypes_true.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI2_subtypes_true.ext.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/go-all extensible: sourceModel data: - - ["github.com/nonexistent/test", "IEmbedI2", True, "Source", "", "", "ReturnValue", "remote", "manual"] + - ["github.com/nonexistent/test", "IEmbedI2", True, "Source", "", "", "ReturnValue", "qltest", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel @@ -13,4 +13,4 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["github.com/nonexistent/test", "IEmbedI2", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"] + - ["github.com/nonexistent/test", "IEmbedI2", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI2_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI2_subtypes_true.ql index 388370ba6b8c..18e461357890 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI2_subtypes_true.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_IEmbedI2_subtypes_true.ql @@ -1,14 +1,12 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation -import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineExpectationsTest import MakeTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } - predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } } module Flow = TaintTracking::Global; diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI1_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI1_subtypes_true.ext.yml index 93f8f74dfb5b..a210d4213261 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI1_subtypes_true.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI1_subtypes_true.ext.yml @@ -3,7 +3,8 @@ extensions: pack: codeql/go-all extensible: sourceModel data: - - ["github.com/nonexistent/test", "SEmbedI1", True, "Source", "", "", "ReturnValue", "remote", "manual"] + - ["github.com/nonexistent/test", "SEmbedI1", True, "Source", "", "", "ReturnValue", "qltest", "manual"] + - ["github.com/nonexistent/test", "SEmbedI1", True, "SourceField", "", "", "", "qltest", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel @@ -13,4 +14,5 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["github.com/nonexistent/test", "SEmbedI1", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"] + - ["github.com/nonexistent/test", "SEmbedI1", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] + - ["github.com/nonexistent/test", "SEmbedI1", True, "SinkField", "", "", "", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI1_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI1_subtypes_true.ql index d56f8ae0f0f9..f401e958315d 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI1_subtypes_true.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI1_subtypes_true.ql @@ -1,14 +1,12 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation -import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineExpectationsTest import MakeTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } - predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } } module Flow = TaintTracking::Global; diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI2_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI2_subtypes_true.ext.yml index ba94082e7e31..f1378ba6fa23 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI2_subtypes_true.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI2_subtypes_true.ext.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/go-all extensible: sourceModel data: - - ["github.com/nonexistent/test", "SEmbedI2", True, "Source", "", "", "ReturnValue", "remote", "manual"] + - ["github.com/nonexistent/test", "SEmbedI2", True, "Source", "", "", "ReturnValue", "qltest", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel @@ -13,4 +13,4 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["github.com/nonexistent/test", "SEmbedI2", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"] + - ["github.com/nonexistent/test", "SEmbedI2", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI2_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI2_subtypes_true.ql index dd46393546fc..0d7169c93cf7 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI2_subtypes_true.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedI2_subtypes_true.ql @@ -1,14 +1,12 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation -import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineExpectationsTest import MakeTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } - predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } } module Flow = TaintTracking::Global; diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS1_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS1_subtypes_true.ext.yml index 89218840c0bf..35baccbe09f6 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS1_subtypes_true.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS1_subtypes_true.ext.yml @@ -3,7 +3,8 @@ extensions: pack: codeql/go-all extensible: sourceModel data: - - ["github.com/nonexistent/test", "SEmbedS1", True, "Source", "", "", "ReturnValue", "remote", "manual"] + - ["github.com/nonexistent/test", "SEmbedS1", True, "Source", "", "", "ReturnValue", "qltest", "manual"] + - ["github.com/nonexistent/test", "SEmbedS1", True, "SourceField", "", "", "", "qltest", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel @@ -13,4 +14,5 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["github.com/nonexistent/test", "SEmbedS1", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"] + - ["github.com/nonexistent/test", "SEmbedS1", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] + - ["github.com/nonexistent/test", "SEmbedS1", True, "SinkField", "", "", "", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS1_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS1_subtypes_true.ql index 0789ada5c51f..f58fd32770a9 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS1_subtypes_true.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS1_subtypes_true.ql @@ -1,14 +1,12 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation -import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineExpectationsTest import MakeTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } - predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } } module Flow = TaintTracking::Global; diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS2_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS2_subtypes_true.ext.yml index e773cf215b40..4772c9de698e 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS2_subtypes_true.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS2_subtypes_true.ext.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/go-all extensible: sourceModel data: - - ["github.com/nonexistent/test", "SEmbedS2", True, "Source", "", "", "ReturnValue", "remote", "manual"] + - ["github.com/nonexistent/test", "SEmbedS2", True, "Source", "", "", "ReturnValue", "qltest", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel @@ -13,4 +13,4 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["github.com/nonexistent/test", "SEmbedS2", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"] + - ["github.com/nonexistent/test", "SEmbedS2", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS2_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS2_subtypes_true.ql index 76d0b6fcd1a1..db9d98e06d28 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS2_subtypes_true.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SEmbedS2_subtypes_true.ql @@ -1,14 +1,12 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation -import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineExpectationsTest import MakeTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } - predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } } module Flow = TaintTracking::Global; diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI1_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI1_subtypes_true.ext.yml index 4b572ad124cc..f75fc2f7652f 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI1_subtypes_true.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI1_subtypes_true.ext.yml @@ -3,7 +3,8 @@ extensions: pack: codeql/go-all extensible: sourceModel data: - - ["github.com/nonexistent/test", "SImplEmbedI1", True, "Source", "", "", "ReturnValue", "remote", "manual"] + - ["github.com/nonexistent/test", "SImplEmbedI1", True, "Source", "", "", "ReturnValue", "qltest", "manual"] + - ["github.com/nonexistent/test", "SImplEmbedI1", True, "SourceField", "", "", "", "qltest", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel @@ -13,4 +14,5 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["github.com/nonexistent/test", "SImplEmbedI1", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"] + - ["github.com/nonexistent/test", "SImplEmbedI1", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] + - ["github.com/nonexistent/test", "SImplEmbedI1", True, "SinkField", "", "", "", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI1_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI1_subtypes_true.ql index 4fb7909d7610..c4e8afd1fbf4 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI1_subtypes_true.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI1_subtypes_true.ql @@ -1,14 +1,12 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation -import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineExpectationsTest import MakeTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } - predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } } module Flow = TaintTracking::Global; diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI2_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI2_subtypes_true.ext.yml index 9d695502c29a..65cba7782506 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI2_subtypes_true.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI2_subtypes_true.ext.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/go-all extensible: sourceModel data: - - ["github.com/nonexistent/test", "SImplEmbedI2", True, "Source", "", "", "ReturnValue", "remote", "manual"] + - ["github.com/nonexistent/test", "SImplEmbedI2", True, "Source", "", "", "ReturnValue", "qltest", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel @@ -13,4 +13,4 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["github.com/nonexistent/test", "SImplEmbedI2", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"] + - ["github.com/nonexistent/test", "SImplEmbedI2", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI2_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI2_subtypes_true.ql index f5dba02a1528..b8ebb68ecdb8 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI2_subtypes_true.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedI2_subtypes_true.ql @@ -1,14 +1,12 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation -import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineExpectationsTest import MakeTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } - predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } } module Flow = TaintTracking::Global; diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS1_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS1_subtypes_true.ext.yml index 0936a7d253b2..30d240d4a2e4 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS1_subtypes_true.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS1_subtypes_true.ext.yml @@ -3,7 +3,8 @@ extensions: pack: codeql/go-all extensible: sourceModel data: - - ["github.com/nonexistent/test", "SImplEmbedS1", True, "Source", "", "", "ReturnValue", "remote", "manual"] + - ["github.com/nonexistent/test", "SImplEmbedS1", True, "Source", "", "", "ReturnValue", "qltest", "manual"] + - ["github.com/nonexistent/test", "SImplEmbedS1", True, "SourceField", "", "", "", "qltest", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel @@ -13,4 +14,5 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["github.com/nonexistent/test", "SImplEmbedS1", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"] + - ["github.com/nonexistent/test", "SImplEmbedS1", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] + - ["github.com/nonexistent/test", "SImplEmbedS1", True, "SinkField", "", "", "", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS1_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS1_subtypes_true.ql index e08c787aa10a..10e9fb96d4c8 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS1_subtypes_true.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS1_subtypes_true.ql @@ -1,14 +1,12 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation -import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineExpectationsTest import MakeTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } - predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } } module Flow = TaintTracking::Global; diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS2_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS2_subtypes_true.ext.yml index 04bc012e7f41..6873efc4258a 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS2_subtypes_true.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS2_subtypes_true.ext.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/go-all extensible: sourceModel data: - - ["github.com/nonexistent/test", "SImplEmbedS2", True, "Source", "", "", "ReturnValue", "remote", "manual"] + - ["github.com/nonexistent/test", "SImplEmbedS2", True, "Source", "", "", "ReturnValue", "qltest", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel @@ -13,4 +13,4 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["github.com/nonexistent/test", "SImplEmbedS2", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"] + - ["github.com/nonexistent/test", "SImplEmbedS2", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS2_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS2_subtypes_true.ql index 4c2d832620cb..403b6238b4f3 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS2_subtypes_true.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_SImplEmbedS2_subtypes_true.ql @@ -1,14 +1,12 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation -import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineExpectationsTest import MakeTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } - predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } } module Flow = TaintTracking::Global; diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i1_subtypes_false.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i1_subtypes_false.ext.yml index 11067b1760da..a50fb9449a35 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i1_subtypes_false.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i1_subtypes_false.ext.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/go-all extensible: sourceModel data: - - ["github.com/nonexistent/test", "I1", False, "Source", "", "", "ReturnValue", "remote", "manual"] + - ["github.com/nonexistent/test", "I1", False, "Source", "", "", "ReturnValue", "qltest", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel @@ -13,4 +13,4 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["github.com/nonexistent/test", "I1", False, "Sink", "", "", "Argument[0]", "path-injection", "manual"] + - ["github.com/nonexistent/test", "I1", False, "Sink", "", "", "Argument[0]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i1_subtypes_false.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i1_subtypes_false.ql index 82d63025f226..3915c20b92bc 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i1_subtypes_false.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i1_subtypes_false.ql @@ -1,14 +1,12 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation -import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineExpectationsTest import MakeTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } - predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } } module Flow = TaintTracking::Global; diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i1_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i1_subtypes_true.ext.yml index 48c3a4daca8c..4b59e9a255f2 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i1_subtypes_true.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i1_subtypes_true.ext.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/go-all extensible: sourceModel data: - - ["github.com/nonexistent/test", "I1", True, "Source", "", "", "ReturnValue", "remote", "manual"] + - ["github.com/nonexistent/test", "I1", True, "Source", "", "", "ReturnValue", "qltest", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel @@ -13,4 +13,4 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["github.com/nonexistent/test", "I1", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"] + - ["github.com/nonexistent/test", "I1", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i1_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i1_subtypes_true.ql index 85a18e65096e..2db01e3a76f5 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i1_subtypes_true.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i1_subtypes_true.ql @@ -1,14 +1,12 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation -import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineExpectationsTest import MakeTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } - predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } } module Flow = TaintTracking::Global; diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i2_subtypes_false.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i2_subtypes_false.ext.yml index 8b01fd001766..660eb326eaaf 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i2_subtypes_false.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i2_subtypes_false.ext.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/go-all extensible: sourceModel data: - - ["github.com/nonexistent/test", "I2", False, "Source", "", "", "ReturnValue", "remote", "manual"] + - ["github.com/nonexistent/test", "I2", False, "Source", "", "", "ReturnValue", "qltest", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel @@ -13,4 +13,4 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["github.com/nonexistent/test", "I2", False, "Sink", "", "", "Argument[0]", "path-injection", "manual"] + - ["github.com/nonexistent/test", "I2", False, "Sink", "", "", "Argument[0]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i2_subtypes_false.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i2_subtypes_false.ql index f8dafe8b4f71..9cff9e92009f 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i2_subtypes_false.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i2_subtypes_false.ql @@ -1,14 +1,12 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation -import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineExpectationsTest import MakeTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } - predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } } module Flow = TaintTracking::Global; diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i2_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i2_subtypes_true.ext.yml index d9fbc304b518..8d2c2ff522ff 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i2_subtypes_true.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i2_subtypes_true.ext.yml @@ -3,7 +3,7 @@ extensions: pack: codeql/go-all extensible: sourceModel data: - - ["github.com/nonexistent/test", "I2", True, "Source", "", "", "ReturnValue", "remote", "manual"] + - ["github.com/nonexistent/test", "I2", True, "Source", "", "", "ReturnValue", "qltest", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel @@ -13,4 +13,4 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["github.com/nonexistent/test", "I2", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"] + - ["github.com/nonexistent/test", "I2", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i2_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i2_subtypes_true.ql index 140591813924..79220e979c08 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i2_subtypes_true.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_i2_subtypes_true.ql @@ -1,14 +1,12 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation -import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineExpectationsTest import MakeTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } - predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } } module Flow = TaintTracking::Global; diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_s1_subtypes_false.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_s1_subtypes_false.ext.yml index b0322a6ecd30..804a920b3242 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_s1_subtypes_false.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_s1_subtypes_false.ext.yml @@ -3,7 +3,8 @@ extensions: pack: codeql/go-all extensible: sourceModel data: - - ["github.com/nonexistent/test", "S1", False, "Source", "", "", "ReturnValue", "remote", "manual"] + - ["github.com/nonexistent/test", "S1", False, "Source", "", "", "ReturnValue", "qltest", "manual"] + - ["github.com/nonexistent/test", "S1", False, "SourceField", "", "", "", "qltest", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel @@ -13,4 +14,5 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["github.com/nonexistent/test", "S1", False, "Sink", "", "", "Argument[0]", "path-injection", "manual"] + - ["github.com/nonexistent/test", "S1", False, "Sink", "", "", "Argument[0]", "qltest", "manual"] + - ["github.com/nonexistent/test", "S1", False, "SinkField", "", "", "", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_s1_subtypes_false.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_s1_subtypes_false.ql index 72cea1afe969..c5754d1ded77 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_s1_subtypes_false.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_s1_subtypes_false.ql @@ -1,14 +1,12 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation -import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineExpectationsTest import MakeTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } - predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } } module Flow = TaintTracking::Global; diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_s1_subtypes_true.ext.yml b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_s1_subtypes_true.ext.yml index 3adf2d35ca48..14f2914b9421 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_s1_subtypes_true.ext.yml +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_s1_subtypes_true.ext.yml @@ -3,7 +3,8 @@ extensions: pack: codeql/go-all extensible: sourceModel data: - - ["github.com/nonexistent/test", "S1", True, "Source", "", "", "ReturnValue", "remote", "manual"] + - ["github.com/nonexistent/test", "S1", True, "Source", "", "", "ReturnValue", "qltest", "manual"] + - ["github.com/nonexistent/test", "S1", True, "SourceField", "", "", "", "qltest", "manual"] - addsTo: pack: codeql/go-all extensible: summaryModel @@ -13,4 +14,5 @@ extensions: pack: codeql/go-all extensible: sinkModel data: - - ["github.com/nonexistent/test", "S1", True, "Sink", "", "", "Argument[0]", "path-injection", "manual"] + - ["github.com/nonexistent/test", "S1", True, "Sink", "", "", "Argument[0]", "qltest", "manual"] + - ["github.com/nonexistent/test", "S1", True, "SinkField", "", "", "", "qltest", "manual"] diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_s1_subtypes_true.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_s1_subtypes_true.ql index 4afbff7ac9e1..92c895b61a33 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_s1_subtypes_true.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/mad_s1_subtypes_true.ql @@ -1,14 +1,12 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation -import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineExpectationsTest import MakeTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source) { sourceNode(source, "qltest") } - predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() } + predicate isSink(DataFlow::Node sink) { sinkNode(sink, "qltest") } } module Flow = TaintTracking::Global; diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_I1.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_I1.ql index 9e563a5bb70e..f4beb7ea28df 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_I1.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_I1.ql @@ -1,14 +1,22 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation -import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineExpectationsTest import MakeTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source) { + exists(Method m | + m.hasQualifiedName("github.com/nonexistent/test", "I1", "Source") and + source = m.getACall().getResult() + ) + } - predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() } + predicate isSink(DataFlow::Node sink) { + exists(Method m | + m.hasQualifiedName("github.com/nonexistent/test", "I1", "Sink") and + sink = m.getACall().getArgument(0) + ) + } } module Flow = TaintTracking::Global; @@ -27,15 +35,6 @@ module FlowTest implements TestSig { } } -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") } @@ -43,14 +42,3 @@ class MyStep extends DataFlow::FunctionModel, Method { 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) } -} diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_S1.ql b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_S1.ql index bf9f36358b9d..49113c53ed7a 100644 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_S1.ql +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/ql_S1.ql @@ -1,14 +1,32 @@ import go -import semmle.go.dataflow.ExternalFlow import ModelValidation -import semmle.go.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import TestUtilities.InlineExpectationsTest import MakeTest module Config implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSource(DataFlow::Node source) { + exists(Method m | + m.hasQualifiedName("github.com/nonexistent/test", "S1", "Source") and + source = m.getACall().getResult() + ) + or + exists(Field f | + f.hasQualifiedName("github.com/nonexistent/test", "S1", "SourceField") and + source = f.getARead() + ) + } - predicate isSink(DataFlow::Node sink) { sink = any(FileSystemAccess fsa).getAPathArgument() } + predicate isSink(DataFlow::Node sink) { + exists(Method m | + m.hasQualifiedName("github.com/nonexistent/test", "S1", "Sink") and + sink = m.getACall().getArgument(0) + ) + or + exists(Field f | + f.hasQualifiedName("github.com/nonexistent/test", "S1", "SinkField") and + any(DataFlow::Write w).writesField(_, f, sink) + ) + } } module Flow = TaintTracking::Global; @@ -27,15 +45,6 @@ module FlowTest implements TestSig { } } -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") } @@ -43,14 +52,3 @@ class MyStep extends DataFlow::FunctionModel, Method { 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) } -} diff --git a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/test.go b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/test.go deleted file mode 100644 index 1c41bc05c76a..000000000000 --- a/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/test.go +++ /dev/null @@ -1,89 +0,0 @@ -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] -} 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 new file mode 100644 index 000000000000..adb0ee991e42 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/test_fields.go @@ -0,0 +1,62 @@ +package main + +import ( + "github.com/nonexistent/test" +) + +func TestFieldsS1(t test.S1) { + a := t.SourceField + t.SinkField = a // $ S1[f] S1[t] ql_S1 +} + +func TestFieldsSEmbedI1(t test.SEmbedI1) { + a := t.SourceField + t.SinkField = a // $ SEmbedI1[t] +} + +func TestFieldsSImplEmbedI1(t test.SImplEmbedI1) { + a := t.SourceField + t.SinkField = a // $ SImplEmbedI1[t] +} + +func TestFieldsSEmbedS1(t test.SEmbedS1) { + a := t.SourceField + t.SinkField = a // $ S1[t] SEmbedS1[t] ql_S1 +} + +func TestFieldsSImplEmbedS1(t test.SImplEmbedS1) { + a := t.SourceField + t.SinkField = a // $ SImplEmbedS1[t] +} + +func TestFieldsSEmbedSEmbedI1(t test.SEmbedSEmbedI1) { + a := t.SourceField + t.SinkField = a +} + +func TestFieldsSEmbedSEmbedS1(t test.SEmbedSEmbedS1) { + a := t.SourceField + t.SinkField = a // $ S1[t] ql_S1 SEmbedS1[t] +} + +// This is needed because of a bug that causes some things to not work unless we +// extract the pointer to a named type. +func doNothingFields( + _ *test.I1, + _ *test.I2, + _ *test.S1, + _ *test.S2, + _ *test.SEmbedI1, + _ *test.SEmbedI2, + _ *test.IEmbedI1, + _ *test.IEmbedI2, + _ *test.SImplEmbedI1, + _ *test.SImplEmbedI2, + _ *test.SEmbedS1, + _ *test.SEmbedS2, + _ *test.SImplEmbedS1, + _ *test.SImplEmbedS2, + _ *test.SEmbedSEmbedI1, + _ *test.SEmbedSEmbedS1, +) { +} 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 new file mode 100644 index 000000000000..f56bffafea60 --- /dev/null +++ b/go/ql/test/library-tests/semmle/go/dataflow/ExternalFlowInheritance/test_methods.go @@ -0,0 +1,123 @@ +package main + +import ( + "github.com/nonexistent/test" +) + +func TestMethodsI1(t test.I1) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[f] I1[t] ql_I1 SPURIOUS: ql_S1 +} + +func TestMethodsI2(t test.I2) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] I2[f] I2[t] +} + +func TestMethodsS1(t test.S1) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] S1[f] S1[t] ql_S1 +} + +func TestMethodsS2(t test.S2) { + 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 +} + +func TestMethodsSEmbedI2(t test.SEmbedI2) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] I2[t] SEmbedI2[t] +} + +func TestMethodsIEmbedI1(t test.IEmbedI1) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] IEmbedI1[t] ql_I1 SPURIOUS: ql_S1 +} + +func TestMethodsIEmbedI2(t test.IEmbedI2) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] I2[t] IEmbedI2[t] +} + +func TestMethodsSImplEmbedI1(t test.SImplEmbedI1) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] SImplEmbedI1[t] +} + +func TestMethodsSImplEmbedI2(t test.SImplEmbedI2) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] I2[t] SImplEmbedI2[t] +} + +func TestMethodsSEmbedS1(t test.SEmbedS1) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] S1[t] SEmbedS1[t] ql_S1 +} + +func TestMethodsSEmbedS2(t test.SEmbedS2) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] I2[t] SEmbedS2[t] +} + +func TestMethodsSImplEmbedS1(t test.SImplEmbedS1) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] SImplEmbedS1[t] +} + +func TestMethodsSImplEmbedS2(t test.SImplEmbedS2) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] I2[t] SImplEmbedS2[t] +} + +func TestMethodsSEmbedSEmbedI1(t test.SEmbedSEmbedI1) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] SEmbedI1[t] ql_I1 SPURIOUS: ql_S1 +} + +func TestMethodsSEmbedSEmbedS1(t test.SEmbedSEmbedS1) { + x := t.Source() + y := t.Step(x) + t.Sink(y) // $ I1[t] S1[t] SEmbedS1[t] ql_S1 +} + +// This is needed because of a bug that causes some things to not work unless we +// extract the pointer to a named type. +func doNothingMethods( + _ *test.I1, + _ *test.I2, + _ *test.S1, + _ *test.S2, + _ *test.SEmbedI1, + _ *test.SEmbedI2, + _ *test.IEmbedI1, + _ *test.IEmbedI2, + _ *test.SImplEmbedI1, + _ *test.SImplEmbedI2, + _ *test.SEmbedS1, + _ *test.SEmbedS2, + _ *test.SImplEmbedS1, + _ *test.SImplEmbedS2, + _ *test.SEmbedSEmbedI1, + _ *test.SEmbedSEmbedS1, +) { +} 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 206e1d99e383..524af77de480 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 @@ -16,7 +16,10 @@ type I2 interface { } // A struct type implementing I1 -type S1 struct{} +type S1 struct { + SourceField string + SinkField string +} func (t *S1) Source() interface{} { return nil @@ -44,7 +47,11 @@ func (t *S2) Step(val interface{}) interface{} { func (t *S2) ExtraMethodI2() {} // A struct type embedding I1 -type SEmbedI1 struct{ I1 } +type SEmbedI1 struct { + I1 + SourceField string + SinkField string +} // A struct type embedding I2 type SEmbedI2 struct{ I2 } @@ -63,7 +70,11 @@ type IEmbedI2 interface { // A struct type embedding I1 and separately implementing its methods, so the // methods of the embedded field are not promoted. -type SImplEmbedI1 struct{ I1 } +type SImplEmbedI1 struct { + I1 + SourceField string + SinkField string +} func (t *SImplEmbedI1) Source() interface{} { return nil @@ -92,14 +103,20 @@ func (t *SImplEmbedI2) Step(val interface{}) interface{} { func (t *SImplEmbedI2) ExtraMethodI2() {} // A struct type embedding S1 -type SEmbedS1 struct{ 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 } +// 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 { + S1 + SourceField string + SinkField string +} func (t *SImplEmbedS1) Source() interface{} { return nil @@ -126,3 +143,13 @@ func (t *SImplEmbedS2) Step(val interface{}) interface{} { } func (t *SImplEmbedS2) ExtraMethodI2() {} + +// A struct type embedding SEmbedI1 +type SEmbedSEmbedI1 struct { + SEmbedI1 + SourceField string + SinkField string +} + +// A struct type embedding SEmbedS1 +type SEmbedSEmbedS1 struct{ SEmbedS1 }