Skip to content

Commit 118e083

Browse files
haasonsaasclaude
andcommitted
fix: operator precedence bug, double boost, redundant to_lowercase
- Add explicit parentheses in extract_tags() TLS/SSL check to clarify operator precedence (|| vs &&) - Remove duplicate "buffer overflow" confidence boost that existed in both "Unsafe code" and "Correctness" sections (+0.4 total → +0.2) - Compute to_lowercase() once in process_raw_comment() and pass the pre-lowercased string to all 5 classification methods, eliminating 4 redundant heap allocations per comment Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e52a16d commit 118e083

1 file changed

Lines changed: 18 additions & 20 deletions

File tree

src/core/comment.rs

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -178,27 +178,28 @@ impl CommentSynthesizer {
178178
}
179179

180180
fn process_raw_comment(raw: RawComment) -> Result<Option<Comment>> {
181+
let lower = raw.content.to_lowercase();
181182
let severity = raw
182183
.severity
183184
.clone()
184-
.unwrap_or_else(|| Self::determine_severity(&raw.content));
185+
.unwrap_or_else(|| Self::determine_severity(&lower));
185186
let category = raw
186187
.category
187188
.clone()
188-
.unwrap_or_else(|| Self::determine_category(&raw.content));
189+
.unwrap_or_else(|| Self::determine_category(&lower));
189190
let confidence = raw
190191
.confidence
191-
.unwrap_or_else(|| Self::calculate_confidence(&raw.content, &severity, &category));
192+
.unwrap_or_else(|| Self::calculate_confidence(&lower, &severity, &category));
192193
let confidence = confidence.clamp(0.0, 1.0);
193194
let tags = if raw.tags.is_empty() {
194-
Self::extract_tags(&raw.content, &category)
195+
Self::extract_tags(&lower, &category)
195196
} else {
196197
raw.tags.clone()
197198
};
198199
let fix_effort = raw
199200
.fix_effort
200201
.clone()
201-
.unwrap_or_else(|| Self::determine_fix_effort(&raw.content, &category));
202+
.unwrap_or_else(|| Self::determine_fix_effort(&lower, &category));
202203
let code_suggestion = Self::generate_code_suggestion(&raw);
203204
let id = Self::generate_comment_id(&raw.file_path, &raw.content, &category);
204205

@@ -223,8 +224,8 @@ impl CommentSynthesizer {
223224
compute_comment_id(file_path, content, category)
224225
}
225226

226-
fn determine_severity(content: &str) -> Severity {
227-
let lower = content.to_lowercase();
227+
/// `lower` must already be lowercased.
228+
fn determine_severity(lower: &str) -> Severity {
228229
if lower.contains("error") || lower.contains("critical") {
229230
Severity::Error
230231
} else if lower.contains("warning") || lower.contains("issue") {
@@ -236,9 +237,8 @@ impl CommentSynthesizer {
236237
}
237238
}
238239

239-
fn determine_category(content: &str) -> Category {
240-
let lower = content.to_lowercase();
241-
240+
/// `lower` must already be lowercased.
241+
fn determine_category(lower: &str) -> Category {
242242
// Security — broad keyword coverage across all 5 vulnerability classes
243243
if lower.contains("security")
244244
|| lower.contains("vulnerability")
@@ -364,11 +364,10 @@ impl CommentSynthesizer {
364364
}
365365
}
366366

367-
fn calculate_confidence(content: &str, severity: &Severity, _category: &Category) -> f32 {
367+
/// `lower` must already be lowercased.
368+
fn calculate_confidence(lower: &str, severity: &Severity, _category: &Category) -> f32 {
368369
let mut confidence: f32 = 0.7; // Base confidence
369370

370-
let lower = content.to_lowercase();
371-
372371
// ── Injection (high-confidence, well-defined patterns) ──
373372
if lower.contains("sql injection") {
374373
confidence += 0.2;
@@ -550,7 +549,7 @@ impl CommentSynthesizer {
550549
}
551550

552551
// ── Correctness ──
553-
if lower.contains("null pointer") || lower.contains("buffer overflow") {
552+
if lower.contains("null pointer") {
554553
confidence += 0.2;
555554
}
556555
if lower.contains("performance issue") || lower.contains("n+1") {
@@ -572,9 +571,9 @@ impl CommentSynthesizer {
572571
confidence.clamp(0.1, 1.0)
573572
}
574573

575-
fn extract_tags(content: &str, category: &Category) -> Vec<String> {
574+
/// `lower` must already be lowercased.
575+
fn extract_tags(lower: &str, category: &Category) -> Vec<String> {
576576
let mut tags = vec![category.as_str().to_string()];
577-
let lower = content.to_lowercase();
578577

579578
// ── Injection tags ──
580579
if lower.contains("sql") && lower.contains("injection") {
@@ -709,7 +708,7 @@ impl CommentSynthesizer {
709708
if lower.contains("ecb") && lower.contains("mode") {
710709
tags.push("ecb-mode".to_string());
711710
}
712-
if lower.contains("insecure tls") || lower.contains("ssl") && lower.contains("insecure") {
711+
if lower.contains("insecure tls") || (lower.contains("ssl") && lower.contains("insecure")) {
713712
tags.push("insecure-tls".to_string());
714713
}
715714
if lower.contains("insecure random")
@@ -861,9 +860,8 @@ impl CommentSynthesizer {
861860
tags
862861
}
863862

864-
fn determine_fix_effort(content: &str, category: &Category) -> FixEffort {
865-
let lower = content.to_lowercase();
866-
863+
/// `lower` must already be lowercased.
864+
fn determine_fix_effort(lower: &str, category: &Category) -> FixEffort {
867865
// High effort indicators
868866
if lower.contains("architecture")
869867
|| lower.contains("refactor")

0 commit comments

Comments
 (0)