Skip to content

Commit 23efba6

Browse files
author
Vara Prasad Bandaru
committed
Upd missing_owner_check to not report local variables, duplicate warnings when to_account_info is called on Anchor's AccountInfo.
1 parent 46dabdd commit 23efba6

File tree

1 file changed

+23
-1
lines changed
  • lints/missing_owner_check/src

1 file changed

+23
-1
lines changed

lints/missing_owner_check/src/lib.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use if_chain::if_chain;
1212
use rustc_hir::{
1313
def_id::LocalDefId,
1414
intravisit::{walk_expr, FnKind, Visitor},
15-
Body, Expr, ExprKind, FnDecl,
15+
Body, Expr, ExprKind, FnDecl, QPath,
1616
};
1717
use rustc_lint::{LateContext, LateLintPass};
1818
use rustc_middle::ty;
@@ -108,6 +108,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for AccountUses<'cx, 'tcx> {
108108
if !is_call_to_clone(self.cx, expr);
109109
let ty = self.cx.typeck_results().expr_ty(expr);
110110
if match_type(self.cx, ty, &paths::SOLANA_PROGRAM_ACCOUNT_INFO);
111+
if !is_expr_local_variable(expr);
111112
if !is_safe_to_account_info(self.cx, expr);
112113
let mut spanless_eq = SpanlessEq::new(self.cx);
113114
if !self.uses.iter().any(|e| spanless_eq.eq_expr(e, expr));
@@ -119,6 +120,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for AccountUses<'cx, 'tcx> {
119120
}
120121
}
121122

123+
// s3v3ru5: the following check removes duplicate warnings where lint would report both `x` and `x.clone()` expressions.
122124
/// Return true if the expr is a method call to clone else false
123125
fn is_call_to_clone<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool {
124126
if_chain! {
@@ -133,6 +135,24 @@ fn is_call_to_clone<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> boo
133135
}
134136
}
135137

138+
// s3v3ru5: if a local variable is of type AccountInfo, the rhs of the let statement assigning to variable
139+
// will be of type AccountInfo. The lint would check that expression and there is no need for checking the
140+
// local variable as well.
141+
// This removes the false positives of following pattern:
142+
// `let x = {Account, Program, ...verified structs}.to_account_info()`,
143+
// the lint reports uses of `x`. Having this check would remove such false positives.
144+
fn is_expr_local_variable<'tcx>(expr: &'tcx Expr<'tcx>) -> bool {
145+
if_chain! {
146+
if let ExprKind::Path(QPath::Resolved(None, path)) = expr.kind;
147+
if path.segments.len() == 1;
148+
then {
149+
true
150+
} else {
151+
false
152+
}
153+
}
154+
}
155+
136156
// smoelius: See: https://github.com/crytic/solana-lints/issues/31
137157
fn is_safe_to_account_info<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool {
138158
if_chain! {
@@ -158,6 +178,8 @@ fn is_safe_to_account_info<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>)
158178
&paths::ANCHOR_LANG_ACCOUNT_LOADER,
159179
&paths::ANCHOR_LANG_SIGNER,
160180
&paths::ANCHOR_LANG_SYSVAR,
181+
// s3v3ru5: The following line will remove duplicate warnings where lint reports both `x` and `x.to_account_info()` when x is of type Anchor's AccountInfo.
182+
&paths::SOLANA_PROGRAM_ACCOUNT_INFO,
161183
],
162184
)
163185
.is_some();

0 commit comments

Comments
 (0)