diff options
author | Levente Kurusa <lkurusa@kernelstuff.org> | 2023-05-28 20:30:55 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-28 12:30:55 -0600 |
commit | bb0676d3e23dfd7fe27f9932b955694d51438486 (patch) | |
tree | b74ddb05c13f0df7f733ea2e75c9d09a21606894 | |
parent | 92080ff6f6caf7673b50be08132729eccaea050a (diff) |
fix(ext/http): fix a possible memleak in Brotli (#19250)
We probably need to free the BrotliEncoderState once the stream has
finished.
-rw-r--r-- | ext/http/response_body.rs | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/ext/http/response_body.rs b/ext/http/response_body.rs index 7da2142d3..6793f0e78 100644 --- a/ext/http/response_body.rs +++ b/ext/http/response_body.rs @@ -7,6 +7,7 @@ use std::pin::Pin; use std::rc::Rc; use std::task::Waker; +use brotli::ffi::compressor::BrotliEncoderState; use bytes::Bytes; use bytes::BytesMut; use deno_core::error::bad_resource; @@ -586,26 +587,42 @@ enum BrotliState { EndOfStream, } +struct BrotliEncoderStateWrapper { + stm: *mut BrotliEncoderState, +} + #[pin_project] pub struct BrotliResponseStream { state: BrotliState, - stm: *mut brotli::ffi::compressor::BrotliEncoderState, + stm: BrotliEncoderStateWrapper, current_cursor: usize, output_written_so_far: usize, #[pin] underlying: ResponseStream, } +impl Drop for BrotliEncoderStateWrapper { + fn drop(&mut self) { + // SAFETY: since we are dropping, we can be sure that this instance will not + // be used again. + unsafe { + brotli::ffi::compressor::BrotliEncoderDestroyInstance(self.stm); + } + } +} + impl BrotliResponseStream { pub fn new(underlying: ResponseStream) -> Self { Self { // SAFETY: creating an FFI instance should be OK with these args. stm: unsafe { - brotli::ffi::compressor::BrotliEncoderCreateInstance( - None, - None, - std::ptr::null_mut(), - ) + BrotliEncoderStateWrapper { + stm: brotli::ffi::compressor::BrotliEncoderCreateInstance( + None, + None, + std::ptr::null_mut(), + ), + } }, output_written_so_far: 0, current_cursor: 0, @@ -662,7 +679,7 @@ impl PollFrame for BrotliResponseStream { // SAFETY: these are okay arguments to these FFI calls. unsafe { brotli::ffi::compressor::BrotliEncoderCompressStream( - this.stm, + this.stm.stm, brotli::ffi::compressor::BrotliEncoderOperation::BROTLI_OPERATION_PROCESS, &mut input_size, &input_buffer.as_ptr() as *const *const u8 as *mut *const u8, @@ -674,7 +691,7 @@ impl PollFrame for BrotliResponseStream { output_written = 0; brotli::ffi::compressor::BrotliEncoderCompressStream( - this.stm, + this.stm.stm, brotli::ffi::compressor::BrotliEncoderOperation::BROTLI_OPERATION_FLUSH, &mut input_size, &input_buffer.as_ptr() as *const *const u8 as *mut *const u8, @@ -700,7 +717,7 @@ impl PollFrame for BrotliResponseStream { // SAFETY: these are okay arguments to these FFI calls. unsafe { brotli::ffi::compressor::BrotliEncoderCompressStream( - this.stm, + this.stm.stm, brotli::ffi::compressor::BrotliEncoderOperation::BROTLI_OPERATION_FINISH, &mut input_size, std::ptr::null_mut(), |