diff --git a/ql/lib/semmle/go/Scopes.qll b/ql/lib/semmle/go/Scopes.qll index 91ac579b4..172156a0c 100644 --- a/ql/lib/semmle/go/Scopes.qll +++ b/ql/lib/semmle/go/Scopes.qll @@ -620,6 +620,9 @@ class Callable extends TCallable { result = this.asFuncLit().getType() } + /** Holds if this callable is variadic. */ + predicate isVariadic() { this.getType().isVariadic() } + /** Gets the name of this callable. */ string getName() { result = this.asFunction().getName() or diff --git a/ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll b/ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll index b6c1005da..177c5e854 100644 --- a/ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll +++ b/ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll @@ -16,6 +16,14 @@ private import semmle.go.dataflow.ExternalFlow predicate containerStoreStep(Node node1, Node node2, Content c) { c instanceof ArrayContent and ( + exists(ArgumentNode arg, ParameterNode parm, Callable fn | + arg = node1 and + parm = node2 and + arg.getCall().getACalleeIncludingExternals() = fn and + arg.isVariadic() and + parm.isParameterOf(fn, fn.getType().getNumParameter() - 1) = arg.getCall() + ) + or ( node2.getType() instanceof ArrayType or node2.getType() instanceof SliceType diff --git a/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll b/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll index a8453792f..f7e1a7ebd 100644 --- a/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll +++ b/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll @@ -542,6 +542,9 @@ module Public { /** Gets the data flow node corresponding to the receiver of this call, if any. */ Node getReceiver() { result = this.getACalleeSource().(MethodReadNode).getReceiver() } + /** Holds if this callee calls a callable that is variadic. */ + predicate isVariadic() { this.getACalleeIncludingExternals().isVariadic() } + /** Holds if this call has an ellipsis after its last argument. */ predicate hasEllipsis() { expr.hasEllipsis() } } @@ -714,6 +717,12 @@ module Public { ) } + /** Holds if this argument is to a call that has a variadic callee. */ + predicate isVariadic() { + this.getCall().isVariadic() and + i >= this.getCall().getACalleeIncludingExternals().getType().getNumParameter() - 1 + } + /** * Gets the `CallNode` this is an argument to. */
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: