Skip to content
This repository has been archived by the owner on Jan 5, 2023. It is now read-only.

Add support for variadic functions in container flow #643

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ql/lib/semmle/go/Scopes.qll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll
Original file line number Diff line number Diff line change
Expand Up @@ -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() }
}
Expand Down Expand Up @@ -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.
*/
Expand Down