summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLevente Kurusa <lkurusa@kernelstuff.org>2023-05-28 20:30:55 +0200
committerGitHub <noreply@github.com>2023-05-28 12:30:55 -0600
commitbb0676d3e23dfd7fe27f9932b955694d51438486 (patch)
treeb74ddb05c13f0df7f733ea2e75c9d09a21606894
parent92080ff6f6caf7673b50be08132729eccaea050a (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.rs35
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(),