Skip to content

Commit d9fe03a

Browse files
authored
fix: memory leak in faidx when fetching sequences (#455)
1 parent 7f3cfea commit d9fe03a

File tree

1 file changed

+16
-14
lines changed

1 file changed

+16
-14
lines changed

src/faidx/mod.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -85,27 +85,27 @@ impl Reader {
8585
/// * `name` - the name of the template sequence (e.g., "chr1")
8686
/// * `begin` - the offset within the template sequence (starting with 0)
8787
/// * `end` - the end position to return (if smaller than `begin`, the behavior is undefined).
88-
pub fn fetch_seq<N: AsRef<str>>(&self, name: N, begin: usize, end: usize) -> Result<&[u8]> {
88+
pub fn fetch_seq<N: AsRef<str>>(&self, name: N, begin: usize, end: usize) -> Result<Vec<u8>> {
8989
if begin > std::i64::MAX as usize {
9090
return Err(Error::FaidxPositionTooLarge);
9191
}
9292
if end > std::i64::MAX as usize {
9393
return Err(Error::FaidxPositionTooLarge);
9494
}
9595
let cname = ffi::CString::new(name.as_ref().as_bytes()).unwrap();
96-
let len_out: i64 = 0;
97-
let cseq = unsafe {
98-
let ptr = htslib::faidx_fetch_seq64(
99-
self.inner, //*const faidx_t,
100-
cname.as_ptr(), // c_name
101-
begin as htslib::hts_pos_t, // p_beg_i
102-
end as htslib::hts_pos_t, // p_end_i
103-
&mut (len_out as htslib::hts_pos_t), //len
104-
);
105-
ffi::CStr::from_ptr(ptr)
96+
let mut len_out: htslib::hts_pos_t = 0;
97+
let ptr = unsafe {
98+
htslib::faidx_fetch_seq64(
99+
self.inner, //*const faidx_t,
100+
cname.as_ptr(), // c_name
101+
begin as htslib::hts_pos_t, // p_beg_i
102+
end as htslib::hts_pos_t, // p_end_i
103+
&mut len_out, //len
104+
)
106105
};
107-
108-
Ok(cseq.to_bytes())
106+
let vec =
107+
unsafe { Vec::from_raw_parts(ptr as *mut u8, len_out as usize, len_out as usize) };
108+
Ok(vec)
109109
}
110110

111111
/// Fetches the sequence and returns it as string.
@@ -122,7 +122,7 @@ impl Reader {
122122
end: usize,
123123
) -> Result<String> {
124124
let bytes = self.fetch_seq(name, begin, end)?;
125-
Ok(std::str::from_utf8(bytes).unwrap().to_owned())
125+
Ok(std::str::from_utf8(&bytes).unwrap().to_owned())
126126
}
127127

128128
/// Fetches the number of sequences in the fai index
@@ -226,13 +226,15 @@ mod tests {
226226
fn faidx_read_chr_start() {
227227
let r = open_reader();
228228

229+
//for _i in 0..100_000_000 { // loop to check for memory leaks
229230
let bseq = r.fetch_seq("chr1", 0, 9).unwrap();
230231
assert_eq!(bseq.len(), 10);
231232
assert_eq!(bseq, b"GGGCACAGCC");
232233

233234
let seq = r.fetch_seq_string("chr1", 0, 9).unwrap();
234235
assert_eq!(seq.len(), 10);
235236
assert_eq!(seq, "GGGCACAGCC");
237+
//}
236238
}
237239

238240
#[test]

0 commit comments

Comments
 (0)