Skip to content

Commit 913c78e

Browse files
Fix memory leak in normalize_language by using Cow instead of Box::leak (#91)
## Summary - Replace `Box::leak` with `Cow<'_, str>` in `normalize_language` to avoid memory leaks - Unknown language names now borrow from input instead of leaking allocated memory - Known aliases still return static string references via `Cow::Borrowed` Fixes #90
1 parent 0f8780e commit 913c78e

File tree

1 file changed

+9
-9
lines changed

1 file changed

+9
-9
lines changed

xtask/templates/umbrella_store.stpl.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
//! This file is automatically generated from the grammar registry
99
//! (`langs/group-*/*/def/arborium.kdl`). Do not edit manually.
1010
11+
use std::borrow::Cow;
1112
use std::collections::HashMap;
1213
use std::sync::{Arc, RwLock};
1314

@@ -61,37 +62,36 @@ impl GrammarStore {
6162
// Fast path: check if already cached
6263
{
6364
let grammars = self.grammars.read().unwrap();
64-
if let Some(grammar) = grammars.get(normalized) {
65+
if let Some(grammar) = grammars.get(&*normalized) {
6566
return Some(grammar.clone());
6667
}
6768
}
6869

6970
// Slow path: compile and cache
70-
let grammar = Self::compile_grammar(normalized)?;
71+
let grammar = Self::compile_grammar(&normalized)?;
7172
let grammar = Arc::new(grammar);
7273

7374
{
7475
let mut grammars = self.grammars.write().unwrap();
7576
// Double-check in case another thread compiled it
76-
if let Some(existing) = grammars.get(normalized) {
77+
if let Some(existing) = grammars.get(&*normalized) {
7778
return Some(existing.clone());
7879
}
79-
grammars.insert(normalized.to_string(), grammar.clone());
80+
grammars.insert(normalized.into_owned(), grammar.clone());
8081
}
8182

8283
Some(grammar)
8384
}
8485

8586
/// Normalize a language name to its canonical form.
86-
fn normalize_language(language: &str) -> &'static str {
87+
fn normalize_language(language: &str) -> Cow<'_, str> {
8788
match language {
8889
// Aliases (generated from arborium.kdl)
8990
<% for (alias, canonical) in aliases { %>
90-
"<%= alias %>" => "<%= canonical %>",
91+
"<%= alias %>" => Cow::Borrowed("<%= canonical %>"),
9192
<% } %>
92-
// Known canonical IDs pass through as-is
93-
// (leak the string to get &'static str - this is fine since language names are finite)
94-
_ => Box::leak(language.to_string().into_boxed_str()),
93+
// Unknown language names pass through as-is
94+
_ => Cow::Borrowed(language),
9595
}
9696
}
9797

0 commit comments

Comments
 (0)