diff --git a/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll index 997564a8c39..eeed7086546 100644 --- a/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll @@ -258,7 +258,8 @@ final class CallExprCfgNode extends Nodes::CallExprCfgNode { /** Gets the `i`th argument of this call. */ ExprCfgNode getSyntacticArgument(int i) { - any(ChildMapping mapping).hasCfgChild(node, node.getSyntacticArgument(i), this, result) + any(ChildMapping mapping) + .hasCfgChild(node, node.getSyntacticPositionalArgument(i), this, result) } } diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index 7cda3bc6ebf..522e5741795 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -210,13 +210,18 @@ module ExprTrees { override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() } } - class ArgsExprTree extends StandardPostOrderTree instanceof ArgsExpr { - ArgsExprTree() { + class InvocationExprTree extends StandardPostOrderTree instanceof InvocationExpr { + InvocationExprTree() { not this instanceof CallExpr and not this instanceof BinaryLogicalOperation } - override AstNode getChildNode(int i) { result = super.getSyntacticArgument(i) } + override AstNode getChildNode(int i) { + i = 0 and + result = super.getSyntacticReceiver() + or + result = super.getSyntacticPositionalArgument(i - 1) + } } class LogicalOrExprTree extends PostOrderTree, LogicalOrExpr { @@ -295,7 +300,7 @@ module ExprTrees { override AstNode getChildNode(int i) { i = 0 and result = super.getFunction() or - result = super.getSyntacticArgument(i - 1) + result = super.getSyntacticPositionalArgument(i - 1) } } @@ -533,10 +538,6 @@ module ExprTrees { } } - class RefExprTree extends StandardPostOrderTree instanceof RefExpr { - override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() } - } - class ReturnExprTree extends StandardPostOrderTree instanceof ReturnExpr { override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() } } diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/Content.qll b/rust/ql/lib/codeql/rust/dataflow/internal/Content.qll index c8b125bbbed..a072edef612 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/Content.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/Content.qll @@ -5,6 +5,7 @@ private import rust private import codeql.rust.frameworks.stdlib.Builtins private import DataFlowImpl +private import codeql.rust.elements.internal.CallExprImpl::Impl as CallExprImpl /** * A path to a value contained in an object. For example a field name of a struct. @@ -168,10 +169,10 @@ final class TuplePositionContent extends FieldContent, TTuplePositionContent { * Used by the model generator to create flow summaries for higher-order * functions. */ -final class ClosureCallArgumentContent extends Content, TClosureCallArgumentContent { +final class FunctionCallArgumentContent extends Content, TFunctionCallArgumentContent { private int pos; - ClosureCallArgumentContent() { this = TClosureCallArgumentContent(pos) } + FunctionCallArgumentContent() { this = TFunctionCallArgumentContent(pos) } int getPosition() { result = pos } @@ -269,8 +270,8 @@ newtype TContent = )] } or TFunctionCallReturnContent() or - TClosureCallArgumentContent(int pos) { - pos in [0 .. any(ClosureCallExpr c).getNumberOfPositionalArguments()] + TFunctionCallArgumentContent(int pos) { + pos in [0 .. any(CallExprImpl::DynamicCallExpr c).getNumberOfPositionalArguments()] } or TCapturedVariableContent(VariableCapture::CapturedVariable v) or TReferenceContent() diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 1dfef18a673..7a77b7de5b6 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -10,6 +10,7 @@ private import codeql.dataflow.internal.DataFlowImpl private import rust private import SsaImpl as SsaImpl private import codeql.rust.controlflow.internal.Scope as Scope +private import codeql.rust.elements.internal.CallExprImpl::Impl as CallExprImpl private import codeql.rust.internal.PathResolution private import codeql.rust.controlflow.ControlFlowGraph private import codeql.rust.dataflow.Ssa @@ -85,62 +86,10 @@ final class DataFlowCall extends TDataFlowCall { Location getLocation() { result = this.asCall().getLocation() } } -/** - * The position of a parameter in a function. - * - * In Rust there is a 1-to-1 correspondence between parameter positions and - * arguments positions, so we use the same underlying type for both. - */ -final class ParameterPosition extends TParameterPosition { - /** Gets the underlying integer position, if any. */ - int getPosition() { this = TPositionalParameterPosition(result) } - - predicate hasPosition() { exists(this.getPosition()) } - - /** Holds if this position represents the `self` position. */ - predicate isSelf() { this = TSelfParameterPosition() } - - /** - * Holds if this position represents a reference to a closure itself. Only - * used for tracking flow through captured variables. - */ - predicate isClosureSelf() { this = TClosureSelfParameterPosition() } - - /** Gets a textual representation of this position. */ - string toString() { - result = this.getPosition().toString() - or - result = "self" and this.isSelf() - or - result = "closure self" and this.isClosureSelf() - } - - ParamBase getParameterIn(ParamList ps) { - result = ps.getParam(this.getPosition()) - or - result = ps.getSelfParam() and this.isSelf() - } -} - -/** - * The position of an argument in a call. - * - * In Rust there is a 1-to-1 correspondence between parameter positions and - * arguments positions, so we use the same underlying type for both. - */ -final class ArgumentPosition extends ParameterPosition { - /** Gets the argument of `call` at this position, if any. */ - Expr getArgument(Call call) { - result = call.getPositionalArgument(this.getPosition()) - or - result = call.(MethodCall).getReceiver() and this.isSelf() - } -} - /** * Holds if `arg` is an argument of `call` at the position `pos`. */ -predicate isArgumentForCall(Expr arg, Call call, ArgumentPosition pos) { +predicate isArgumentForCall(Expr arg, Call call, RustDataFlow::ArgumentPosition pos) { // TODO: Handle index expressions as calls in data flow. not call instanceof IndexExpr and arg = pos.getArgument(call) @@ -292,8 +241,8 @@ predicate lambdaCreationExpr(Expr creation) { * Holds if `call` is a lambda call of kind `kind` where `receiver` is the * invoked expression. */ -predicate lambdaCallExpr(ClosureCallExpr call, LambdaCallKind kind, Expr receiver) { - receiver = call.getClosureExpr() and +predicate lambdaCallExpr(CallExprImpl::DynamicCallExpr call, LambdaCallKind kind, Expr receiver) { + receiver = call.getFunction() and exists(kind) } @@ -305,10 +254,6 @@ private module Aliases { class DataFlowCallAlias = DataFlowCall; - class ParameterPositionAlias = ParameterPosition; - - class ArgumentPositionAlias = ArgumentPosition; - class ContentAlias = Content; class ContentSetAlias = ContentSet; @@ -340,6 +285,58 @@ module RustDataFlow implements InputSig { final class CastNode = Node::CastNode; + /** + * The position of a parameter in a function. + * + * In Rust there is a 1-to-1 correspondence between parameter positions and + * arguments positions, so we use the same underlying type for both. + */ + final class ParameterPosition extends TParameterPosition { + /** Gets the underlying integer position, if any. */ + int getPosition() { this = TPositionalParameterPosition(result) } + + predicate hasPosition() { exists(this.getPosition()) } + + /** Holds if this position represents the `self` position. */ + predicate isSelf() { this = TSelfParameterPosition() } + + /** + * Holds if this position represents a reference to a closure itself. Only + * used for tracking flow through captured variables. + */ + predicate isClosureSelf() { this = TClosureSelfParameterPosition() } + + /** Gets a textual representation of this position. */ + string toString() { + result = this.getPosition().toString() + or + result = "self" and this.isSelf() + or + result = "closure self" and this.isClosureSelf() + } + + ParamBase getParameterIn(ParamList ps) { + result = ps.getParam(this.getPosition()) + or + result = ps.getSelfParam() and this.isSelf() + } + } + + /** + * The position of an argument in a call. + * + * In Rust there is a 1-to-1 correspondence between parameter positions and + * arguments positions, so we use the same underlying type for both. + */ + final class ArgumentPosition extends ParameterPosition { + /** Gets the argument of `call` at this position, if any. */ + Expr getArgument(Call call) { + result = call.getPositionalArgument(this.getPosition()) + or + result = call.(MethodCall).getReceiver() and this.isSelf() + } + } + /** Holds if `p` is a parameter of `c` at the position `pos`. */ predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) { p.isParameterOf(c, pos) @@ -449,10 +446,6 @@ module RustDataFlow implements InputSig { ContentApprox getContentApprox(Content c) { result = c } - class ParameterPosition = ParameterPositionAlias; - - class ArgumentPosition = ArgumentPositionAlias; - /** * Holds if the parameter position `ppos` matches the argument position * `apos`. @@ -664,7 +657,7 @@ module RustDataFlow implements InputSig { pragma[nomagic] additional predicate storeContentStep(Node node1, Content c, Node node2) { exists(CallExpr ce, TupleField tf, int pos | - node1.asExpr() = ce.getSyntacticArgument(pos) and + node1.asExpr() = ce.getSyntacticPositionalArgument(pos) and node2.asExpr() = ce and c = TTupleFieldContent(tf) | @@ -716,7 +709,7 @@ module RustDataFlow implements InputSig { exists(DataFlowCall call, int i | isArgumentNode(node1, call, TPositionalParameterPosition(i)) and lambdaCall(call, _, node2.(PostUpdateNode).getPreUpdateNode()) and - c.(ClosureCallArgumentContent).getPosition() = i + c.(FunctionCallArgumentContent).getPosition() = i ) or VariableCapture::storeStep(node1, c, node2) @@ -825,7 +818,7 @@ module RustDataFlow implements InputSig { */ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { ( - receiver.asExpr() = call.asCall().(ClosureCallExpr).getClosureExpr() + receiver.asExpr() = call.asCall().(CallExprImpl::DynamicCallExpr).getFunction() or call.isSummaryCall(_, receiver.(FlowSummaryNode).getSummaryNode()) ) and diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll index 891da92ab33..4aef065efdf 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll @@ -50,7 +50,7 @@ module Input implements InputSig { ReturnKind getStandardReturnValueKind() { result = TNormalReturnKind() } - string encodeParameterPosition(ParameterPosition pos) { result = pos.toString() } + string encodeParameterPosition(RustDataFlow::ParameterPosition pos) { result = pos.toString() } string encodeArgumentPosition(RustDataFlow::ArgumentPosition pos) { result = pos.toString() } @@ -105,7 +105,9 @@ module Input implements InputSig { string encodeWithContent(ContentSet c, string arg) { result = "With" + encodeContent(c, arg) } bindingset[token] - ParameterPosition decodeUnknownParameterPosition(AccessPath::AccessPathTokenBase token) { + RustDataFlow::ParameterPosition decodeUnknownParameterPosition( + AccessPath::AccessPathTokenBase token + ) { // needed to support `Argument[x..y]` ranges token.getName() = "Argument" and result.getPosition() = AccessPath::parseInt(token.getAnArgument()) @@ -132,7 +134,7 @@ private module StepsInput implements Impl::Private::StepsInputSig { /** Gets the argument of `source` described by `sc`, if any. */ private Expr getSourceNodeArgument(Input::SourceBase source, Impl::Private::SummaryComponent sc) { - exists(ArgumentPosition pos | + exists(RustDataFlow::ArgumentPosition pos | sc = Impl::Private::SummaryComponent::argument(pos) and result = pos.getArgument(source.getCall()) ) @@ -159,7 +161,7 @@ private module StepsInput implements Impl::Private::StepsInputSig { s.head() = Impl::Private::SummaryComponent::return(_) and result.asExpr() = source.getCall() or - exists(ArgumentPosition pos, Expr arg | + exists(RustDataFlow::ArgumentPosition pos, Expr arg | s.head() = Impl::Private::SummaryComponent::parameter(pos) and arg = getSourceNodeArgument(source, s.tail().headOfSingleton()) and result.asParameter() = getCallable(arg).getParam(pos.getPosition()) @@ -170,7 +172,7 @@ private module StepsInput implements Impl::Private::StepsInputSig { } RustDataFlow::Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { - exists(ArgsExpr call, Expr arg, ArgumentPosition pos | + exists(InvocationExpr call, Expr arg, RustDataFlow::ArgumentPosition pos | result.asExpr() = arg and sc = Impl::Private::SummaryComponent::argument(pos) and call = sink.getCall() and diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll b/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll index 29e47746990..1e4289afa3f 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll @@ -167,7 +167,7 @@ final class NameNode extends AstNodeNode, TNameNode { */ abstract class ParameterNode extends Node { /** Holds if this node is a parameter of `c` at position `pos`. */ - abstract predicate isParameterOf(DataFlowCallable c, ParameterPosition pos); + abstract predicate isParameterOf(DataFlowCallable c, RustDataFlow::ParameterPosition pos); } final class SourceParameterNode extends AstNodeNode, ParameterNode, TSourceParameterNode { @@ -175,12 +175,12 @@ final class SourceParameterNode extends AstNodeNode, ParameterNode, TSourceParam SourceParameterNode() { this = TSourceParameterNode(n) } - override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { + override predicate isParameterOf(DataFlowCallable c, RustDataFlow::ParameterPosition pos) { n = pos.getParameterIn(c.asCfgScope().(Callable).getParamList()) } /** Get the parameter position of this parameter. */ - ParameterPosition getPosition() { this.isParameterOf(_, result) } + RustDataFlow::ParameterPosition getPosition() { this.isParameterOf(_, result) } /** Gets the parameter in the CFG that this node corresponds to. */ ParamBase getParameter() { result = n } @@ -188,13 +188,13 @@ final class SourceParameterNode extends AstNodeNode, ParameterNode, TSourceParam /** A parameter for a library callable with a flow summary. */ final class SummaryParameterNode extends ParameterNode, FlowSummaryNode { - private ParameterPosition pos_; + private RustDataFlow::ParameterPosition pos_; SummaryParameterNode() { FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), pos_) } - override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { + override predicate isParameterOf(DataFlowCallable c, RustDataFlow::ParameterPosition pos) { this.getSummarizedCallable() = c.asSummarizedCallable() and pos = pos_ } } @@ -210,7 +210,7 @@ final class ClosureParameterNode extends ParameterNode, TClosureSelfReferenceNod final override CfgScope getCfgScope() { result = cfgScope } - override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { + override predicate isParameterOf(DataFlowCallable c, RustDataFlow::ParameterPosition pos) { cfgScope = c.asCfgScope() and pos.isClosureSelf() } diff --git a/rust/ql/lib/codeql/rust/elements/ArgsExpr.qll b/rust/ql/lib/codeql/rust/elements/ArgsExpr.qll deleted file mode 100644 index be0c1cea9c6..00000000000 --- a/rust/ql/lib/codeql/rust/elements/ArgsExpr.qll +++ /dev/null @@ -1,7 +0,0 @@ -/** - * This module provides the public class `ArgsExpr`. - */ - -private import internal.ArgsExprImpl - -final class ArgsExpr = Impl::ArgsExpr; diff --git a/rust/ql/lib/codeql/rust/elements/Call.qll b/rust/ql/lib/codeql/rust/elements/Call.qll index a7f84e77c4a..3a14425df1e 100644 --- a/rust/ql/lib/codeql/rust/elements/Call.qll +++ b/rust/ql/lib/codeql/rust/elements/Call.qll @@ -1,5 +1,5 @@ /** - * This module provides the public class `Call`. + * This module provides the public classes `Call` and `MethodCall`. */ private import rust @@ -9,21 +9,3 @@ private import internal.CallExprImpl::Impl as CallExprImpl final class Call = Impl::Call; final class MethodCall = Impl::MethodCall; - -/** - * A call expression that targets a closure. - * - * Closure calls never have a static target, and the set of potential - * run-time targets is only available internally to the data flow library. - */ -class ClosureCallExpr extends CallExprImpl::CallExprCall { - ClosureCallExpr() { - exists(Expr f | f = this.getFunction() | - // All calls to complex expressions and local variable accesses are lambda calls - f instanceof PathExpr implies f = any(Variable v).getAnAccess() - ) - } - - /** Gets the closure expression being called. */ - Expr getClosureExpr() { result = super.getFunction() } -} diff --git a/rust/ql/lib/codeql/rust/elements/InvocationExpr.qll b/rust/ql/lib/codeql/rust/elements/InvocationExpr.qll new file mode 100644 index 00000000000..315c6bdef84 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/InvocationExpr.qll @@ -0,0 +1,9 @@ +/** + * This module provides the public classes `InvocationExpr` and `ArgumentPosition`. + */ + +private import internal.InvocationExprImpl + +final class InvocationExpr = Impl::InvocationExpr; + +final class ArgumentPosition = Impl::ArgumentPosition; diff --git a/rust/ql/lib/codeql/rust/elements/internal/ArgsExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/ArgsExprImpl.qll deleted file mode 100644 index 19835c5029b..00000000000 --- a/rust/ql/lib/codeql/rust/elements/internal/ArgsExprImpl.qll +++ /dev/null @@ -1,37 +0,0 @@ -private import rust - -module Impl { - private import codeql.rust.internal.TypeInference as TypeInference - private import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl - - /** - * An expression with arguments. - * - * Either a `CallExpr`, a `MethodCallExpr`, an `Operation`, or an `IndexExpr`. - */ - abstract class ArgsExpr extends ExprImpl::Expr { - /** - * Gets the `i`th syntactic argument of this expression. - * - * Examples: - * ```rust - * foo(42, "bar"); // `42` is argument 0 and `"bar"` is argument 1 - * foo.bar(42); // `foo` is argument 0 and `42` is argument 1 - * x + y; // `x` is argument 0 and `y` is argument 1 - * x[y]; // `x` is argument 0 and `y` is argument 1 - * ``` - */ - Expr getSyntacticArgument(int i) { none() } - - /** Gets an argument of this expression. */ - Expr getASyntacticArgument() { result = this.getSyntacticArgument(_) } - - /** Gets the number of arguments of this expression. */ - int getNumberOfSyntacticArguments() { - result = count(Expr arg | arg = this.getSyntacticArgument(_)) - } - - /** Gets the resolved target (function or tuple struct/variant), if any. */ - Addressable getResolvedTarget() { result = TypeInference::resolveCallTarget(this) } - } -} diff --git a/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll index 24336e5b5f2..3de75d6bdc2 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll @@ -12,7 +12,7 @@ private import codeql.rust.elements.internal.generated.CallExpr */ module Impl { private import rust - private import codeql.rust.elements.internal.ArgsExprImpl::Impl as ArgsExprImpl + private import codeql.rust.elements.internal.InvocationExprImpl::Impl as InvocationExprImpl private import codeql.rust.elements.internal.CallImpl::Impl as CallImpl private import codeql.rust.internal.PathResolution as PathResolution private import codeql.rust.internal.TypeInference as TypeInference @@ -25,6 +25,8 @@ module Impl { result = PathResolution::resolvePath(getFunctionPath(ce)) } + private Expr getSyntacticArg(CallExpr ce, int i) { result = ce.getArgList().getArg(i) } + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * NOTE: Consider using `Call` instead, as that excludes call expressions that are @@ -38,20 +40,20 @@ module Impl { * Option::Some(42); // tuple variant instantiation * ``` */ - class CallExpr extends Generated::CallExpr, ArgsExprImpl::ArgsExpr { + class CallExpr extends Generated::CallExpr, InvocationExprImpl::InvocationExpr { override string toStringImpl() { result = this.getFunction().toAbbreviatedString() + "(...)" } - override Expr getSyntacticArgument(int i) { result = this.getArgList().getArg(i) } + override Expr getSyntacticPositionalArgument(int i) { result = getSyntacticArg(this, i) } // todo: remove once internal query has been updated - Expr getArg(int i) { result = this.getSyntacticArgument(i) } + Expr getArg(int i) { result = getSyntacticArg(this, i) } // todo: remove once internal query has been updated int getNumberOfArgs() { result = this.getNumberOfSyntacticArguments() } } /** - * A call expression that is _not_ an instantiation of a tuple struct or a tuple enum variant. + * A call expression that is _not_ an instantiation of a tuple struct or a tuple variant. * * For example: * ```rust @@ -67,7 +69,23 @@ module Impl { not this instanceof TupleVariantExpr } - override Expr getPositionalArgument(int i) { result = super.getSyntacticArgument(i) } + override Expr getPositionalArgument(int i) { result = getSyntacticArg(this, i) } + } + + /** + * A call expression that targets a closure (or any value that implements + * `Fn`, `FnMut`, or `FnOnce`). + * + * Dynamic calls never have a static target, and the set of potential + * run-time targets is only available internally to the data flow library. + */ + class DynamicCallExpr extends CallExprCall { + DynamicCallExpr() { + exists(Expr f | f = this.getFunction() | + // All calls to complex expressions and local variable accesses are lambda calls + f instanceof PathExpr implies f = any(Variable v).getAnAccess() + ) + } } /** @@ -77,20 +95,20 @@ module Impl { * layer, we do not check that the resolved target is a method in the charpred, * instead we check this in `getPositionalArgument` and `getReceiver`. */ - class CallExprMethodCall extends CallExprCall, CallImpl::MethodCall { - CallExprMethodCall() { not this instanceof ClosureCallExpr } + class CallExprMethodCall extends CallImpl::MethodCall instanceof CallExprCall { + CallExprMethodCall() { not this instanceof DynamicCallExpr } private predicate isInFactMethodCall() { this.getResolvedTarget() instanceof Method } override Expr getPositionalArgument(int i) { if this.isInFactMethodCall() - then result = this.getSyntacticArgument(i + 1) - else result = this.getSyntacticArgument(i) + then result = getSyntacticArg(this, i + 1) + else result = getSyntacticArg(this, i) } override Expr getReceiver() { this.isInFactMethodCall() and - result = super.getSyntacticArgument(0) + result = getSyntacticArg(this, 0) } } @@ -119,7 +137,7 @@ module Impl { } /** - * A call expression that instantiates a tuple enum variant. + * A call expression that instantiates a tuple variant. * * For example: * ```rust diff --git a/rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll index 339a53c92c1..ae01736f9fa 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll @@ -3,31 +3,56 @@ private import rust module Impl { private import codeql.rust.internal.TypeInference as TypeInference private import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl - private import codeql.rust.elements.internal.ArgsExprImpl::Impl as ArgsExprImpl + private import codeql.rust.elements.internal.InvocationExprImpl::Impl as InvocationExprImpl /** * A call. * * Either * - * - a `CallExpr` that is _not_ an instantiation of a tuple struct or a tuple enum variant, + * - a `CallExpr` that is _not_ an instantiation of a tuple struct or a tuple variant, * - a `MethodCallExpr`, * - an `Operation` that targets an overloadable operator, or * - an `IndexExpr`. */ - abstract class Call extends ArgsExprImpl::ArgsExpr { + abstract class Call extends InvocationExprImpl::InvocationExpr { + /** + * Gets the argument at position `pos` of this call. + * + * Examples: + * ```rust + * foo(42, "bar"); // `42` is argument 0 and `"bar"` is argument 1 + * foo.bar(42); // `foo` is receiver and `42` is argument 0 + * Foo::bar(foo, 42); // `foo` is receiver and `42` is argument 0 + * x + y; // `x` is receiver and `y` is argument 0 + * -x; // `x` is receiver + * x[y]; // `x` is receiver and `y` is argument 0 + * ``` + */ + final Expr getArgument(ArgumentPosition pos) { + result = this.getPositionalArgument(pos.asPosition()) + or + pos.isSelf() and + result = this.(MethodCall).getReceiver() + } + + /** Gets an argument of this call. */ + Expr getAnArgument() { result = this.getArgument(_) } + // todo: remove once internal query has been updated Expr getReceiver() { none() } /** - * Gets the `i`th positional argument of this call, if any. + * Gets the `i`th positional argument of this call. * * Examples: * ```rust - * foo(42, "bar"); // `42` is argument 0 and `"bar"` is argument 1 - * foo.bar(42); // `42` is argument 0 - * x + y; // `y` is argument 0 - * x[y]; // `y` is argument 0 + * foo(42, "bar"); // `42` is argument 0 and `"bar"` is argument 1 + * foo.bar(42); // `42` is argument 0 + * Foo::bar(foo, 42); // `42` is argument 0 + * x + y; // `y` is argument 0 + * -x; // no positional arguments + * x[y]; // `y` is argument 0 * ``` */ Expr getPositionalArgument(int i) { none() } @@ -43,10 +68,11 @@ module Impl { /** Gets the resolved target of this call, if any. */ Function getStaticTarget() { result = TypeInference::resolveCallTarget(this) } - /** Gets the name of the method called, if any. */ - string getMethodName() { - result = any(Function m | m = this.getStaticTarget() and m.hasSelfParam()).getName().getText() - } + /** Gets the name of the function called, if any. */ + string getTargetName() { result = this.getStaticTarget().getName().getText() } + + // todo: remove once internal query has been updated + string getMethodName() { result = this.getTargetName() } /** Gets a runtime target of this call, if any. */ pragma[nomagic] @@ -76,10 +102,12 @@ module Impl { * * Examples: * ```rust - * foo(42, "bar"); // no receiver - * foo.bar(42); // `foo` is receiver - * x + y; // `x` is receiver - * x[y]; // `x` is receiver + * foo(42, "bar"); // no receiver + * foo.bar(42); // `foo` is receiver + * Foo::bar(foo, 42); // `foo` is receiver + * x + y; // `x` is receiver + * -x; // `x` is receiver + * x[y]; // `x` is receiver * ``` */ override Expr getReceiver() { none() } diff --git a/rust/ql/lib/codeql/rust/elements/internal/IndexExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/IndexExprImpl.qll index 1fb801dc943..f5336497e28 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/IndexExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/IndexExprImpl.qll @@ -4,6 +4,7 @@ * INTERNAL: Do not use. */ +private import rust private import codeql.rust.elements.internal.generated.IndexExpr /** @@ -12,7 +13,6 @@ private import codeql.rust.elements.internal.generated.IndexExpr */ module Impl { private import codeql.rust.elements.internal.CallImpl::Impl as CallImpl - private import codeql.rust.elements.internal.ArgsExprImpl::Impl as ArgsExprImpl // the following QLdoc is generated: if you need to edit it, do it in the schema file /** @@ -28,7 +28,7 @@ module Impl { this.getBase().toAbbreviatedString() + "[" + this.getIndex().toAbbreviatedString() + "]" } - override Expr getSyntacticArgument(int i) { + override Expr getSyntacticPositionalArgument(int i) { i = 0 and result = this.getBase() or i = 1 and result = this.getIndex() diff --git a/rust/ql/lib/codeql/rust/elements/internal/InvocationExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/InvocationExprImpl.qll new file mode 100644 index 00000000000..f3cf32248e1 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/internal/InvocationExprImpl.qll @@ -0,0 +1,99 @@ +private import rust + +module Impl { + private import codeql.rust.internal.TypeInference as TypeInference + private import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl + + private newtype TArgumentPosition = + TPositionalArgumentPosition(int i) { + i in [0 .. max([any(ParamList l).getNumberOfParams(), any(ArgList l).getNumberOfArgs()]) - 1] + } or + TSelfArgumentPosition() + + /** An argument position in a call. */ + class ArgumentPosition extends TArgumentPosition { + /** Gets the index of the argument in the call, if this is a positional argument. */ + int asPosition() { this = TPositionalArgumentPosition(result) } + + /** Holds if this call position is a self argument. */ + predicate isSelf() { this instanceof TSelfArgumentPosition } + + /** Gets a string representation of this argument position. */ + string toString() { + result = this.asPosition().toString() + or + this.isSelf() and result = "self" + } + } + + /** + * An expression with arguments. + * + * Either a `CallExpr`, a `MethodCallExpr`, an `Operation`, or an `IndexExpr`. + */ + abstract class InvocationExpr extends ExprImpl::Expr { + /** + * Gets the `i`th syntactical argument of this expression. + * + * Examples: + * ```rust + * foo(42, "bar"); // `42` is syntactic argument 0 and `"bar"` is syntactic argument 1 + * foo.bar(42); // `42` is syntactic argument 0 + * Foo::bar(foo, 42); // `foo` is syntactic argument 0 and `42` is syntactic argument 1 + * Option::Some(x); // `x` is syntactic argument 0 + * x + y; // `x` is syntactic argument 0 and `y` is syntactic argument 1 + * -x; // `x` is syntactic argument 0 + * x[y]; // `x` is syntactic argument 0 and `y` is syntactic argument 1 + * ``` + */ + Expr getSyntacticPositionalArgument(int i) { none() } + + /** + * Gets the syntactic receiver of this expression, if any. + * + * Examples: + * ```rust + * foo(42, "bar"); // no syntactic receiver + * foo.bar(42); // `foo` is syntactic receiver + * Foo::bar(foo, 42); // no syntactic receiver + * Option::Some(x); // no syntactic receiver + * x + y; // no syntactic receiver + * -x; // no syntactic receiver + * x[y]; // no syntactic receiver + * ``` + */ + Expr getSyntacticReceiver() { none() } + + /** + * Gets the argument at syntactic position `pos` of this expression. + * + * Examples: + * ```rust + * foo(42, "bar"); // `42` is syntactic argument 0 and `"bar"` is syntactic argument 1 + * foo.bar(42); // `foo` is syntactic receiver and `42` is syntactic argument 0 + * Foo::bar(foo, 42); // `foo` is syntactic argument 0 and `42` is syntactic argument 1 + * Option::Some(x); // `x` is syntactic argument 0 + * x + y; // `x` is syntactic argument 0 and `y` is syntactic argument 1 + * -x; // `x` is syntactic argument 0 + * x[y]; // `x` is syntactic argument 0 and `y` is syntactic argument 1 + * ``` + */ + final Expr getSyntacticArgument(ArgumentPosition pos) { + result = this.getSyntacticPositionalArgument(pos.asPosition()) + or + pos.isSelf() and + result = this.getSyntacticReceiver() + } + + /** Gets a syntactic argument of this expression. */ + Expr getASyntacticArgument() { result = this.getSyntacticArgument(_) } + + /** Gets the number of syntactic arguments of this expression. */ + int getNumberOfSyntacticArguments() { + result = count(Expr arg | arg = this.getSyntacticArgument(_)) + } + + /** Gets the resolved target (function or tuple struct/variant), if any. */ + Addressable getResolvedTarget() { result = TypeInference::resolveCallTarget(this) } + } +} diff --git a/rust/ql/lib/codeql/rust/elements/internal/MethodCallExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/MethodCallExprImpl.qll index 635f0846551..d5fa29b26b2 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/MethodCallExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/MethodCallExprImpl.qll @@ -13,7 +13,7 @@ private import codeql.rust.elements.internal.generated.MethodCallExpr */ module Impl { private import codeql.rust.elements.internal.CallImpl::Impl as CallImpl - private import codeql.rust.elements.internal.ArgsExprImpl::Impl as ArgsExprImpl + private import codeql.rust.elements.internal.InvocationExprImpl::Impl as InvocationExprImpl // the following QLdoc is generated: if you need to edit it, do it in the schema file /** @@ -46,11 +46,9 @@ module Impl { result = strictconcat(int i | | this.toStringPart(i) order by i) } - override Expr getSyntacticArgument(int i) { - i = 0 and result = this.getReceiver() - or - result = this.getPositionalArgument(i - 1) - } + override Expr getSyntacticPositionalArgument(int i) { result = this.getArgList().getArg(i) } + + override Expr getSyntacticReceiver() { result = Generated::MethodCallExpr.super.getReceiver() } override Expr getPositionalArgument(int i) { result = this.getArgList().getArg(i) } diff --git a/rust/ql/lib/codeql/rust/elements/internal/OperationImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/OperationImpl.qll index c34396b26b9..58dcdeb481f 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/OperationImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/OperationImpl.qll @@ -13,7 +13,7 @@ private import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl */ module Impl { private import codeql.rust.elements.internal.CallImpl::Impl as CallImpl - private import codeql.rust.elements.internal.ArgsExprImpl::Impl as ArgsExprImpl + private import codeql.rust.elements.internal.InvocationExprImpl::Impl as InvocationExprImpl /** * Holds if the operator `op` with arity `arity` is overloaded to a trait with @@ -108,14 +108,14 @@ module Impl { * for `Add::add(x, y)`, and `x += y` is syntactic sugar for * `AddAssign::add_assign(&mut x, y)`. */ - abstract class Operation extends ArgsExprImpl::ArgsExpr { + abstract class Operation extends InvocationExprImpl::InvocationExpr { /** Gets the operator name of this operation, if it exists. */ abstract string getOperatorName(); /** Gets the `n`th operand of this operation, if any. */ abstract Expr getOperand(int n); - override Expr getSyntacticArgument(int i) { result = this.getOperand(i) } + override Expr getSyntacticPositionalArgument(int i) { result = this.getOperand(i) } /** * Gets the number of operands of this operation. @@ -140,7 +140,7 @@ module Impl { private class OperationMethodCall extends CallImpl::MethodCall instanceof Operation { OperationMethodCall() { super.isOverloaded(_, _, _) } - override Expr getPositionalArgument(int i) { result = super.getOperand(i + 1) and i >= 0 } + override Expr getPositionalArgument(int i) { result = super.getOperand(i + 1) } override Expr getReceiver() { result = super.getOperand(0) } } diff --git a/rust/ql/lib/codeql/rust/frameworks/rustcrypto/RustCrypto.qll b/rust/ql/lib/codeql/rust/frameworks/rustcrypto/RustCrypto.qll index 2448c48c2d8..6e50659103d 100644 --- a/rust/ql/lib/codeql/rust/frameworks/rustcrypto/RustCrypto.qll +++ b/rust/ql/lib/codeql/rust/frameworks/rustcrypto/RustCrypto.qll @@ -26,8 +26,7 @@ class StreamCipherInit extends Cryptography::CryptographicOperation::Range { // `cipher::KeyIvInit::new`, `cipher::KeyIvInit::new_from_slices`, `rc2::Rc2::new_with_eff_key_len` or similar. exists(Call call, string rawAlgorithmName | call = this.asExpr() and - call.getStaticTarget().getName().getText() = - ["new", "new_from_slice", "new_with_eff_key_len", "new_from_slices"] and + call.getTargetName() = ["new", "new_from_slice", "new_with_eff_key_len", "new_from_slices"] and // extract the algorithm name from the type of `ce` or its receiver. exists(Type t, TypePath tp | t = inferType([call, call.(MethodCall).getReceiver()], tp) and diff --git a/rust/ql/lib/codeql/rust/internal/PathResolutionConsistency.qll b/rust/ql/lib/codeql/rust/internal/PathResolutionConsistency.qll index 852e8b83fb0..857afc1f552 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolutionConsistency.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolutionConsistency.qll @@ -25,7 +25,7 @@ query predicate multiplePathResolutions(Path p, ItemNode i) { } // TODO: Take other calls into account -abstract private class CallExprBase extends ArgsExpr { } +abstract private class CallExprBase extends InvocationExpr { } private class CallExprCallExprBase extends CallExpr, CallExprBase { } diff --git a/rust/ql/lib/codeql/rust/internal/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/TypeInference.qll index 079abbf1b36..05675a42088 100644 --- a/rust/ql/lib/codeql/rust/internal/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/TypeInference.qll @@ -1624,10 +1624,7 @@ private module MethodResolution { } override Expr getArg(ArgumentPosition pos) { - pos.isSelf() and - result = MethodCallExpr.super.getReceiver() - or - result = super.getArgList().getArg(pos.asPosition()) + result = MethodCallExpr.super.getSyntacticArgument(pos) } override predicate supportsAutoDerefAndBorrow() { any() } @@ -1685,9 +1682,9 @@ private module MethodResolution { override Expr getArg(ArgumentPosition pos) { pos.isSelf() and - result = super.getSyntacticArgument(0) + result = super.getSyntacticPositionalArgument(0) or - result = super.getSyntacticArgument(pos.asPosition() + 1) + result = super.getSyntacticPositionalArgument(pos.asPosition() + 1) } // needed for `TypeQualifierIsInstantiationOfImplSelfInput` @@ -2383,7 +2380,7 @@ private module NonMethodResolution { } AstNode getNodeAt(FunctionPosition pos) { - result = this.getSyntacticArgument(pos.asPosition()) + result = this.getSyntacticArgument(pos.asArgumentPosition()) or result = this and pos.isReturn() } @@ -3415,7 +3412,7 @@ private Type inferDynamicCallExprType(Expr n, TypePath path) { or // Propagate the function's parameter type to the arguments exists(int index | - n = ce.getCall().getSyntacticArgument(index) and + n = ce.getCall().getSyntacticPositionalArgument(index) and path = path0.stripPrefix(fnParameterPath(ce.getCall().getArgList().getNumberOfArgs(), index)) ) @@ -3631,7 +3628,7 @@ private module Debug { result = inferType(n, path) } - Addressable debugResolveCallTarget(ArgsExpr c) { + Addressable debugResolveCallTarget(InvocationExpr c) { c = getRelevantLocatable() and result = resolveCallTarget(c) } diff --git a/rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll b/rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll index 79bc2dbd3f7..c219ef0eacc 100644 --- a/rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll +++ b/rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll @@ -4,28 +4,6 @@ private import codeql.rust.internal.PathResolution private import codeql.rust.internal.Type private import codeql.rust.internal.TypeMention -private newtype TArgumentPosition = - TPositionalArgumentPosition(int i) { - i in [0 .. max([any(ParamList l).getNumberOfParams(), any(ArgList l).getNumberOfArgs()]) - 1] - } or - TSelfArgumentPosition() - -/** An argument position in a call. */ -class ArgumentPosition extends TArgumentPosition { - /** Gets the index of the argument in the call, if this is a positional argument. */ - int asPosition() { this = TPositionalArgumentPosition(result) } - - /** Holds if this call position is a self argument. */ - predicate isSelf() { this instanceof TSelfArgumentPosition } - - /** Gets a string representation of this argument position. */ - string toString() { - result = this.asPosition().toString() - or - this.isSelf() and result = "self" - } -} - private newtype TFunctionPosition = TArgumentFunctionPosition(ArgumentPosition pos) or TReturnFunctionPosition() diff --git a/rust/ql/lib/codeql/rust/security/SensitiveData.qll b/rust/ql/lib/codeql/rust/security/SensitiveData.qll index 94c69f834a6..c4cd7c31366 100644 --- a/rust/ql/lib/codeql/rust/security/SensitiveData.qll +++ b/rust/ql/lib/codeql/rust/security/SensitiveData.qll @@ -28,7 +28,7 @@ private class SensitiveDataCall extends SensitiveData { SensitiveDataClassification classification; SensitiveDataCall() { - exists(ArgsExpr call, Addressable target, string name | + exists(InvocationExpr call, Addressable target, string name | call = this.asExpr() and target = call.getResolvedTarget() and name = diff --git a/rust/ql/lib/codeql/rust/security/XssExtensions.qll b/rust/ql/lib/codeql/rust/security/XssExtensions.qll index 46ac5c5099e..cb0510cd704 100644 --- a/rust/ql/lib/codeql/rust/security/XssExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/XssExtensions.qll @@ -53,9 +53,9 @@ module Xss { /** A call to a function with "escape" or "encode" in its name. */ private class HeuristicHtmlEncodingBarrier extends Barrier { HeuristicHtmlEncodingBarrier() { - exists(Call fc | - fc.getStaticTarget().getName().getText().regexpMatch(".*(escape|encode).*") and - fc.getAPositionalArgument() = this.asExpr() + exists(Call c | + c.getStaticTarget().getName().getText().regexpMatch(".*(escape|encode).*") and + c.getAnArgument() = this.asExpr() ) } } diff --git a/rust/ql/lib/rust.qll b/rust/ql/lib/rust.qll index 2b6adfd4d5d..410f062d91e 100644 --- a/rust/ql/lib/rust.qll +++ b/rust/ql/lib/rust.qll @@ -6,7 +6,7 @@ import codeql.Locations import codeql.files.FileSystem import codeql.rust.elements.Operation import codeql.rust.elements.ArithmeticOperation -import codeql.rust.elements.ArgsExpr +import codeql.rust.elements.InvocationExpr import codeql.rust.elements.AssignmentOperation import codeql.rust.elements.BitwiseOperation import codeql.rust.elements.ComparisonOperation diff --git a/rust/ql/lib/utils/test/InlineFlowTest.qll b/rust/ql/lib/utils/test/InlineFlowTest.qll index 8b48fbb1cc7..c1398df9e11 100644 --- a/rust/ql/lib/utils/test/InlineFlowTest.qll +++ b/rust/ql/lib/utils/test/InlineFlowTest.qll @@ -31,7 +31,7 @@ private module FlowTestImpl implements InputSig { private string getSourceArgString(DataFlow::Node src) { defaultSource(src) and - result = src.asExpr().(CallExpr).getSyntacticArgument(0).toString() + result = src.asExpr().(Call).getPositionalArgument(0).toString() or sourceNode(src, _) and result = diff --git a/rust/ql/src/queries/telemetry/DatabaseQuality.qll b/rust/ql/src/queries/telemetry/DatabaseQuality.qll index 7a5523c8b00..553783498ae 100644 --- a/rust/ql/src/queries/telemetry/DatabaseQuality.qll +++ b/rust/ql/src/queries/telemetry/DatabaseQuality.qll @@ -6,6 +6,7 @@ import rust import codeql.util.ReportStats +import codeql.rust.elements.internal.CallExprImpl::Impl as CallExprImpl import codeql.rust.internal.TypeInference as TypeInference /** @@ -20,7 +21,7 @@ private class RelevantFile extends File { module CallTargetStats implements StatsSig { // TODO: Take other calls into account - abstract private class CallExprBase extends ArgsExpr { } + abstract private class CallExprBase extends InvocationExpr { } private class CallExprCallExprBase extends CallExpr, CallExprBase { } @@ -34,7 +35,7 @@ module CallTargetStats implements StatsSig { additional predicate isNotOkCall(CallExprBase c) { c.getFile() instanceof RelevantFile and not exists(c.getResolvedTarget()) and - not c instanceof ClosureCallExpr + not c instanceof CallExprImpl::DynamicCallExpr } int getNumberOfNotOk() { result = count(CallExprBase c | isNotOkCall(c)) } diff --git a/rust/ql/src/utils/modelgenerator/internal/CaptureModels.qll b/rust/ql/src/utils/modelgenerator/internal/CaptureModels.qll index 5c54e8a7842..9826f56795f 100644 --- a/rust/ql/src/utils/modelgenerator/internal/CaptureModels.qll +++ b/rust/ql/src/utils/modelgenerator/internal/CaptureModels.qll @@ -67,8 +67,9 @@ module ModelGeneratorCommonInput implements string parameterExactAccess(R::ParamBase p) { result = - "Argument[" + any(DataFlowImpl::ParameterPosition pos | p = pos.getParameterIn(_)).toString() + - "]" + "Argument[" + + any(DataFlowImpl::RustDataFlow::ParameterPosition pos | p = pos.getParameterIn(_)) + .toString() + "]" } string parameterApproximateAccess(R::ParamBase p) { result = parameterExactAccess(p) } @@ -78,12 +79,16 @@ module ModelGeneratorCommonInput implements } bindingset[c] - string paramReturnNodeAsApproximateOutput(QualifiedCallable c, DataFlowImpl::ParameterPosition pos) { + string paramReturnNodeAsApproximateOutput( + QualifiedCallable c, DataFlowImpl::RustDataFlow::ParameterPosition pos + ) { result = paramReturnNodeAsExactOutput(c, pos) } bindingset[c] - string paramReturnNodeAsExactOutput(QualifiedCallable c, DataFlowImpl::ParameterPosition pos) { + string paramReturnNodeAsExactOutput( + QualifiedCallable c, DataFlowImpl::RustDataFlow::ParameterPosition pos + ) { result = parameterExactAccess(c.getFunction().getParam(pos.getPosition())) or pos.isSelf() and result = qualifierString() @@ -134,7 +139,7 @@ private module SummaryModelGeneratorInput implements SummaryModelGeneratorInputS predicate isCallback(DataFlow::ContentSet cs) { exists(Content c | c = cs.(SingletonContentSet).getContent() | c instanceof FunctionCallReturnContent or - c instanceof ClosureCallArgumentContent + c instanceof FunctionCallArgumentContent ) } @@ -145,7 +150,7 @@ private module SummaryModelGeneratorInput implements SummaryModelGeneratorInputS or exists(Content c | cs = DataFlowImpl::TSingletonContentSet(c) | exists(int pos | - pos = c.(ClosureCallArgumentContent).getPosition() and + pos = c.(FunctionCallArgumentContent).getPosition() and result = "Parameter" and arg = pos.toString() ) diff --git a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected index c3fdbbee6ff..16e6f165028 100644 --- a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected +++ b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected @@ -2,18 +2,15 @@ instances | gen_call_expr.rs:8:5:8:11 | foo(...) | | gen_call_expr.rs:9:5:9:23 | foo::<...>(...) | | gen_call_expr.rs:10:5:10:14 | ...(...) | -| gen_call_expr.rs:11:5:11:10 | foo(...) | -| gen_call_expr.rs:12:5:12:20 | ...::Some(...) | +| gen_call_expr.rs:11:5:11:20 | ...::Some(...) | getArgList | gen_call_expr.rs:8:5:8:11 | foo(...) | gen_call_expr.rs:8:8:8:11 | ArgList | | gen_call_expr.rs:9:5:9:23 | foo::<...>(...) | gen_call_expr.rs:9:20:9:23 | ArgList | | gen_call_expr.rs:10:5:10:14 | ...(...) | gen_call_expr.rs:10:11:10:14 | ArgList | -| gen_call_expr.rs:11:5:11:10 | foo(...) | gen_call_expr.rs:11:8:11:10 | ArgList | -| gen_call_expr.rs:12:5:12:20 | ...::Some(...) | gen_call_expr.rs:12:17:12:20 | ArgList | +| gen_call_expr.rs:11:5:11:20 | ...::Some(...) | gen_call_expr.rs:11:17:11:20 | ArgList | getAttr getFunction | gen_call_expr.rs:8:5:8:11 | foo(...) | gen_call_expr.rs:8:5:8:7 | foo | | gen_call_expr.rs:9:5:9:23 | foo::<...>(...) | gen_call_expr.rs:9:5:9:19 | foo::<...> | | gen_call_expr.rs:10:5:10:14 | ...(...) | gen_call_expr.rs:10:5:10:10 | foo[0] | -| gen_call_expr.rs:11:5:11:10 | foo(...) | gen_call_expr.rs:11:5:11:7 | foo | -| gen_call_expr.rs:12:5:12:20 | ...::Some(...) | gen_call_expr.rs:12:5:12:16 | ...::Some | +| gen_call_expr.rs:11:5:11:20 | ...::Some(...) | gen_call_expr.rs:11:5:11:16 | ...::Some | diff --git a/rust/ql/test/library-tests/dataflow/sources/net/InlineFlow.expected b/rust/ql/test/library-tests/dataflow/sources/net/InlineFlow.expected index 9682ff1a01d..c74ffd2989f 100644 --- a/rust/ql/test/library-tests/dataflow/sources/net/InlineFlow.expected +++ b/rust/ql/test/library-tests/dataflow/sources/net/InlineFlow.expected @@ -183,7 +183,11 @@ edges | test.rs:389:61:389:66 | [post] buffer | test.rs:392:23:392:33 | buffer[...] | provenance | | | test.rs:391:23:391:28 | buffer | test.rs:391:22:391:28 | &buffer | provenance | | | test.rs:392:23:392:33 | buffer[...] | test.rs:392:22:392:33 | &... | provenance | | +| test.rs:399:63:399:73 | &mut reader [&ref] | test.rs:399:63:399:73 | [post] &mut reader [&ref] | provenance | MaD:13 | | test.rs:399:63:399:73 | &mut reader [&ref] | test.rs:399:76:399:87 | [post] &mut buffer1 [&ref] | provenance | MaD:13 | +| test.rs:399:63:399:73 | [post] &mut reader [&ref] | test.rs:399:68:399:73 | [post] reader | provenance | | +| test.rs:399:68:399:73 | [post] reader | test.rs:403:31:403:36 | reader | provenance | | +| test.rs:399:68:399:73 | [post] reader | test.rs:408:55:408:60 | reader | provenance | | | test.rs:399:68:399:73 | reader | test.rs:399:63:399:73 | &mut reader [&ref] | provenance | | | test.rs:399:76:399:87 | [post] &mut buffer1 [&ref] | test.rs:399:81:399:87 | [post] buffer1 | provenance | | | test.rs:399:81:399:87 | [post] buffer1 | test.rs:400:19:400:40 | buffer1[...] | provenance | | @@ -257,7 +261,15 @@ edges | test.rs:447:61:447:66 | [post] buffer | test.rs:450:23:450:33 | buffer[...] | provenance | | | test.rs:448:19:448:24 | buffer | test.rs:448:18:448:24 | &buffer | provenance | | | test.rs:450:23:450:33 | buffer[...] | test.rs:450:22:450:33 | &... | provenance | | +| test.rs:457:63:457:74 | &mut reader2 [&ref] | test.rs:457:63:457:74 | [post] &mut reader2 [&ref] | provenance | MaD:13 | | test.rs:457:63:457:74 | &mut reader2 [&ref] | test.rs:457:77:457:88 | [post] &mut buffer1 [&ref] | provenance | MaD:13 | +| test.rs:457:63:457:74 | [post] &mut reader2 [&ref] | test.rs:457:68:457:74 | [post] reader2 | provenance | | +| test.rs:457:68:457:74 | [post] reader2 | test.rs:461:31:461:37 | reader2 | provenance | | +| test.rs:457:68:457:74 | [post] reader2 | test.rs:467:44:467:50 | reader2 | provenance | | +| test.rs:457:68:457:74 | [post] reader2 | test.rs:479:26:479:32 | reader2 | provenance | | +| test.rs:457:68:457:74 | [post] reader2 | test.rs:486:31:486:37 | reader2 | provenance | | +| test.rs:457:68:457:74 | [post] reader2 | test.rs:493:31:493:37 | reader2 | provenance | | +| test.rs:457:68:457:74 | [post] reader2 | test.rs:500:31:500:37 | reader2 | provenance | | | test.rs:457:68:457:74 | reader2 | test.rs:457:63:457:74 | &mut reader2 [&ref] | provenance | | | test.rs:457:77:457:88 | [post] &mut buffer1 [&ref] | test.rs:457:82:457:88 | [post] buffer1 | provenance | | | test.rs:457:82:457:88 | [post] buffer1 | test.rs:458:19:458:40 | buffer1[...] | provenance | | @@ -461,6 +473,8 @@ nodes | test.rs:392:22:392:33 | &... | semmle.label | &... | | test.rs:392:23:392:33 | buffer[...] | semmle.label | buffer[...] | | test.rs:399:63:399:73 | &mut reader [&ref] | semmle.label | &mut reader [&ref] | +| test.rs:399:63:399:73 | [post] &mut reader [&ref] | semmle.label | [post] &mut reader [&ref] | +| test.rs:399:68:399:73 | [post] reader | semmle.label | [post] reader | | test.rs:399:68:399:73 | reader | semmle.label | reader | | test.rs:399:76:399:87 | [post] &mut buffer1 [&ref] | semmle.label | [post] &mut buffer1 [&ref] | | test.rs:399:81:399:87 | [post] buffer1 | semmle.label | [post] buffer1 | @@ -529,6 +543,8 @@ nodes | test.rs:450:22:450:33 | &... | semmle.label | &... | | test.rs:450:23:450:33 | buffer[...] | semmle.label | buffer[...] | | test.rs:457:63:457:74 | &mut reader2 [&ref] | semmle.label | &mut reader2 [&ref] | +| test.rs:457:63:457:74 | [post] &mut reader2 [&ref] | semmle.label | [post] &mut reader2 [&ref] | +| test.rs:457:68:457:74 | [post] reader2 | semmle.label | [post] reader2 | | test.rs:457:68:457:74 | reader2 | semmle.label | reader2 | | test.rs:457:77:457:88 | [post] &mut buffer1 [&ref] | semmle.label | [post] &mut buffer1 [&ref] | | test.rs:457:82:457:88 | [post] buffer1 | semmle.label | [post] buffer1 |