Skip to content

Commit 3f6ef95

Browse files
Copilot0xrinegade
andcommitted
Fix AST analyzer tests - improve pattern matching for token streams
Co-authored-by: 0xrinegade <[email protected]>
1 parent 0fd2cac commit 3f6ef95

File tree

1 file changed

+32
-6
lines changed

1 file changed

+32
-6
lines changed

src/utils/ast_analyzer.rs

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -287,17 +287,41 @@ impl AstAnalyzer {
287287
None
288288
}
289289

290+
/// Extract the variable name that holds an account reference
291+
fn extract_account_variable_name(&self, content: &str) -> Option<String> {
292+
// Look for patterns like "let var_name = &ctx.accounts.something"
293+
if let Some(start) = content.find("let ") {
294+
let after_let = &content[start + 4..];
295+
if let Some(equals_pos) = after_let.find(" = ") {
296+
let var_name = after_let[..equals_pos].trim();
297+
if content.contains(&format!("{}.balance", var_name)) ||
298+
content.contains(&format!("{}.", var_name)) {
299+
return Some(var_name.to_string());
300+
}
301+
}
302+
}
303+
None
304+
}
305+
290306
/// Apply pattern-based fixes as fallback
291307
fn apply_pattern_based_fixes(&self, content: &str, finding: &AuditFinding) -> String {
292308
let mut fixed_content = content.to_string();
293309

294310
match finding.category.as_str() {
295311
"Authentication & Authorization" => {
296-
if !content.contains("is_signer") && content.contains("AccountInfo") {
297-
fixed_content = format!(
298-
"// Added signer validation\nrequire!(account.is_signer, ErrorCode::MissingSignature);\n{}",
299-
fixed_content
300-
);
312+
if !content.contains("is_signer") && (content.contains("AccountInfo") || content.contains("ctx.accounts")) {
313+
// Extract account variable name from the content
314+
if let Some(account_var) = self.extract_account_variable_name(content) {
315+
fixed_content = format!(
316+
"// Added signer validation\nrequire!({}.is_signer, ErrorCode::MissingSignature);\n{}",
317+
account_var, fixed_content
318+
);
319+
} else {
320+
fixed_content = format!(
321+
"// Added signer validation\nrequire!(account.is_signer, ErrorCode::MissingSignature);\n{}",
322+
fixed_content
323+
);
324+
}
301325
}
302326
}
303327
"Solana Security" => {
@@ -394,7 +418,9 @@ impl SolanaSecurityVisitor {
394418
let func_str = func.to_token_stream().to_string();
395419

396420
// Check for missing signer validation
397-
if func_str.contains("ctx.accounts") && !func_str.contains("is_signer") {
421+
// Token stream format: "ctx . accounts" instead of "ctx.accounts"
422+
if (func_str.contains("ctx . accounts") || func_str.contains("ctx.accounts")) &&
423+
!func_str.contains("is_signer") {
398424
self.context.security_issues.push(SecurityIssue {
399425
issue_type: SecurityIssueType::MissingSignerCheck,
400426
location: CodeLocation {

0 commit comments

Comments
 (0)