mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 15:49:44 -05:00
fix(ext/node/ops/zlib/brotli): Allow decompressing more than 4096 bytes (#20301)
Fixes https://github.com/denoland/deno/issues/19816 In that issue, I suggest switching over the other brotli functionality to the Rust API provided by the `brotli` crate. Here, I only do that with the `brotli_decompress` function to fix the bug with buffers longer than 4096 bytes.
This commit is contained in:
parent
4a11603c76
commit
a9cc4631ca
2 changed files with 13 additions and 30 deletions
|
@ -62,6 +62,13 @@ Deno.test("brotli compression", async () => {
|
|||
}
|
||||
});
|
||||
|
||||
Deno.test("brotli end-to-end with 4097 bytes", () => {
|
||||
const a = "a".repeat(4097);
|
||||
const compressed = brotliCompressSync(a);
|
||||
const decompressed = brotliDecompressSync(compressed);
|
||||
assertEquals(decompressed.toString(), a);
|
||||
});
|
||||
|
||||
Deno.test(
|
||||
"zlib create deflate with dictionary",
|
||||
{ sanitizeResources: false },
|
||||
|
|
|
@ -4,6 +4,7 @@ use brotli::ffi::compressor::*;
|
|||
use brotli::ffi::decompressor::ffi::interface::BrotliDecoderResult;
|
||||
use brotli::ffi::decompressor::ffi::BrotliDecoderState;
|
||||
use brotli::ffi::decompressor::*;
|
||||
use brotli::Decompressor;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
|
@ -11,6 +12,7 @@ use deno_core::JsBuffer;
|
|||
use deno_core::OpState;
|
||||
use deno_core::Resource;
|
||||
use deno_core::ToJsBuffer;
|
||||
use std::io::Read;
|
||||
|
||||
fn encoder_mode(mode: u32) -> Result<BrotliEncoderMode, AnyError> {
|
||||
if mode > 6 {
|
||||
|
@ -214,36 +216,10 @@ pub fn op_brotli_compress_stream_end(
|
|||
}
|
||||
|
||||
fn brotli_decompress(buffer: &[u8]) -> Result<ToJsBuffer, AnyError> {
|
||||
let in_buffer = buffer.as_ptr();
|
||||
let in_size = buffer.len();
|
||||
|
||||
let mut out = vec![0u8; 4096];
|
||||
loop {
|
||||
let out_buffer = out.as_mut_ptr();
|
||||
let mut out_size = out.len();
|
||||
// SAFETY: TODO(littledivy)
|
||||
match unsafe {
|
||||
CBrotliDecoderDecompress(
|
||||
in_size,
|
||||
in_buffer,
|
||||
&mut out_size as *mut usize,
|
||||
out_buffer,
|
||||
)
|
||||
} {
|
||||
BrotliDecoderResult::BROTLI_DECODER_RESULT_SUCCESS => {
|
||||
out.truncate(out_size);
|
||||
return Ok(out.into());
|
||||
}
|
||||
BrotliDecoderResult::BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT => {
|
||||
let new_size = out.len() * 2;
|
||||
if new_size < out.len() {
|
||||
return Err(type_error("Failed to decompress"));
|
||||
}
|
||||
out.resize(new_size, 0);
|
||||
}
|
||||
_ => return Err(type_error("Failed to decompress")),
|
||||
}
|
||||
}
|
||||
let mut output = Vec::with_capacity(4096);
|
||||
let mut decompressor = Decompressor::new(buffer, buffer.len());
|
||||
decompressor.read_to_end(&mut output)?;
|
||||
Ok(output.into())
|
||||
}
|
||||
|
||||
#[op]
|
||||
|
|
Loading…
Reference in a new issue