diff options
| author | Florian Schwalm <68847951+egfx-notifications@users.noreply.github.com> | 2024-02-13 22:45:23 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-13 21:45:23 +0000 |
| commit | 082f8128b8d784c599fdf2c0d857dbbe6abbc7fe (patch) | |
| tree | 340091c16273e3faca4e08465ef8685086a3907c /ext | |
| parent | 365d7886480281056c930174d756ae660619b044 (diff) | |
fix(ext/web): Prevent (De-)CompressionStream resource leak on stream cancellation (#21199)
Based on #21074 and #20741 I was looking for further potential use cases
of `TransformStream` `cancel()` method, so here go `CompressionStream`
and `DecompressionStream`.
Fixes #14212
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/web/14_compression.js | 10 | ||||
| -rw-r--r-- | ext/web/compression.rs | 26 |
2 files changed, 26 insertions, 10 deletions
diff --git a/ext/web/14_compression.js b/ext/web/14_compression.js index 1ec9e5462..0d3a8ebd0 100644 --- a/ext/web/14_compression.js +++ b/ext/web/14_compression.js @@ -50,9 +50,12 @@ class CompressionStream { maybeEnqueue(controller, output); }, flush(controller) { - const output = op_compression_finish(rid); + const output = op_compression_finish(rid, true); maybeEnqueue(controller, output); }, + cancel: (_reason) => { + op_compression_finish(rid, false); + }, }); this[webidl.brand] = webidl.brand; @@ -109,9 +112,12 @@ class DecompressionStream { maybeEnqueue(controller, output); }, flush(controller) { - const output = op_compression_finish(rid); + const output = op_compression_finish(rid, true); maybeEnqueue(controller, output); }, + cancel: (_reason) => { + op_compression_finish(rid, false); + }, }); this[webidl.brand] = webidl.brand; diff --git a/ext/web/compression.rs b/ext/web/compression.rs index 0829af8e5..4f4d90cbf 100644 --- a/ext/web/compression.rs +++ b/ext/web/compression.rs @@ -116,25 +116,35 @@ pub fn op_compression_write( pub fn op_compression_finish( state: &mut OpState, #[smi] rid: ResourceId, + report_errors: bool, ) -> Result<ToJsBuffer, AnyError> { let resource = state.resource_table.take::<CompressionResource>(rid)?; let resource = Rc::try_unwrap(resource).unwrap(); let inner = resource.0.into_inner(); - let out: Vec<u8> = match inner { + let out = match inner { Inner::DeflateDecoder(d) => { - d.finish().map_err(|e| type_error(e.to_string()))? + d.finish().map_err(|e| type_error(e.to_string())) } Inner::DeflateEncoder(d) => { - d.finish().map_err(|e| type_error(e.to_string()))? + d.finish().map_err(|e| type_error(e.to_string())) } Inner::DeflateRawDecoder(d) => { - d.finish().map_err(|e| type_error(e.to_string()))? + d.finish().map_err(|e| type_error(e.to_string())) } Inner::DeflateRawEncoder(d) => { - d.finish().map_err(|e| type_error(e.to_string()))? + d.finish().map_err(|e| type_error(e.to_string())) } - Inner::GzDecoder(d) => d.finish().map_err(|e| type_error(e.to_string()))?, - Inner::GzEncoder(d) => d.finish().map_err(|e| type_error(e.to_string()))?, + Inner::GzDecoder(d) => d.finish().map_err(|e| type_error(e.to_string())), + Inner::GzEncoder(d) => d.finish().map_err(|e| type_error(e.to_string())), }; - Ok(out.into()) + match out { + Err(err) => { + if report_errors { + Err(err) + } else { + Ok(Vec::with_capacity(0).into()) + } + } + Ok(out) => Ok(out.into()), + } } |
