1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 07:14:47 -05:00

fix(ext/http): fix a possible memleak in Brotli (#19250)

We probably need to free the BrotliEncoderState once the stream has
finished.
This commit is contained in:
Levente Kurusa 2023-05-28 20:30:55 +02:00 committed by GitHub
parent 92080ff6f6
commit bb0676d3e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -7,6 +7,7 @@ use std::pin::Pin;
use std::rc::Rc; use std::rc::Rc;
use std::task::Waker; use std::task::Waker;
use brotli::ffi::compressor::BrotliEncoderState;
use bytes::Bytes; use bytes::Bytes;
use bytes::BytesMut; use bytes::BytesMut;
use deno_core::error::bad_resource; use deno_core::error::bad_resource;
@ -586,26 +587,42 @@ enum BrotliState {
EndOfStream, EndOfStream,
} }
struct BrotliEncoderStateWrapper {
stm: *mut BrotliEncoderState,
}
#[pin_project] #[pin_project]
pub struct BrotliResponseStream { pub struct BrotliResponseStream {
state: BrotliState, state: BrotliState,
stm: *mut brotli::ffi::compressor::BrotliEncoderState, stm: BrotliEncoderStateWrapper,
current_cursor: usize, current_cursor: usize,
output_written_so_far: usize, output_written_so_far: usize,
#[pin] #[pin]
underlying: ResponseStream, 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 { impl BrotliResponseStream {
pub fn new(underlying: ResponseStream) -> Self { pub fn new(underlying: ResponseStream) -> Self {
Self { Self {
// SAFETY: creating an FFI instance should be OK with these args. // SAFETY: creating an FFI instance should be OK with these args.
stm: unsafe { stm: unsafe {
brotli::ffi::compressor::BrotliEncoderCreateInstance( BrotliEncoderStateWrapper {
None, stm: brotli::ffi::compressor::BrotliEncoderCreateInstance(
None, None,
std::ptr::null_mut(), None,
) std::ptr::null_mut(),
),
}
}, },
output_written_so_far: 0, output_written_so_far: 0,
current_cursor: 0, current_cursor: 0,
@ -662,7 +679,7 @@ impl PollFrame for BrotliResponseStream {
// SAFETY: these are okay arguments to these FFI calls. // SAFETY: these are okay arguments to these FFI calls.
unsafe { unsafe {
brotli::ffi::compressor::BrotliEncoderCompressStream( brotli::ffi::compressor::BrotliEncoderCompressStream(
this.stm, this.stm.stm,
brotli::ffi::compressor::BrotliEncoderOperation::BROTLI_OPERATION_PROCESS, brotli::ffi::compressor::BrotliEncoderOperation::BROTLI_OPERATION_PROCESS,
&mut input_size, &mut input_size,
&input_buffer.as_ptr() as *const *const u8 as *mut *const u8, &input_buffer.as_ptr() as *const *const u8 as *mut *const u8,
@ -674,7 +691,7 @@ impl PollFrame for BrotliResponseStream {
output_written = 0; output_written = 0;
brotli::ffi::compressor::BrotliEncoderCompressStream( brotli::ffi::compressor::BrotliEncoderCompressStream(
this.stm, this.stm.stm,
brotli::ffi::compressor::BrotliEncoderOperation::BROTLI_OPERATION_FLUSH, brotli::ffi::compressor::BrotliEncoderOperation::BROTLI_OPERATION_FLUSH,
&mut input_size, &mut input_size,
&input_buffer.as_ptr() as *const *const u8 as *mut *const u8, &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. // SAFETY: these are okay arguments to these FFI calls.
unsafe { unsafe {
brotli::ffi::compressor::BrotliEncoderCompressStream( brotli::ffi::compressor::BrotliEncoderCompressStream(
this.stm, this.stm.stm,
brotli::ffi::compressor::BrotliEncoderOperation::BROTLI_OPERATION_FINISH, brotli::ffi::compressor::BrotliEncoderOperation::BROTLI_OPERATION_FINISH,
&mut input_size, &mut input_size,
std::ptr::null_mut(), std::ptr::null_mut(),