fix: leaky demuxer file handles

This commit is contained in:
kieran 2025-01-27 22:50:43 +00:00
parent 128f204253
commit a63b88ef3c
No known key found for this signature in database
GPG Key ID: DE71CEB3925BE941
3 changed files with 37 additions and 8 deletions

12
Cargo.lock generated
View File

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
@ -181,6 +181,7 @@ dependencies = [
"ffmpeg-sys-the-third", "ffmpeg-sys-the-third",
"libc", "libc",
"log", "log",
"rlimit",
"slimbox", "slimbox",
] ]
@ -333,6 +334,15 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "rlimit"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7043b63bd0cd1aaa628e476b80e6d4023a3b50eb32789f2728908107bd0c793a"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "rustc-hash" name = "rustc-hash"
version = "1.1.0" version = "1.1.0"

View File

@ -17,3 +17,4 @@ log = "0.4.22"
[dev-dependencies] [dev-dependencies]
env_logger = "0.11.5" env_logger = "0.11.5"
rlimit = "0.10.2"

View File

@ -250,14 +250,15 @@ impl Drop for Demuxer {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
if !self.ctx.is_null() { if !self.ctx.is_null() {
if let DemuxerInput::Reader(_, _) = self.input { match self.input {
av_free((*(*self.ctx).pb).buffer as *mut _); DemuxerInput::Reader(_, _) => {
drop(SlimBox::<dyn Read>::from_raw((*(*self.ctx).pb).opaque)); av_free((*(*self.ctx).pb).buffer as *mut _);
drop(SlimBox::<dyn Read>::from_raw((*(*self.ctx).pb).opaque));
avio_context_free(&mut (*self.ctx).pb);
}
_ => {}
} }
if !(*self.ctx).pb.is_null() { avformat_close_input(&mut self.ctx);
avio_context_free(&mut (*self.ctx).pb);
}
avformat_free_context(self.ctx);
} }
} }
} }
@ -284,4 +285,21 @@ mod tests {
} }
Ok(()) Ok(())
} }
/// Test for leaking file handles
#[test]
fn probe_lots() -> Result<()> {
rlimit::setrlimit(rlimit::Resource::NOFILE, 64, 128)?;
let nof_limit = rlimit::Resource::NOFILE.get_hard()?;
for n in 0..nof_limit {
let mut demux = Demuxer::new("./test_output/test.png")?;
unsafe {
if let Err(e) = demux.probe_input() {
bail!("Failed on {}: {}", n, e);
}
}
}
Ok(())
}
} }