From 55121d866cd96939c126d9c2988af6e21a3e9346 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 20 Nov 2024 11:45:42 +0100 Subject: [PATCH 1/4] Rust: Add CFG tests for method definitions with self parameters --- .../library-tests/controlflow/Cfg.expected | 30 +++++++++++++++++++ .../ql/test/library-tests/controlflow/test.rs | 18 +++++++++++ 2 files changed, 48 insertions(+) diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 620837abc826..6b2642e65126 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -1044,6 +1044,36 @@ edges | test.rs:490:5:490:19 | ExprStmt | test.rs:490:5:490:10 | nested | | | test.rs:490:12:490:17 | RefExpr | test.rs:490:5:490:18 | CallExpr | | | test.rs:490:17:490:17 | x | test.rs:490:12:490:17 | RefExpr | | +| test.rs:502:5:504:5 | enter new | test.rs:502:12:502:12 | a | | +| test.rs:502:5:504:5 | exit new (normal) | test.rs:502:5:504:5 | exit new | | +| test.rs:502:12:502:12 | a | test.rs:502:12:502:17 | Param | match | +| test.rs:502:12:502:17 | Param | test.rs:503:23:503:23 | a | | +| test.rs:502:28:504:5 | BlockExpr | test.rs:502:5:504:5 | exit new (normal) | | +| test.rs:503:9:503:25 | RecordExpr | test.rs:502:28:504:5 | BlockExpr | | +| test.rs:503:23:503:23 | a | test.rs:503:9:503:25 | RecordExpr | | +| test.rs:506:5:508:5 | enter negated | test.rs:507:23:507:26 | self | | +| test.rs:506:5:508:5 | exit negated (normal) | test.rs:506:5:508:5 | exit negated | | +| test.rs:506:30:508:5 | BlockExpr | test.rs:506:5:508:5 | exit negated (normal) | | +| test.rs:507:9:507:30 | RecordExpr | test.rs:506:30:508:5 | BlockExpr | | +| test.rs:507:23:507:26 | self | test.rs:507:23:507:28 | FieldExpr | | +| test.rs:507:23:507:28 | FieldExpr | test.rs:507:9:507:30 | RecordExpr | | +| test.rs:510:5:512:5 | enter multifly_add | test.rs:510:32:510:32 | a | | +| test.rs:510:5:512:5 | exit multifly_add (normal) | test.rs:510:5:512:5 | exit multifly_add | | +| test.rs:510:32:510:32 | a | test.rs:510:32:510:37 | Param | match | +| test.rs:510:32:510:37 | Param | test.rs:510:40:510:40 | b | | +| test.rs:510:40:510:40 | b | test.rs:510:40:510:45 | Param | match | +| test.rs:510:40:510:45 | Param | test.rs:511:9:511:34 | ExprStmt | | +| test.rs:510:48:512:5 | BlockExpr | test.rs:510:5:512:5 | exit multifly_add (normal) | | +| test.rs:511:9:511:12 | self | test.rs:511:9:511:14 | FieldExpr | | +| test.rs:511:9:511:14 | FieldExpr | test.rs:511:19:511:22 | self | | +| test.rs:511:9:511:33 | ... = ... | test.rs:510:48:512:5 | BlockExpr | | +| test.rs:511:9:511:34 | ExprStmt | test.rs:511:9:511:12 | self | | +| test.rs:511:18:511:33 | ... + ... | test.rs:511:9:511:33 | ... = ... | | +| test.rs:511:19:511:22 | self | test.rs:511:19:511:24 | FieldExpr | | +| test.rs:511:19:511:24 | FieldExpr | test.rs:511:28:511:28 | a | | +| test.rs:511:19:511:28 | ... * ... | test.rs:511:33:511:33 | b | | +| test.rs:511:28:511:28 | a | test.rs:511:19:511:28 | ... * ... | | +| test.rs:511:33:511:33 | b | test.rs:511:18:511:33 | ... + ... | | breakTarget | test.rs:34:17:34:21 | BreakExpr | test.rs:28:9:40:9 | LoopExpr | | test.rs:48:21:48:25 | BreakExpr | test.rs:46:13:53:13 | LoopExpr | diff --git a/rust/ql/test/library-tests/controlflow/test.rs b/rust/ql/test/library-tests/controlflow/test.rs index e1d596188061..42094c5432e5 100644 --- a/rust/ql/test/library-tests/controlflow/test.rs +++ b/rust/ql/test/library-tests/controlflow/test.rs @@ -493,3 +493,21 @@ fn test_nested_function2() { trait MyFrom { fn my_from(x: T) -> Self; } + +struct MyNumber { + n: i64, +} + +impl MyNumber { + fn new(a: i64) -> Self { + MyNumber { n: a } + } + + fn negated(self) -> Self { + MyNumber { n: self.n } + } + + fn multifly_add(&mut self, a: i64, b: i64) { + self.n = (self.n * a) + b; + } +} From 24adbb80c7adaa0ee084cd4dac18acd5dc3c4c0c Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 20 Nov 2024 11:50:46 +0100 Subject: [PATCH 2/4] Rust: Include self parameters in the CFG --- .../controlflow/internal/ControlFlowGraphImpl.qll | 15 +++++++++++++-- .../test/library-tests/controlflow/Cfg.expected | 8 ++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index b331ddd2d540..ef4f7808fa20 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -72,10 +72,17 @@ import CfgImpl class CallableScopeTree extends StandardTree, PreOrderTree, PostOrderTree, Scope::CallableScope { override predicate propagatesAbnormal(AstNode child) { none() } + private int getNumberOfSelfParams() { + if this.getParamList().hasSelfParam() then result = 1 else result = 0 + } + override AstNode getChildNode(int i) { - result = this.getParamList().getParam(i) + i = 0 and + result = this.getParamList().getSelfParam() + or + result = this.getParamList().getParam(i - this.getNumberOfSelfParams()) or - i = this.getParamList().getNumberOfParams() and + i = this.getParamList().getNumberOfParams() + this.getNumberOfSelfParams() and result = this.getBody() } } @@ -191,6 +198,10 @@ class NameTree extends LeafTree, Name { } class NameRefTree extends LeafTree, NameRef { } +class SelfParamTree extends StandardPostOrderTree, SelfParam { + override AstNode getChildNode(int i) { i = 0 and result = this.getName() } +} + class TypeRefTree extends LeafTree instanceof TypeRef { } /** diff --git a/rust/ql/test/library-tests/controlflow/Cfg.expected b/rust/ql/test/library-tests/controlflow/Cfg.expected index 6b2642e65126..8fd71a451b86 100644 --- a/rust/ql/test/library-tests/controlflow/Cfg.expected +++ b/rust/ql/test/library-tests/controlflow/Cfg.expected @@ -1051,14 +1051,18 @@ edges | test.rs:502:28:504:5 | BlockExpr | test.rs:502:5:504:5 | exit new (normal) | | | test.rs:503:9:503:25 | RecordExpr | test.rs:502:28:504:5 | BlockExpr | | | test.rs:503:23:503:23 | a | test.rs:503:9:503:25 | RecordExpr | | -| test.rs:506:5:508:5 | enter negated | test.rs:507:23:507:26 | self | | +| test.rs:506:5:508:5 | enter negated | test.rs:506:16:506:19 | self | | | test.rs:506:5:508:5 | exit negated (normal) | test.rs:506:5:508:5 | exit negated | | +| test.rs:506:16:506:19 | SelfParam | test.rs:507:23:507:26 | self | | +| test.rs:506:16:506:19 | self | test.rs:506:16:506:19 | SelfParam | | | test.rs:506:30:508:5 | BlockExpr | test.rs:506:5:508:5 | exit negated (normal) | | | test.rs:507:9:507:30 | RecordExpr | test.rs:506:30:508:5 | BlockExpr | | | test.rs:507:23:507:26 | self | test.rs:507:23:507:28 | FieldExpr | | | test.rs:507:23:507:28 | FieldExpr | test.rs:507:9:507:30 | RecordExpr | | -| test.rs:510:5:512:5 | enter multifly_add | test.rs:510:32:510:32 | a | | +| test.rs:510:5:512:5 | enter multifly_add | test.rs:510:26:510:29 | self | | | test.rs:510:5:512:5 | exit multifly_add (normal) | test.rs:510:5:512:5 | exit multifly_add | | +| test.rs:510:21:510:29 | SelfParam | test.rs:510:32:510:32 | a | | +| test.rs:510:26:510:29 | self | test.rs:510:21:510:29 | SelfParam | | | test.rs:510:32:510:32 | a | test.rs:510:32:510:37 | Param | match | | test.rs:510:32:510:37 | Param | test.rs:510:40:510:40 | b | | | test.rs:510:40:510:40 | b | test.rs:510:40:510:45 | Param | match | From aab0d5e9e4fbdf3447b928c0239f0bdb2ef394ac Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 20 Nov 2024 12:35:52 +0100 Subject: [PATCH 3/4] Rust: Refactor to avoid needing `getNumberOfSelfParams` --- .../rust/controlflow/internal/ControlFlowGraphImpl.qll | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index ef4f7808fa20..938b933cba05 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -72,17 +72,13 @@ import CfgImpl class CallableScopeTree extends StandardTree, PreOrderTree, PostOrderTree, Scope::CallableScope { override predicate propagatesAbnormal(AstNode child) { none() } - private int getNumberOfSelfParams() { - if this.getParamList().hasSelfParam() then result = 1 else result = 0 - } - override AstNode getChildNode(int i) { i = 0 and result = this.getParamList().getSelfParam() or - result = this.getParamList().getParam(i - this.getNumberOfSelfParams()) + result = this.getParamList().getParam(i - 1) or - i = this.getParamList().getNumberOfParams() + this.getNumberOfSelfParams() and + i = this.getParamList().getNumberOfParams() + 1 and result = this.getBody() } } From 93f6f042e1a1b144f3bc8f3cfa2f2105da99794f Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 20 Nov 2024 12:39:31 +0100 Subject: [PATCH 4/4] Rust: Update expected file --- rust/ql/test/library-tests/variables/Cfg.expected | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rust/ql/test/library-tests/variables/Cfg.expected b/rust/ql/test/library-tests/variables/Cfg.expected index 3ff46aa9f7ec..bb635f788792 100644 --- a/rust/ql/test/library-tests/variables/Cfg.expected +++ b/rust/ql/test/library-tests/variables/Cfg.expected @@ -1070,8 +1070,10 @@ edges | variables.rs:472:9:472:20 | CallExpr | variables.rs:471:12:473:5 | BlockExpr | | | variables.rs:472:9:472:21 | ExprStmt | variables.rs:472:9:472:17 | print_i64 | | | variables.rs:472:19:472:19 | x | variables.rs:472:9:472:20 | CallExpr | | -| variables.rs:482:5:484:5 | enter my_get | variables.rs:483:9:483:24 | ExprStmt | | +| variables.rs:482:5:484:5 | enter my_get | variables.rs:482:20:482:23 | self | | | variables.rs:482:5:484:5 | exit my_get (normal) | variables.rs:482:5:484:5 | exit my_get | | +| variables.rs:482:15:482:23 | SelfParam | variables.rs:483:9:483:24 | ExprStmt | | +| variables.rs:482:20:482:23 | self | variables.rs:482:15:482:23 | SelfParam | | | variables.rs:483:9:483:23 | ReturnExpr | variables.rs:482:5:484:5 | exit my_get (normal) | return | | variables.rs:483:9:483:24 | ExprStmt | variables.rs:483:16:483:19 | self | | | variables.rs:483:16:483:19 | self | variables.rs:483:16:483:23 | FieldExpr | | @@ -1131,8 +1133,10 @@ edges | variables.rs:502:5:502:22 | ExprStmt | variables.rs:502:5:502:17 | print_i64_ref | | | variables.rs:502:19:502:20 | RefExpr | variables.rs:502:5:502:21 | CallExpr | | | variables.rs:502:20:502:20 | z | variables.rs:502:19:502:20 | RefExpr | | -| variables.rs:510:3:512:3 | enter bar | variables.rs:511:5:511:32 | ExprStmt | | +| variables.rs:510:3:512:3 | enter bar | variables.rs:510:15:510:18 | self | | | variables.rs:510:3:512:3 | exit bar (normal) | variables.rs:510:3:512:3 | exit bar | | +| variables.rs:510:10:510:18 | SelfParam | variables.rs:511:5:511:32 | ExprStmt | | +| variables.rs:510:15:510:18 | self | variables.rs:510:10:510:18 | SelfParam | | | variables.rs:510:21:512:3 | BlockExpr | variables.rs:510:3:512:3 | exit bar (normal) | | | variables.rs:511:5:511:9 | * ... | variables.rs:511:29:511:29 | 3 | | | variables.rs:511:5:511:31 | ... = ... | variables.rs:510:21:512:3 | BlockExpr | |