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:
parent
92080ff6f6
commit
bb0676d3e2
1 changed files with 26 additions and 9 deletions
|
@ -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(),
|
||||||
|
|
Loading…
Reference in a new issue