diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowConsistency.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowConsistency.qll index 9202985a8527..c95056a7dba0 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowConsistency.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowConsistency.qll @@ -18,6 +18,8 @@ private module Input implements InputSig { // We allow flow into post-update node for receiver expressions (from the // synthetic post receiever node). n.(Node::PostUpdateNode).getPreUpdateNode().asExpr() = any(Node::ReceiverNode r).getReceiver() + or + n.(Node::PostUpdateNode).getPreUpdateNode().asExpr() = getPostUpdateReverseStep(_, _) } predicate missingLocationExclude(RustDataFlow::Node n) { not exists(n.asExpr().getLocation()) } diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 0dc31a7966e9..82d817dca976 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -213,6 +213,28 @@ private ExprCfgNode getALastEvalNode(ExprCfgNode e) { result.(BreakExprCfgNode).getTarget() = e } +/** + * Holds if a reverse local flow step should be added from the post-update node + * for `e` to the post-update node for the result. + * + * This is needed to allow for side-effects on compound expressions to propagate + * to sub components. For example, in + * + * ```rust + * ({ foo(); &mut a}).set_data(taint); + * ``` + * + * we add a reverse flow step from `[post] { foo(); &mut a}` to `[post] &mut a`, + * in order for the side-effect of `set_data` to reach `&mut a`. + */ +ExprCfgNode getPostUpdateReverseStep(ExprCfgNode e, boolean preservesValue) { + result = getALastEvalNode(e) and + preservesValue = true + or + result = e.(CastExprCfgNode).getExpr() and + preservesValue = false +} + module LocalFlow { predicate flowSummaryLocalStep(Node nodeFrom, Node nodeTo, string model) { exists(FlowSummaryImpl::Public::SummarizedCallable c | @@ -274,6 +296,9 @@ module LocalFlow { // The dual step of the above, for the post-update nodes. nodeFrom.(PostUpdateNode).getPreUpdateNode().(ReceiverNode).getReceiver() = nodeTo.(PostUpdateNode).getPreUpdateNode().asExpr() + or + nodeTo.(PostUpdateNode).getPreUpdateNode().asExpr() = + getPostUpdateReverseStep(nodeFrom.(PostUpdateNode).getPreUpdateNode().asExpr(), true) } } diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll b/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll index c84da6712bbd..108d22abc343 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll @@ -29,7 +29,7 @@ abstract class NodePublic extends TNode { /** * Gets the expression that corresponds to this node, if any. */ - ExprCfgNode asExpr() { none() } + final ExprCfgNode asExpr() { this = TExprNode(result) } /** * Gets the parameter that corresponds to this node, if any. @@ -39,7 +39,7 @@ abstract class NodePublic extends TNode { /** * Gets the pattern that corresponds to this node, if any. */ - PatCfgNode asPat() { none() } + final PatCfgNode asPat() { this = TPatNode(result) } } abstract class Node extends NodePublic { @@ -144,16 +144,12 @@ class ExprNode extends AstCfgFlowNode, TExprNode { override ExprCfgNode n; ExprNode() { this = TExprNode(n) } - - override ExprCfgNode asExpr() { result = n } } final class PatNode extends AstCfgFlowNode, TPatNode { override PatCfgNode n; PatNode() { this = TPatNode(n) } - - override PatCfgNode asPat() { result = n } } /** A data flow node that corresponds to a name node in the CFG. */ @@ -467,10 +463,12 @@ newtype TNode = or e = [ - any(IndexExprCfgNode i).getBase(), any(FieldExprCfgNode access).getExpr(), - any(TryExprCfgNode try).getExpr(), - any(PrefixExprCfgNode pe | pe.getOperatorName() = "*").getExpr(), - any(AwaitExprCfgNode a).getExpr(), any(MethodCallExprCfgNode mc).getReceiver() + any(IndexExprCfgNode i).getBase(), // + any(FieldExprCfgNode access).getExpr(), // + any(TryExprCfgNode try).getExpr(), // + any(PrefixExprCfgNode pe | pe.getOperatorName() = "*").getExpr(), // + any(AwaitExprCfgNode a).getExpr(), any(MethodCallExprCfgNode mc).getReceiver(), // + getPostUpdateReverseStep(any(PostUpdateNode n).getPreUpdateNode().asExpr(), _) ] } or TReceiverNode(MethodCallExprCfgNode mc, Boolean isPost) or diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll index 2e10977a95d2..7d3ccea4809d 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll @@ -332,6 +332,8 @@ import Cached private import codeql.rust.dataflow.Ssa private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInputSig { + private import codeql.rust.dataflow.internal.DataFlowImpl as DataFlowImpl + class Expr extends CfgNodes::AstCfgNode { predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { this = bb.getNode(i) } } @@ -343,14 +345,22 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu none() // handled in `DataFlowImpl.qll` instead } + private predicate isArg(CfgNodes::CallExprBaseCfgNode call, CfgNodes::ExprCfgNode e) { + call.getArgument(_) = e + or + call.(CfgNodes::MethodCallExprCfgNode).getReceiver() = e + or + exists(CfgNodes::ExprCfgNode mid | + isArg(call, mid) and + e = DataFlowImpl::getPostUpdateReverseStep(mid, _) + ) + } + predicate allowFlowIntoUncertainDef(UncertainWriteDefinition def) { exists(CfgNodes::CallExprBaseCfgNode call, Variable v, BasicBlock bb, int i | def.definesAt(v, bb, i) and - mutablyBorrows(bb.getNode(i).getAstNode(), v) - | - call.getArgument(_) = bb.getNode(i) - or - call.(CfgNodes::MethodCallExprCfgNode).getReceiver() = bb.getNode(i) + mutablyBorrows(bb.getNode(i).getAstNode(), v) and + isArg(call, bb.getNode(i)) ) } diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/TaintTrackingImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/TaintTrackingImpl.qll index 7cef3b58f554..e64f697d929f 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/TaintTrackingImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/TaintTrackingImpl.qll @@ -53,6 +53,9 @@ module RustTaintTracking implements InputSig { exists(FormatArgsExprCfgNode format | succ.asExpr() = format | pred.asExpr() = [format.getArgumentExpr(_), format.getFormatTemplateVariableAccess(_)] ) + or + succ.(Node::PostUpdateNode).getPreUpdateNode().asExpr() = + getPostUpdateReverseStep(pred.(Node::PostUpdateNode).getPreUpdateNode().asExpr(), false) ) or FlowSummaryImpl::Private::Steps::summaryLocalStep(pred.(Node::FlowSummaryNode).getSummaryNode(), diff --git a/rust/ql/test/library-tests/dataflow/global/inline-flow.expected b/rust/ql/test/library-tests/dataflow/global/inline-flow.expected index 54b70e0ac128..291d43d1a62c 100644 --- a/rust/ql/test/library-tests/dataflow/global/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/global/inline-flow.expected @@ -4,185 +4,231 @@ edges | main.rs:13:5:13:13 | source(...) | main.rs:12:28:14:1 | { ... } | provenance | | | main.rs:17:9:17:9 | a | main.rs:18:10:18:10 | a | provenance | | | main.rs:17:13:17:23 | get_data(...) | main.rs:17:9:17:9 | a | provenance | | -| main.rs:21:12:21:17 | ...: i64 | main.rs:22:10:22:10 | n | provenance | | -| main.rs:26:9:26:9 | a | main.rs:27:13:27:13 | a | provenance | | -| main.rs:26:13:26:21 | source(...) | main.rs:26:9:26:9 | a | provenance | | -| main.rs:27:13:27:13 | a | main.rs:21:12:21:17 | ...: i64 | provenance | | -| main.rs:30:17:30:22 | ...: i64 | main.rs:30:32:32:1 | { ... } | provenance | | -| main.rs:35:9:35:9 | a | main.rs:36:26:36:26 | a | provenance | | -| main.rs:35:13:35:21 | source(...) | main.rs:35:9:35:9 | a | provenance | | -| main.rs:36:9:36:9 | b | main.rs:37:10:37:10 | b | provenance | | -| main.rs:36:13:36:27 | pass_through(...) | main.rs:36:9:36:9 | b | provenance | | -| main.rs:36:26:36:26 | a | main.rs:30:17:30:22 | ...: i64 | provenance | | -| main.rs:36:26:36:26 | a | main.rs:36:13:36:27 | pass_through(...) | provenance | | -| main.rs:41:9:41:9 | a | main.rs:45:10:45:10 | a | provenance | | -| main.rs:41:13:44:6 | pass_through(...) | main.rs:41:9:41:9 | a | provenance | | -| main.rs:41:26:44:5 | { ... } | main.rs:30:17:30:22 | ...: i64 | provenance | | -| main.rs:41:26:44:5 | { ... } | main.rs:41:13:44:6 | pass_through(...) | provenance | | -| main.rs:43:9:43:18 | source(...) | main.rs:41:26:44:5 | { ... } | provenance | | -| main.rs:49:9:49:9 | a | main.rs:55:26:55:26 | a | provenance | | -| main.rs:49:13:49:22 | source(...) | main.rs:49:9:49:9 | a | provenance | | -| main.rs:51:21:51:26 | ...: i64 | main.rs:51:36:53:5 | { ... } | provenance | | -| main.rs:55:9:55:9 | b | main.rs:56:10:56:10 | b | provenance | | -| main.rs:55:13:55:27 | pass_through(...) | main.rs:55:9:55:9 | b | provenance | | -| main.rs:55:26:55:26 | a | main.rs:51:21:51:26 | ...: i64 | provenance | | -| main.rs:55:26:55:26 | a | main.rs:55:13:55:27 | pass_through(...) | provenance | | -| main.rs:67:22:67:27 | ...: i64 | main.rs:68:14:68:14 | n | provenance | | -| main.rs:71:30:77:5 | { ... } | main.rs:90:13:90:25 | mn.get_data(...) | provenance | | -| main.rs:75:13:75:21 | source(...) | main.rs:71:30:77:5 | { ... } | provenance | | -| main.rs:79:27:79:32 | ...: i64 | main.rs:79:42:85:5 | { ... } | provenance | | -| main.rs:90:9:90:9 | a | main.rs:91:10:91:10 | a | provenance | | -| main.rs:90:13:90:25 | mn.get_data(...) | main.rs:90:9:90:9 | a | provenance | | -| main.rs:96:9:96:9 | a | main.rs:97:16:97:16 | a | provenance | | -| main.rs:96:13:96:21 | source(...) | main.rs:96:9:96:9 | a | provenance | | -| main.rs:97:16:97:16 | a | main.rs:67:22:67:27 | ...: i64 | provenance | | -| main.rs:102:9:102:9 | a | main.rs:103:29:103:29 | a | provenance | | -| main.rs:102:13:102:21 | source(...) | main.rs:102:9:102:9 | a | provenance | | -| main.rs:103:9:103:9 | b | main.rs:104:10:104:10 | b | provenance | | -| main.rs:103:13:103:30 | mn.data_through(...) | main.rs:103:9:103:9 | b | provenance | | -| main.rs:103:29:103:29 | a | main.rs:79:27:79:32 | ...: i64 | provenance | | -| main.rs:103:29:103:29 | a | main.rs:103:13:103:30 | mn.data_through(...) | provenance | | -| main.rs:109:9:109:9 | a | main.rs:110:25:110:25 | a | provenance | | -| main.rs:109:13:109:21 | source(...) | main.rs:109:9:109:9 | a | provenance | | -| main.rs:110:25:110:25 | a | main.rs:67:22:67:27 | ...: i64 | provenance | | -| main.rs:115:9:115:9 | a | main.rs:116:38:116:38 | a | provenance | | -| main.rs:115:13:115:22 | source(...) | main.rs:115:9:115:9 | a | provenance | | -| main.rs:116:9:116:9 | b | main.rs:117:10:117:10 | b | provenance | | -| main.rs:116:13:116:39 | ...::data_through(...) | main.rs:116:9:116:9 | b | provenance | | -| main.rs:116:38:116:38 | a | main.rs:79:27:79:32 | ...: i64 | provenance | | -| main.rs:116:38:116:38 | a | main.rs:116:13:116:39 | ...::data_through(...) | provenance | | -| main.rs:128:12:128:17 | ...: i64 | main.rs:129:24:129:24 | n | provenance | | -| main.rs:129:9:129:26 | MyInt {...} [MyInt] | main.rs:128:28:130:5 | { ... } [MyInt] | provenance | | -| main.rs:129:24:129:24 | n | main.rs:129:9:129:26 | MyInt {...} [MyInt] | provenance | | -| main.rs:134:9:134:9 | n [MyInt] | main.rs:135:9:135:26 | MyInt {...} [MyInt] | provenance | | -| main.rs:134:13:134:34 | ...::new(...) [MyInt] | main.rs:134:9:134:9 | n [MyInt] | provenance | | -| main.rs:134:24:134:33 | source(...) | main.rs:128:12:128:17 | ...: i64 | provenance | | -| main.rs:134:24:134:33 | source(...) | main.rs:134:13:134:34 | ...::new(...) [MyInt] | provenance | | -| main.rs:135:9:135:26 | MyInt {...} [MyInt] | main.rs:135:24:135:24 | m | provenance | | -| main.rs:135:24:135:24 | m | main.rs:136:10:136:10 | m | provenance | | -| main.rs:142:12:142:15 | SelfParam [MyInt] | main.rs:144:24:144:27 | self [MyInt] | provenance | | -| main.rs:144:9:144:35 | MyInt {...} [MyInt] | main.rs:142:42:145:5 | { ... } [MyInt] | provenance | | -| main.rs:144:24:144:27 | self [MyInt] | main.rs:144:24:144:33 | self.value | provenance | | -| main.rs:144:24:144:33 | self.value | main.rs:144:9:144:35 | MyInt {...} [MyInt] | provenance | | -| main.rs:159:9:159:9 | a [MyInt] | main.rs:142:12:142:15 | SelfParam [MyInt] | provenance | | -| main.rs:159:9:159:9 | a [MyInt] | main.rs:161:13:161:20 | a.add(...) [MyInt] | provenance | | -| main.rs:159:13:159:38 | MyInt {...} [MyInt] | main.rs:159:9:159:9 | a [MyInt] | provenance | | -| main.rs:159:28:159:36 | source(...) | main.rs:159:13:159:38 | MyInt {...} [MyInt] | provenance | | -| main.rs:161:9:161:9 | d [MyInt] | main.rs:162:10:162:10 | d [MyInt] | provenance | | -| main.rs:161:13:161:20 | a.add(...) [MyInt] | main.rs:161:9:161:9 | d [MyInt] | provenance | | -| main.rs:162:10:162:10 | d [MyInt] | main.rs:162:10:162:16 | d.value | provenance | | -| main.rs:201:9:201:9 | a | main.rs:202:10:202:10 | a | provenance | | -| main.rs:201:13:201:21 | source(...) | main.rs:201:9:201:9 | a | provenance | | -| main.rs:211:13:211:13 | c | main.rs:212:14:212:14 | c | provenance | | -| main.rs:211:17:211:25 | source(...) | main.rs:211:13:211:13 | c | provenance | | +| main.rs:26:28:26:33 | ...: i64 | main.rs:27:24:27:24 | n | provenance | | +| main.rs:27:10:27:14 | [post] * ... [MyStruct] | main.rs:27:11:27:14 | [post] self [&ref, MyStruct] | provenance | | +| main.rs:27:11:27:14 | [post] self [&ref, MyStruct] | main.rs:26:17:26:25 | SelfParam [Return] [&ref, MyStruct] | provenance | | +| main.rs:27:24:27:24 | n | main.rs:27:10:27:14 | [post] * ... [MyStruct] | provenance | | +| main.rs:30:17:30:21 | SelfParam [&ref, MyStruct] | main.rs:31:11:31:14 | self [&ref, MyStruct] | provenance | | +| main.rs:31:9:31:20 | ... .data | main.rs:30:31:32:5 | { ... } | provenance | | +| main.rs:31:10:31:14 | * ... [MyStruct] | main.rs:31:9:31:20 | ... .data | provenance | | +| main.rs:31:11:31:14 | self [&ref, MyStruct] | main.rs:31:10:31:14 | * ... [MyStruct] | provenance | | +| main.rs:38:6:38:11 | [post] &mut a [&ref, MyStruct] | main.rs:38:11:38:11 | [post] a [MyStruct] | provenance | | +| main.rs:38:11:38:11 | [post] a [MyStruct] | main.rs:39:10:39:10 | a [MyStruct] | provenance | | +| main.rs:38:23:38:31 | source(...) | main.rs:26:28:26:33 | ...: i64 | provenance | | +| main.rs:38:23:38:31 | source(...) | main.rs:38:6:38:11 | [post] &mut a [&ref, MyStruct] | provenance | | +| main.rs:39:10:39:10 | a [MyStruct] | main.rs:30:17:30:21 | SelfParam [&ref, MyStruct] | provenance | | +| main.rs:39:10:39:10 | a [MyStruct] | main.rs:39:10:39:21 | a.get_data(...) | provenance | | +| main.rs:44:12:44:17 | [post] &mut a [&ref, MyStruct] | main.rs:44:17:44:17 | [post] a [MyStruct] | provenance | | +| main.rs:44:17:44:17 | [post] a [MyStruct] | main.rs:45:10:45:10 | a [MyStruct] | provenance | | +| main.rs:44:30:44:38 | source(...) | main.rs:26:28:26:33 | ...: i64 | provenance | | +| main.rs:44:30:44:38 | source(...) | main.rs:44:12:44:17 | [post] &mut a [&ref, MyStruct] | provenance | | +| main.rs:45:10:45:10 | a [MyStruct] | main.rs:30:17:30:21 | SelfParam [&ref, MyStruct] | provenance | | +| main.rs:45:10:45:10 | a [MyStruct] | main.rs:45:10:45:21 | a.get_data(...) | provenance | | +| main.rs:48:12:48:17 | ...: i64 | main.rs:49:10:49:10 | n | provenance | | +| main.rs:53:9:53:9 | a | main.rs:54:13:54:13 | a | provenance | | +| main.rs:53:13:53:21 | source(...) | main.rs:53:9:53:9 | a | provenance | | +| main.rs:54:13:54:13 | a | main.rs:48:12:48:17 | ...: i64 | provenance | | +| main.rs:57:17:57:22 | ...: i64 | main.rs:57:32:59:1 | { ... } | provenance | | +| main.rs:62:9:62:9 | a | main.rs:63:26:63:26 | a | provenance | | +| main.rs:62:13:62:21 | source(...) | main.rs:62:9:62:9 | a | provenance | | +| main.rs:63:9:63:9 | b | main.rs:64:10:64:10 | b | provenance | | +| main.rs:63:13:63:27 | pass_through(...) | main.rs:63:9:63:9 | b | provenance | | +| main.rs:63:26:63:26 | a | main.rs:57:17:57:22 | ...: i64 | provenance | | +| main.rs:63:26:63:26 | a | main.rs:63:13:63:27 | pass_through(...) | provenance | | +| main.rs:68:9:68:9 | a | main.rs:72:10:72:10 | a | provenance | | +| main.rs:68:13:71:6 | pass_through(...) | main.rs:68:9:68:9 | a | provenance | | +| main.rs:68:26:71:5 | { ... } | main.rs:57:17:57:22 | ...: i64 | provenance | | +| main.rs:68:26:71:5 | { ... } | main.rs:68:13:71:6 | pass_through(...) | provenance | | +| main.rs:70:9:70:18 | source(...) | main.rs:68:26:71:5 | { ... } | provenance | | +| main.rs:76:9:76:9 | a | main.rs:82:26:82:26 | a | provenance | | +| main.rs:76:13:76:22 | source(...) | main.rs:76:9:76:9 | a | provenance | | +| main.rs:78:21:78:26 | ...: i64 | main.rs:78:36:80:5 | { ... } | provenance | | +| main.rs:82:9:82:9 | b | main.rs:83:10:83:10 | b | provenance | | +| main.rs:82:13:82:27 | pass_through(...) | main.rs:82:9:82:9 | b | provenance | | +| main.rs:82:26:82:26 | a | main.rs:78:21:78:26 | ...: i64 | provenance | | +| main.rs:82:26:82:26 | a | main.rs:82:13:82:27 | pass_through(...) | provenance | | +| main.rs:94:22:94:27 | ...: i64 | main.rs:95:14:95:14 | n | provenance | | +| main.rs:98:30:104:5 | { ... } | main.rs:117:13:117:25 | mn.get_data(...) | provenance | | +| main.rs:102:13:102:21 | source(...) | main.rs:98:30:104:5 | { ... } | provenance | | +| main.rs:106:27:106:32 | ...: i64 | main.rs:106:42:112:5 | { ... } | provenance | | +| main.rs:117:9:117:9 | a | main.rs:118:10:118:10 | a | provenance | | +| main.rs:117:13:117:25 | mn.get_data(...) | main.rs:117:9:117:9 | a | provenance | | +| main.rs:123:9:123:9 | a | main.rs:124:16:124:16 | a | provenance | | +| main.rs:123:13:123:21 | source(...) | main.rs:123:9:123:9 | a | provenance | | +| main.rs:124:16:124:16 | a | main.rs:94:22:94:27 | ...: i64 | provenance | | +| main.rs:129:9:129:9 | a | main.rs:130:29:130:29 | a | provenance | | +| main.rs:129:13:129:21 | source(...) | main.rs:129:9:129:9 | a | provenance | | +| main.rs:130:9:130:9 | b | main.rs:131:10:131:10 | b | provenance | | +| main.rs:130:13:130:30 | mn.data_through(...) | main.rs:130:9:130:9 | b | provenance | | +| main.rs:130:29:130:29 | a | main.rs:106:27:106:32 | ...: i64 | provenance | | +| main.rs:130:29:130:29 | a | main.rs:130:13:130:30 | mn.data_through(...) | provenance | | +| main.rs:136:9:136:9 | a | main.rs:137:25:137:25 | a | provenance | | +| main.rs:136:13:136:21 | source(...) | main.rs:136:9:136:9 | a | provenance | | +| main.rs:137:25:137:25 | a | main.rs:94:22:94:27 | ...: i64 | provenance | | +| main.rs:142:9:142:9 | a | main.rs:143:38:143:38 | a | provenance | | +| main.rs:142:13:142:22 | source(...) | main.rs:142:9:142:9 | a | provenance | | +| main.rs:143:9:143:9 | b | main.rs:144:10:144:10 | b | provenance | | +| main.rs:143:13:143:39 | ...::data_through(...) | main.rs:143:9:143:9 | b | provenance | | +| main.rs:143:38:143:38 | a | main.rs:106:27:106:32 | ...: i64 | provenance | | +| main.rs:143:38:143:38 | a | main.rs:143:13:143:39 | ...::data_through(...) | provenance | | +| main.rs:155:12:155:17 | ...: i64 | main.rs:156:24:156:24 | n | provenance | | +| main.rs:156:9:156:26 | MyInt {...} [MyInt] | main.rs:155:28:157:5 | { ... } [MyInt] | provenance | | +| main.rs:156:24:156:24 | n | main.rs:156:9:156:26 | MyInt {...} [MyInt] | provenance | | +| main.rs:161:9:161:9 | n [MyInt] | main.rs:162:9:162:26 | MyInt {...} [MyInt] | provenance | | +| main.rs:161:13:161:34 | ...::new(...) [MyInt] | main.rs:161:9:161:9 | n [MyInt] | provenance | | +| main.rs:161:24:161:33 | source(...) | main.rs:155:12:155:17 | ...: i64 | provenance | | +| main.rs:161:24:161:33 | source(...) | main.rs:161:13:161:34 | ...::new(...) [MyInt] | provenance | | +| main.rs:162:9:162:26 | MyInt {...} [MyInt] | main.rs:162:24:162:24 | m | provenance | | +| main.rs:162:24:162:24 | m | main.rs:163:10:163:10 | m | provenance | | +| main.rs:169:12:169:15 | SelfParam [MyInt] | main.rs:171:24:171:27 | self [MyInt] | provenance | | +| main.rs:171:9:171:35 | MyInt {...} [MyInt] | main.rs:169:42:172:5 | { ... } [MyInt] | provenance | | +| main.rs:171:24:171:27 | self [MyInt] | main.rs:171:24:171:33 | self.value | provenance | | +| main.rs:171:24:171:33 | self.value | main.rs:171:9:171:35 | MyInt {...} [MyInt] | provenance | | +| main.rs:186:9:186:9 | a [MyInt] | main.rs:169:12:169:15 | SelfParam [MyInt] | provenance | | +| main.rs:186:9:186:9 | a [MyInt] | main.rs:188:13:188:20 | a.add(...) [MyInt] | provenance | | +| main.rs:186:13:186:38 | MyInt {...} [MyInt] | main.rs:186:9:186:9 | a [MyInt] | provenance | | +| main.rs:186:28:186:36 | source(...) | main.rs:186:13:186:38 | MyInt {...} [MyInt] | provenance | | +| main.rs:188:9:188:9 | d [MyInt] | main.rs:189:10:189:10 | d [MyInt] | provenance | | +| main.rs:188:13:188:20 | a.add(...) [MyInt] | main.rs:188:9:188:9 | d [MyInt] | provenance | | +| main.rs:189:10:189:10 | d [MyInt] | main.rs:189:10:189:16 | d.value | provenance | | +| main.rs:228:9:228:9 | a | main.rs:229:10:229:10 | a | provenance | | +| main.rs:228:13:228:21 | source(...) | main.rs:228:9:228:9 | a | provenance | | +| main.rs:238:13:238:13 | c | main.rs:239:14:239:14 | c | provenance | | +| main.rs:238:17:238:25 | source(...) | main.rs:238:13:238:13 | c | provenance | | nodes | main.rs:12:28:14:1 | { ... } | semmle.label | { ... } | | main.rs:13:5:13:13 | source(...) | semmle.label | source(...) | | main.rs:17:9:17:9 | a | semmle.label | a | | main.rs:17:13:17:23 | get_data(...) | semmle.label | get_data(...) | | main.rs:18:10:18:10 | a | semmle.label | a | -| main.rs:21:12:21:17 | ...: i64 | semmle.label | ...: i64 | -| main.rs:22:10:22:10 | n | semmle.label | n | -| main.rs:26:9:26:9 | a | semmle.label | a | -| main.rs:26:13:26:21 | source(...) | semmle.label | source(...) | -| main.rs:27:13:27:13 | a | semmle.label | a | -| main.rs:30:17:30:22 | ...: i64 | semmle.label | ...: i64 | -| main.rs:30:32:32:1 | { ... } | semmle.label | { ... } | -| main.rs:35:9:35:9 | a | semmle.label | a | -| main.rs:35:13:35:21 | source(...) | semmle.label | source(...) | -| main.rs:36:9:36:9 | b | semmle.label | b | -| main.rs:36:13:36:27 | pass_through(...) | semmle.label | pass_through(...) | -| main.rs:36:26:36:26 | a | semmle.label | a | -| main.rs:37:10:37:10 | b | semmle.label | b | -| main.rs:41:9:41:9 | a | semmle.label | a | -| main.rs:41:13:44:6 | pass_through(...) | semmle.label | pass_through(...) | -| main.rs:41:26:44:5 | { ... } | semmle.label | { ... } | -| main.rs:43:9:43:18 | source(...) | semmle.label | source(...) | -| main.rs:45:10:45:10 | a | semmle.label | a | -| main.rs:49:9:49:9 | a | semmle.label | a | -| main.rs:49:13:49:22 | source(...) | semmle.label | source(...) | -| main.rs:51:21:51:26 | ...: i64 | semmle.label | ...: i64 | -| main.rs:51:36:53:5 | { ... } | semmle.label | { ... } | -| main.rs:55:9:55:9 | b | semmle.label | b | -| main.rs:55:13:55:27 | pass_through(...) | semmle.label | pass_through(...) | -| main.rs:55:26:55:26 | a | semmle.label | a | -| main.rs:56:10:56:10 | b | semmle.label | b | -| main.rs:67:22:67:27 | ...: i64 | semmle.label | ...: i64 | -| main.rs:68:14:68:14 | n | semmle.label | n | -| main.rs:71:30:77:5 | { ... } | semmle.label | { ... } | -| main.rs:75:13:75:21 | source(...) | semmle.label | source(...) | -| main.rs:79:27:79:32 | ...: i64 | semmle.label | ...: i64 | -| main.rs:79:42:85:5 | { ... } | semmle.label | { ... } | -| main.rs:90:9:90:9 | a | semmle.label | a | -| main.rs:90:13:90:25 | mn.get_data(...) | semmle.label | mn.get_data(...) | -| main.rs:91:10:91:10 | a | semmle.label | a | -| main.rs:96:9:96:9 | a | semmle.label | a | -| main.rs:96:13:96:21 | source(...) | semmle.label | source(...) | -| main.rs:97:16:97:16 | a | semmle.label | a | -| main.rs:102:9:102:9 | a | semmle.label | a | +| main.rs:26:17:26:25 | SelfParam [Return] [&ref, MyStruct] | semmle.label | SelfParam [Return] [&ref, MyStruct] | +| main.rs:26:28:26:33 | ...: i64 | semmle.label | ...: i64 | +| main.rs:27:10:27:14 | [post] * ... [MyStruct] | semmle.label | [post] * ... [MyStruct] | +| main.rs:27:11:27:14 | [post] self [&ref, MyStruct] | semmle.label | [post] self [&ref, MyStruct] | +| main.rs:27:24:27:24 | n | semmle.label | n | +| main.rs:30:17:30:21 | SelfParam [&ref, MyStruct] | semmle.label | SelfParam [&ref, MyStruct] | +| main.rs:30:31:32:5 | { ... } | semmle.label | { ... } | +| main.rs:31:9:31:20 | ... .data | semmle.label | ... .data | +| main.rs:31:10:31:14 | * ... [MyStruct] | semmle.label | * ... [MyStruct] | +| main.rs:31:11:31:14 | self [&ref, MyStruct] | semmle.label | self [&ref, MyStruct] | +| main.rs:38:6:38:11 | [post] &mut a [&ref, MyStruct] | semmle.label | [post] &mut a [&ref, MyStruct] | +| main.rs:38:11:38:11 | [post] a [MyStruct] | semmle.label | [post] a [MyStruct] | +| main.rs:38:23:38:31 | source(...) | semmle.label | source(...) | +| main.rs:39:10:39:10 | a [MyStruct] | semmle.label | a [MyStruct] | +| main.rs:39:10:39:21 | a.get_data(...) | semmle.label | a.get_data(...) | +| main.rs:44:12:44:17 | [post] &mut a [&ref, MyStruct] | semmle.label | [post] &mut a [&ref, MyStruct] | +| main.rs:44:17:44:17 | [post] a [MyStruct] | semmle.label | [post] a [MyStruct] | +| main.rs:44:30:44:38 | source(...) | semmle.label | source(...) | +| main.rs:45:10:45:10 | a [MyStruct] | semmle.label | a [MyStruct] | +| main.rs:45:10:45:21 | a.get_data(...) | semmle.label | a.get_data(...) | +| main.rs:48:12:48:17 | ...: i64 | semmle.label | ...: i64 | +| main.rs:49:10:49:10 | n | semmle.label | n | +| main.rs:53:9:53:9 | a | semmle.label | a | +| main.rs:53:13:53:21 | source(...) | semmle.label | source(...) | +| main.rs:54:13:54:13 | a | semmle.label | a | +| main.rs:57:17:57:22 | ...: i64 | semmle.label | ...: i64 | +| main.rs:57:32:59:1 | { ... } | semmle.label | { ... } | +| main.rs:62:9:62:9 | a | semmle.label | a | +| main.rs:62:13:62:21 | source(...) | semmle.label | source(...) | +| main.rs:63:9:63:9 | b | semmle.label | b | +| main.rs:63:13:63:27 | pass_through(...) | semmle.label | pass_through(...) | +| main.rs:63:26:63:26 | a | semmle.label | a | +| main.rs:64:10:64:10 | b | semmle.label | b | +| main.rs:68:9:68:9 | a | semmle.label | a | +| main.rs:68:13:71:6 | pass_through(...) | semmle.label | pass_through(...) | +| main.rs:68:26:71:5 | { ... } | semmle.label | { ... } | +| main.rs:70:9:70:18 | source(...) | semmle.label | source(...) | +| main.rs:72:10:72:10 | a | semmle.label | a | +| main.rs:76:9:76:9 | a | semmle.label | a | +| main.rs:76:13:76:22 | source(...) | semmle.label | source(...) | +| main.rs:78:21:78:26 | ...: i64 | semmle.label | ...: i64 | +| main.rs:78:36:80:5 | { ... } | semmle.label | { ... } | +| main.rs:82:9:82:9 | b | semmle.label | b | +| main.rs:82:13:82:27 | pass_through(...) | semmle.label | pass_through(...) | +| main.rs:82:26:82:26 | a | semmle.label | a | +| main.rs:83:10:83:10 | b | semmle.label | b | +| main.rs:94:22:94:27 | ...: i64 | semmle.label | ...: i64 | +| main.rs:95:14:95:14 | n | semmle.label | n | +| main.rs:98:30:104:5 | { ... } | semmle.label | { ... } | | main.rs:102:13:102:21 | source(...) | semmle.label | source(...) | -| main.rs:103:9:103:9 | b | semmle.label | b | -| main.rs:103:13:103:30 | mn.data_through(...) | semmle.label | mn.data_through(...) | -| main.rs:103:29:103:29 | a | semmle.label | a | -| main.rs:104:10:104:10 | b | semmle.label | b | -| main.rs:109:9:109:9 | a | semmle.label | a | -| main.rs:109:13:109:21 | source(...) | semmle.label | source(...) | -| main.rs:110:25:110:25 | a | semmle.label | a | -| main.rs:115:9:115:9 | a | semmle.label | a | -| main.rs:115:13:115:22 | source(...) | semmle.label | source(...) | -| main.rs:116:9:116:9 | b | semmle.label | b | -| main.rs:116:13:116:39 | ...::data_through(...) | semmle.label | ...::data_through(...) | -| main.rs:116:38:116:38 | a | semmle.label | a | -| main.rs:117:10:117:10 | b | semmle.label | b | -| main.rs:128:12:128:17 | ...: i64 | semmle.label | ...: i64 | -| main.rs:128:28:130:5 | { ... } [MyInt] | semmle.label | { ... } [MyInt] | -| main.rs:129:9:129:26 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] | -| main.rs:129:24:129:24 | n | semmle.label | n | -| main.rs:134:9:134:9 | n [MyInt] | semmle.label | n [MyInt] | -| main.rs:134:13:134:34 | ...::new(...) [MyInt] | semmle.label | ...::new(...) [MyInt] | -| main.rs:134:24:134:33 | source(...) | semmle.label | source(...) | -| main.rs:135:9:135:26 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] | -| main.rs:135:24:135:24 | m | semmle.label | m | -| main.rs:136:10:136:10 | m | semmle.label | m | -| main.rs:142:12:142:15 | SelfParam [MyInt] | semmle.label | SelfParam [MyInt] | -| main.rs:142:42:145:5 | { ... } [MyInt] | semmle.label | { ... } [MyInt] | -| main.rs:144:9:144:35 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] | -| main.rs:144:24:144:27 | self [MyInt] | semmle.label | self [MyInt] | -| main.rs:144:24:144:33 | self.value | semmle.label | self.value | -| main.rs:159:9:159:9 | a [MyInt] | semmle.label | a [MyInt] | -| main.rs:159:13:159:38 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] | -| main.rs:159:28:159:36 | source(...) | semmle.label | source(...) | -| main.rs:161:9:161:9 | d [MyInt] | semmle.label | d [MyInt] | -| main.rs:161:13:161:20 | a.add(...) [MyInt] | semmle.label | a.add(...) [MyInt] | -| main.rs:162:10:162:10 | d [MyInt] | semmle.label | d [MyInt] | -| main.rs:162:10:162:16 | d.value | semmle.label | d.value | -| main.rs:201:9:201:9 | a | semmle.label | a | -| main.rs:201:13:201:21 | source(...) | semmle.label | source(...) | -| main.rs:202:10:202:10 | a | semmle.label | a | -| main.rs:211:13:211:13 | c | semmle.label | c | -| main.rs:211:17:211:25 | source(...) | semmle.label | source(...) | -| main.rs:212:14:212:14 | c | semmle.label | c | +| main.rs:106:27:106:32 | ...: i64 | semmle.label | ...: i64 | +| main.rs:106:42:112:5 | { ... } | semmle.label | { ... } | +| main.rs:117:9:117:9 | a | semmle.label | a | +| main.rs:117:13:117:25 | mn.get_data(...) | semmle.label | mn.get_data(...) | +| main.rs:118:10:118:10 | a | semmle.label | a | +| main.rs:123:9:123:9 | a | semmle.label | a | +| main.rs:123:13:123:21 | source(...) | semmle.label | source(...) | +| main.rs:124:16:124:16 | a | semmle.label | a | +| main.rs:129:9:129:9 | a | semmle.label | a | +| main.rs:129:13:129:21 | source(...) | semmle.label | source(...) | +| main.rs:130:9:130:9 | b | semmle.label | b | +| main.rs:130:13:130:30 | mn.data_through(...) | semmle.label | mn.data_through(...) | +| main.rs:130:29:130:29 | a | semmle.label | a | +| main.rs:131:10:131:10 | b | semmle.label | b | +| main.rs:136:9:136:9 | a | semmle.label | a | +| main.rs:136:13:136:21 | source(...) | semmle.label | source(...) | +| main.rs:137:25:137:25 | a | semmle.label | a | +| main.rs:142:9:142:9 | a | semmle.label | a | +| main.rs:142:13:142:22 | source(...) | semmle.label | source(...) | +| main.rs:143:9:143:9 | b | semmle.label | b | +| main.rs:143:13:143:39 | ...::data_through(...) | semmle.label | ...::data_through(...) | +| main.rs:143:38:143:38 | a | semmle.label | a | +| main.rs:144:10:144:10 | b | semmle.label | b | +| main.rs:155:12:155:17 | ...: i64 | semmle.label | ...: i64 | +| main.rs:155:28:157:5 | { ... } [MyInt] | semmle.label | { ... } [MyInt] | +| main.rs:156:9:156:26 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] | +| main.rs:156:24:156:24 | n | semmle.label | n | +| main.rs:161:9:161:9 | n [MyInt] | semmle.label | n [MyInt] | +| main.rs:161:13:161:34 | ...::new(...) [MyInt] | semmle.label | ...::new(...) [MyInt] | +| main.rs:161:24:161:33 | source(...) | semmle.label | source(...) | +| main.rs:162:9:162:26 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] | +| main.rs:162:24:162:24 | m | semmle.label | m | +| main.rs:163:10:163:10 | m | semmle.label | m | +| main.rs:169:12:169:15 | SelfParam [MyInt] | semmle.label | SelfParam [MyInt] | +| main.rs:169:42:172:5 | { ... } [MyInt] | semmle.label | { ... } [MyInt] | +| main.rs:171:9:171:35 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] | +| main.rs:171:24:171:27 | self [MyInt] | semmle.label | self [MyInt] | +| main.rs:171:24:171:33 | self.value | semmle.label | self.value | +| main.rs:186:9:186:9 | a [MyInt] | semmle.label | a [MyInt] | +| main.rs:186:13:186:38 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] | +| main.rs:186:28:186:36 | source(...) | semmle.label | source(...) | +| main.rs:188:9:188:9 | d [MyInt] | semmle.label | d [MyInt] | +| main.rs:188:13:188:20 | a.add(...) [MyInt] | semmle.label | a.add(...) [MyInt] | +| main.rs:189:10:189:10 | d [MyInt] | semmle.label | d [MyInt] | +| main.rs:189:10:189:16 | d.value | semmle.label | d.value | +| main.rs:228:9:228:9 | a | semmle.label | a | +| main.rs:228:13:228:21 | source(...) | semmle.label | source(...) | +| main.rs:229:10:229:10 | a | semmle.label | a | +| main.rs:238:13:238:13 | c | semmle.label | c | +| main.rs:238:17:238:25 | source(...) | semmle.label | source(...) | +| main.rs:239:14:239:14 | c | semmle.label | c | subpaths -| main.rs:36:26:36:26 | a | main.rs:30:17:30:22 | ...: i64 | main.rs:30:32:32:1 | { ... } | main.rs:36:13:36:27 | pass_through(...) | -| main.rs:41:26:44:5 | { ... } | main.rs:30:17:30:22 | ...: i64 | main.rs:30:32:32:1 | { ... } | main.rs:41:13:44:6 | pass_through(...) | -| main.rs:55:26:55:26 | a | main.rs:51:21:51:26 | ...: i64 | main.rs:51:36:53:5 | { ... } | main.rs:55:13:55:27 | pass_through(...) | -| main.rs:103:29:103:29 | a | main.rs:79:27:79:32 | ...: i64 | main.rs:79:42:85:5 | { ... } | main.rs:103:13:103:30 | mn.data_through(...) | -| main.rs:116:38:116:38 | a | main.rs:79:27:79:32 | ...: i64 | main.rs:79:42:85:5 | { ... } | main.rs:116:13:116:39 | ...::data_through(...) | -| main.rs:134:24:134:33 | source(...) | main.rs:128:12:128:17 | ...: i64 | main.rs:128:28:130:5 | { ... } [MyInt] | main.rs:134:13:134:34 | ...::new(...) [MyInt] | -| main.rs:159:9:159:9 | a [MyInt] | main.rs:142:12:142:15 | SelfParam [MyInt] | main.rs:142:42:145:5 | { ... } [MyInt] | main.rs:161:13:161:20 | a.add(...) [MyInt] | +| main.rs:38:23:38:31 | source(...) | main.rs:26:28:26:33 | ...: i64 | main.rs:26:17:26:25 | SelfParam [Return] [&ref, MyStruct] | main.rs:38:6:38:11 | [post] &mut a [&ref, MyStruct] | +| main.rs:39:10:39:10 | a [MyStruct] | main.rs:30:17:30:21 | SelfParam [&ref, MyStruct] | main.rs:30:31:32:5 | { ... } | main.rs:39:10:39:21 | a.get_data(...) | +| main.rs:44:30:44:38 | source(...) | main.rs:26:28:26:33 | ...: i64 | main.rs:26:17:26:25 | SelfParam [Return] [&ref, MyStruct] | main.rs:44:12:44:17 | [post] &mut a [&ref, MyStruct] | +| main.rs:45:10:45:10 | a [MyStruct] | main.rs:30:17:30:21 | SelfParam [&ref, MyStruct] | main.rs:30:31:32:5 | { ... } | main.rs:45:10:45:21 | a.get_data(...) | +| main.rs:63:26:63:26 | a | main.rs:57:17:57:22 | ...: i64 | main.rs:57:32:59:1 | { ... } | main.rs:63:13:63:27 | pass_through(...) | +| main.rs:68:26:71:5 | { ... } | main.rs:57:17:57:22 | ...: i64 | main.rs:57:32:59:1 | { ... } | main.rs:68:13:71:6 | pass_through(...) | +| main.rs:82:26:82:26 | a | main.rs:78:21:78:26 | ...: i64 | main.rs:78:36:80:5 | { ... } | main.rs:82:13:82:27 | pass_through(...) | +| main.rs:130:29:130:29 | a | main.rs:106:27:106:32 | ...: i64 | main.rs:106:42:112:5 | { ... } | main.rs:130:13:130:30 | mn.data_through(...) | +| main.rs:143:38:143:38 | a | main.rs:106:27:106:32 | ...: i64 | main.rs:106:42:112:5 | { ... } | main.rs:143:13:143:39 | ...::data_through(...) | +| main.rs:161:24:161:33 | source(...) | main.rs:155:12:155:17 | ...: i64 | main.rs:155:28:157:5 | { ... } [MyInt] | main.rs:161:13:161:34 | ...::new(...) [MyInt] | +| main.rs:186:9:186:9 | a [MyInt] | main.rs:169:12:169:15 | SelfParam [MyInt] | main.rs:169:42:172:5 | { ... } [MyInt] | main.rs:188:13:188:20 | a.add(...) [MyInt] | testFailures #select | main.rs:18:10:18:10 | a | main.rs:13:5:13:13 | source(...) | main.rs:18:10:18:10 | a | $@ | main.rs:13:5:13:13 | source(...) | source(...) | -| main.rs:22:10:22:10 | n | main.rs:26:13:26:21 | source(...) | main.rs:22:10:22:10 | n | $@ | main.rs:26:13:26:21 | source(...) | source(...) | -| main.rs:37:10:37:10 | b | main.rs:35:13:35:21 | source(...) | main.rs:37:10:37:10 | b | $@ | main.rs:35:13:35:21 | source(...) | source(...) | -| main.rs:45:10:45:10 | a | main.rs:43:9:43:18 | source(...) | main.rs:45:10:45:10 | a | $@ | main.rs:43:9:43:18 | source(...) | source(...) | -| main.rs:56:10:56:10 | b | main.rs:49:13:49:22 | source(...) | main.rs:56:10:56:10 | b | $@ | main.rs:49:13:49:22 | source(...) | source(...) | -| main.rs:68:14:68:14 | n | main.rs:96:13:96:21 | source(...) | main.rs:68:14:68:14 | n | $@ | main.rs:96:13:96:21 | source(...) | source(...) | -| main.rs:68:14:68:14 | n | main.rs:109:13:109:21 | source(...) | main.rs:68:14:68:14 | n | $@ | main.rs:109:13:109:21 | source(...) | source(...) | -| main.rs:91:10:91:10 | a | main.rs:75:13:75:21 | source(...) | main.rs:91:10:91:10 | a | $@ | main.rs:75:13:75:21 | source(...) | source(...) | -| main.rs:104:10:104:10 | b | main.rs:102:13:102:21 | source(...) | main.rs:104:10:104:10 | b | $@ | main.rs:102:13:102:21 | source(...) | source(...) | -| main.rs:117:10:117:10 | b | main.rs:115:13:115:22 | source(...) | main.rs:117:10:117:10 | b | $@ | main.rs:115:13:115:22 | source(...) | source(...) | -| main.rs:136:10:136:10 | m | main.rs:134:24:134:33 | source(...) | main.rs:136:10:136:10 | m | $@ | main.rs:134:24:134:33 | source(...) | source(...) | -| main.rs:162:10:162:16 | d.value | main.rs:159:28:159:36 | source(...) | main.rs:162:10:162:16 | d.value | $@ | main.rs:159:28:159:36 | source(...) | source(...) | -| main.rs:202:10:202:10 | a | main.rs:201:13:201:21 | source(...) | main.rs:202:10:202:10 | a | $@ | main.rs:201:13:201:21 | source(...) | source(...) | -| main.rs:212:14:212:14 | c | main.rs:211:17:211:25 | source(...) | main.rs:212:14:212:14 | c | $@ | main.rs:211:17:211:25 | source(...) | source(...) | +| main.rs:39:10:39:21 | a.get_data(...) | main.rs:38:23:38:31 | source(...) | main.rs:39:10:39:21 | a.get_data(...) | $@ | main.rs:38:23:38:31 | source(...) | source(...) | +| main.rs:45:10:45:21 | a.get_data(...) | main.rs:44:30:44:38 | source(...) | main.rs:45:10:45:21 | a.get_data(...) | $@ | main.rs:44:30:44:38 | source(...) | source(...) | +| main.rs:49:10:49:10 | n | main.rs:53:13:53:21 | source(...) | main.rs:49:10:49:10 | n | $@ | main.rs:53:13:53:21 | source(...) | source(...) | +| main.rs:64:10:64:10 | b | main.rs:62:13:62:21 | source(...) | main.rs:64:10:64:10 | b | $@ | main.rs:62:13:62:21 | source(...) | source(...) | +| main.rs:72:10:72:10 | a | main.rs:70:9:70:18 | source(...) | main.rs:72:10:72:10 | a | $@ | main.rs:70:9:70:18 | source(...) | source(...) | +| main.rs:83:10:83:10 | b | main.rs:76:13:76:22 | source(...) | main.rs:83:10:83:10 | b | $@ | main.rs:76:13:76:22 | source(...) | source(...) | +| main.rs:95:14:95:14 | n | main.rs:123:13:123:21 | source(...) | main.rs:95:14:95:14 | n | $@ | main.rs:123:13:123:21 | source(...) | source(...) | +| main.rs:95:14:95:14 | n | main.rs:136:13:136:21 | source(...) | main.rs:95:14:95:14 | n | $@ | main.rs:136:13:136:21 | source(...) | source(...) | +| main.rs:118:10:118:10 | a | main.rs:102:13:102:21 | source(...) | main.rs:118:10:118:10 | a | $@ | main.rs:102:13:102:21 | source(...) | source(...) | +| main.rs:131:10:131:10 | b | main.rs:129:13:129:21 | source(...) | main.rs:131:10:131:10 | b | $@ | main.rs:129:13:129:21 | source(...) | source(...) | +| main.rs:144:10:144:10 | b | main.rs:142:13:142:22 | source(...) | main.rs:144:10:144:10 | b | $@ | main.rs:142:13:142:22 | source(...) | source(...) | +| main.rs:163:10:163:10 | m | main.rs:161:24:161:33 | source(...) | main.rs:163:10:163:10 | m | $@ | main.rs:161:24:161:33 | source(...) | source(...) | +| main.rs:189:10:189:16 | d.value | main.rs:186:28:186:36 | source(...) | main.rs:189:10:189:16 | d.value | $@ | main.rs:186:28:186:36 | source(...) | source(...) | +| main.rs:229:10:229:10 | a | main.rs:228:13:228:21 | source(...) | main.rs:229:10:229:10 | a | $@ | main.rs:228:13:228:21 | source(...) | source(...) | +| main.rs:239:14:239:14 | c | main.rs:238:17:238:25 | source(...) | main.rs:239:14:239:14 | c | $@ | main.rs:238:17:238:25 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/global/main.rs b/rust/ql/test/library-tests/dataflow/global/main.rs index c1e3ee4e8387..f2d1b3dd7770 100644 --- a/rust/ql/test/library-tests/dataflow/global/main.rs +++ b/rust/ql/test/library-tests/dataflow/global/main.rs @@ -18,6 +18,33 @@ fn data_out_of_call() { sink(a); // $ hasValueFlow=n } +struct MyStruct { + data: i64, +} + +impl MyStruct { + fn set_data(&mut self, n: i64) { + (*self).data = n // todo: implicit deref not yet supported + } + + fn get_data(&self) -> i64 { + (*self).data // todo: implicit deref not yet supported + } +} + +fn data_out_of_call_side_effect1() { + let mut a = MyStruct { data: 0 }; + sink(a.get_data()); + (&mut a).set_data(source(8)); + sink(a.get_data()); // $ hasValueFlow=8 +} + +fn data_out_of_call_side_effect2() { + let mut a = MyStruct { data: 0 }; + ({ 42; &mut a}).set_data(source(9)); + sink(a.get_data()); // $ hasValueFlow=9 +} + fn data_in(n: i64) { sink(n); // $ hasValueFlow=3 } @@ -224,6 +251,8 @@ fn test_async_await() { fn main() { data_out_of_call(); + data_out_of_call_side_effect1(); + data_out_of_call_side_effect2(); data_in_to_call(); data_through_call(); data_through_nested_function(); diff --git a/rust/ql/test/library-tests/dataflow/global/viableCallable.expected b/rust/ql/test/library-tests/dataflow/global/viableCallable.expected index 2bbff8e33c3f..c861feaa0177 100644 --- a/rust/ql/test/library-tests/dataflow/global/viableCallable.expected +++ b/rust/ql/test/library-tests/dataflow/global/viableCallable.expected @@ -1,64 +1,76 @@ | main.rs:13:5:13:13 | source(...) | main.rs:1:1:3:1 | fn source | | main.rs:17:13:17:23 | get_data(...) | main.rs:12:1:14:1 | fn get_data | | main.rs:18:5:18:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:22:5:22:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:26:13:26:21 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:27:5:27:14 | data_in(...) | main.rs:21:1:23:1 | fn data_in | -| main.rs:35:13:35:21 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:36:13:36:27 | pass_through(...) | main.rs:30:1:32:1 | fn pass_through | -| main.rs:37:5:37:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:41:13:44:6 | pass_through(...) | main.rs:30:1:32:1 | fn pass_through | -| main.rs:43:9:43:18 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:45:5:45:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:49:13:49:22 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:55:13:55:27 | pass_through(...) | main.rs:51:5:53:5 | fn pass_through | -| main.rs:56:5:56:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:68:9:68:15 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:75:13:75:21 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:90:13:90:25 | mn.get_data(...) | main.rs:71:5:77:5 | fn get_data | -| main.rs:91:5:91:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:96:13:96:21 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:97:5:97:17 | mn.data_in(...) | main.rs:67:5:69:5 | fn data_in | +| main.rs:37:5:37:22 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:37:10:37:21 | a.get_data(...) | main.rs:30:5:32:5 | fn get_data | +| main.rs:38:5:38:32 | ... .set_data(...) | main.rs:26:5:28:5 | fn set_data | +| main.rs:38:23:38:31 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:39:5:39:22 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:39:10:39:21 | a.get_data(...) | main.rs:30:5:32:5 | fn get_data | +| main.rs:44:5:44:39 | ... .set_data(...) | main.rs:26:5:28:5 | fn set_data | +| main.rs:44:30:44:38 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:45:5:45:22 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:45:10:45:21 | a.get_data(...) | main.rs:30:5:32:5 | fn get_data | +| main.rs:49:5:49:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:53:13:53:21 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:54:5:54:14 | data_in(...) | main.rs:48:1:50:1 | fn data_in | +| main.rs:62:13:62:21 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:63:13:63:27 | pass_through(...) | main.rs:57:1:59:1 | fn pass_through | +| main.rs:64:5:64:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:68:13:71:6 | pass_through(...) | main.rs:57:1:59:1 | fn pass_through | +| main.rs:70:9:70:18 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:72:5:72:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:76:13:76:22 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:82:13:82:27 | pass_through(...) | main.rs:78:5:80:5 | fn pass_through | +| main.rs:83:5:83:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:95:9:95:15 | sink(...) | main.rs:5:1:7:1 | fn sink | | main.rs:102:13:102:21 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:103:13:103:30 | mn.data_through(...) | main.rs:79:5:85:5 | fn data_through | -| main.rs:104:5:104:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:109:13:109:21 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:110:5:110:26 | ...::data_in(...) | main.rs:67:5:69:5 | fn data_in | -| main.rs:115:13:115:22 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:116:13:116:39 | ...::data_through(...) | main.rs:79:5:85:5 | fn data_through | -| main.rs:117:5:117:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:134:13:134:34 | ...::new(...) | main.rs:127:5:130:5 | fn new | -| main.rs:134:24:134:33 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:136:5:136:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:149:28:149:36 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:152:5:152:17 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:155:28:155:36 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:157:5:157:17 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:159:28:159:36 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:161:13:161:20 | a.add(...) | main.rs:142:5:145:5 | fn add | -| main.rs:162:5:162:17 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:184:28:184:36 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:187:5:187:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:190:28:190:37 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:192:5:192:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:195:28:195:37 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:197:5:197:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:201:13:201:21 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:202:5:202:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:207:13:207:26 | async_source(...) | main.rs:200:1:204:1 | fn async_source | -| main.rs:208:5:208:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:211:17:211:25 | source(...) | main.rs:1:1:3:1 | fn source | -| main.rs:212:9:212:15 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:215:5:215:17 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:219:41:219:54 | async_source(...) | main.rs:200:1:204:1 | fn async_source | -| main.rs:220:5:220:11 | sink(...) | main.rs:5:1:7:1 | fn sink | -| main.rs:222:33:222:61 | test_async_await_async_part(...) | main.rs:206:1:216:1 | fn test_async_await_async_part | -| main.rs:226:5:226:22 | data_out_of_call(...) | main.rs:16:1:19:1 | fn data_out_of_call | -| main.rs:227:5:227:21 | data_in_to_call(...) | main.rs:25:1:28:1 | fn data_in_to_call | -| main.rs:228:5:228:23 | data_through_call(...) | main.rs:34:1:38:1 | fn data_through_call | -| main.rs:229:5:229:34 | data_through_nested_function(...) | main.rs:48:1:57:1 | fn data_through_nested_function | -| main.rs:231:5:231:24 | data_out_of_method(...) | main.rs:88:1:92:1 | fn data_out_of_method | -| main.rs:232:5:232:28 | data_in_to_method_call(...) | main.rs:94:1:98:1 | fn data_in_to_method_call | -| main.rs:233:5:233:25 | data_through_method(...) | main.rs:100:1:105:1 | fn data_through_method | -| main.rs:235:5:235:31 | test_operator_overloading(...) | main.rs:148:1:163:1 | fn test_operator_overloading | -| main.rs:236:5:236:22 | test_async_await(...) | main.rs:218:1:223:1 | fn test_async_await | +| main.rs:117:13:117:25 | mn.get_data(...) | main.rs:98:5:104:5 | fn get_data | +| main.rs:118:5:118:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:123:13:123:21 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:124:5:124:17 | mn.data_in(...) | main.rs:94:5:96:5 | fn data_in | +| main.rs:129:13:129:21 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:130:13:130:30 | mn.data_through(...) | main.rs:106:5:112:5 | fn data_through | +| main.rs:131:5:131:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:136:13:136:21 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:137:5:137:26 | ...::data_in(...) | main.rs:94:5:96:5 | fn data_in | +| main.rs:142:13:142:22 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:143:13:143:39 | ...::data_through(...) | main.rs:106:5:112:5 | fn data_through | +| main.rs:144:5:144:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:161:13:161:34 | ...::new(...) | main.rs:154:5:157:5 | fn new | +| main.rs:161:24:161:33 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:163:5:163:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:176:28:176:36 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:179:5:179:17 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:182:28:182:36 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:184:5:184:17 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:186:28:186:36 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:188:13:188:20 | a.add(...) | main.rs:169:5:172:5 | fn add | +| main.rs:189:5:189:17 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:211:28:211:36 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:214:5:214:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:217:28:217:37 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:219:5:219:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:222:28:222:37 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:224:5:224:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:228:13:228:21 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:229:5:229:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:234:13:234:26 | async_source(...) | main.rs:227:1:231:1 | fn async_source | +| main.rs:235:5:235:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:238:17:238:25 | source(...) | main.rs:1:1:3:1 | fn source | +| main.rs:239:9:239:15 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:242:5:242:17 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:246:41:246:54 | async_source(...) | main.rs:227:1:231:1 | fn async_source | +| main.rs:247:5:247:11 | sink(...) | main.rs:5:1:7:1 | fn sink | +| main.rs:249:33:249:61 | test_async_await_async_part(...) | main.rs:233:1:243:1 | fn test_async_await_async_part | +| main.rs:253:5:253:22 | data_out_of_call(...) | main.rs:16:1:19:1 | fn data_out_of_call | +| main.rs:254:5:254:35 | data_out_of_call_side_effect1(...) | main.rs:35:1:40:1 | fn data_out_of_call_side_effect1 | +| main.rs:255:5:255:35 | data_out_of_call_side_effect2(...) | main.rs:42:1:46:1 | fn data_out_of_call_side_effect2 | +| main.rs:256:5:256:21 | data_in_to_call(...) | main.rs:52:1:55:1 | fn data_in_to_call | +| main.rs:257:5:257:23 | data_through_call(...) | main.rs:61:1:65:1 | fn data_through_call | +| main.rs:258:5:258:34 | data_through_nested_function(...) | main.rs:75:1:84:1 | fn data_through_nested_function | +| main.rs:260:5:260:24 | data_out_of_method(...) | main.rs:115:1:119:1 | fn data_out_of_method | +| main.rs:261:5:261:28 | data_in_to_method_call(...) | main.rs:121:1:125:1 | fn data_in_to_method_call | +| main.rs:262:5:262:25 | data_through_method(...) | main.rs:127:1:132:1 | fn data_through_method | +| main.rs:264:5:264:31 | test_operator_overloading(...) | main.rs:175:1:190:1 | fn test_operator_overloading | +| main.rs:265:5:265:22 | test_async_await(...) | main.rs:245:1:250:1 | fn test_async_await | diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index 84d3626f3b65..e32320ff522f 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -9,11 +9,13 @@ localStep | main.rs:6:9:6:9 | s | main.rs:6:9:6:9 | s | | main.rs:6:9:6:14 | ...: i64 | main.rs:6:9:6:9 | s | | main.rs:7:14:7:20 | FormatArgsExpr | main.rs:7:14:7:20 | MacroExpr | +| main.rs:7:14:7:20 | [post] MacroExpr | main.rs:7:14:7:20 | [post] FormatArgsExpr | | main.rs:10:13:10:14 | [SSA] sr | main.rs:11:20:11:21 | sr | | main.rs:10:13:10:14 | sr | main.rs:10:13:10:14 | [SSA] sr | | main.rs:10:13:10:14 | sr | main.rs:10:13:10:14 | sr | | main.rs:10:13:10:20 | ...: ... | main.rs:10:13:10:14 | sr | | main.rs:11:14:11:21 | FormatArgsExpr | main.rs:11:14:11:21 | MacroExpr | +| main.rs:11:14:11:21 | [post] MacroExpr | main.rs:11:14:11:21 | [post] FormatArgsExpr | | main.rs:22:9:22:9 | [SSA] s | main.rs:23:10:23:10 | s | | main.rs:22:9:22:9 | s | main.rs:22:9:22:9 | [SSA] s | | main.rs:22:9:22:9 | s | main.rs:22:9:22:9 | s | @@ -690,6 +692,7 @@ localStep | main.rs:462:16:462:16 | s | main.rs:462:16:462:16 | s | | main.rs:462:16:462:24 | ...: String | main.rs:462:16:462:16 | s | | main.rs:463:14:463:20 | FormatArgsExpr | main.rs:463:14:463:20 | MacroExpr | +| main.rs:463:14:463:20 | [post] MacroExpr | main.rs:463:14:463:20 | [post] FormatArgsExpr | | main.rs:467:9:467:9 | [SSA] a | main.rs:468:13:468:13 | a | | main.rs:467:9:467:9 | a | main.rs:467:9:467:9 | [SSA] a | | main.rs:467:9:467:9 | a | main.rs:467:9:467:9 | a | @@ -850,6 +853,7 @@ localStep | main.rs:528:9:528:9 | a | main.rs:528:9:528:9 | [SSA] a | | main.rs:528:9:528:9 | a | main.rs:528:9:528:9 | a | | main.rs:528:18:528:27 | source(...) | main.rs:528:9:528:9 | a | +| main.rs:530:10:530:10 | [post] a | main.rs:531:10:531:10 | a | | main.rs:530:10:530:10 | a | main.rs:531:10:531:10 | a | | main.rs:531:10:531:10 | [post] a | main.rs:532:20:532:20 | a | | main.rs:531:10:531:10 | [post] receiver for a | main.rs:531:10:531:10 | [post] a | @@ -859,6 +863,7 @@ localStep | main.rs:534:9:534:9 | b | main.rs:534:9:534:9 | [SSA] b | | main.rs:534:9:534:9 | b | main.rs:534:9:534:9 | b | | main.rs:534:18:534:34 | ... as i32 | main.rs:534:9:534:9 | b | +| main.rs:536:10:536:10 | [post] b | main.rs:537:10:537:10 | b | | main.rs:536:10:536:10 | b | main.rs:537:10:537:10 | b | | main.rs:537:10:537:10 | [post] b | main.rs:538:20:538:20 | b | | main.rs:537:10:537:10 | [post] receiver for b | main.rs:537:10:537:10 | [post] b | @@ -866,6 +871,7 @@ localStep | main.rs:537:10:537:10 | b | main.rs:538:20:538:20 | b | | main.rs:565:13:565:33 | result_questionmark(...) | main.rs:565:9:565:9 | _ | | main.rs:577:36:577:41 | ...::new(...) | main.rs:577:36:577:41 | MacroExpr | +| main.rs:577:36:577:41 | [post] MacroExpr | main.rs:577:36:577:41 | [post] ...::new(...) | models | 1 | Sink: lang:std; crate::io::stdio::_print; log-injection; Argument[0] | | 2 | Summary: lang:alloc; <&&str as crate::string::SpecToString>::spec_to_string; Argument[self].Reference.Reference; ReturnValue; value | diff --git a/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected b/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected index 89e3a15ab487..fa32f2201b24 100644 --- a/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected @@ -6,6 +6,7 @@ | main.rs:18:11:18:11 | a | main.rs:18:10:18:11 | - ... | | main.rs:23:13:23:13 | a | main.rs:23:13:23:19 | a as u8 | | main.rs:24:10:24:10 | b | main.rs:24:10:24:17 | b as i64 | +| main.rs:24:10:24:17 | [post] b as i64 | main.rs:24:10:24:10 | [post] b | | main.rs:29:23:29:23 | i | main.rs:29:17:29:23 | FormatArgsExpr | | main.rs:33:24:33:24 | s | main.rs:33:18:33:24 | FormatArgsExpr | | main.rs:38:23:38:23 | s | main.rs:38:23:38:29 | s[...] |