diff options
author | Jovi De Croock <decroockjovi@gmail.com> | 2024-01-03 14:33:51 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-03 19:03:51 +0530 |
commit | f5ad15b5048ec34346cb86450c5cba0509b584db (patch) | |
tree | fcb7c0f71186e17ce688780fb0ed0880a143c2d8 | |
parent | 59cfe20f3be727096d328ecb2196478ae01447f6 (diff) |
fix(node/zlib): accept dataview and buffer in zlib bindings (#21756)
Fixes #20516
Follow up to #21747 and #21746
This tackles the last point of #20516 where certain inputs weren't
accepted in the other zlib methods
This adds the `toU8` conversion of `_brotli` to `_zlib.mjs`, when we
create the ZLibBuffer, we'll sanitize the input. I noticed that the
async had no handler for `string` input so I added that as well.
-rw-r--r-- | cli/tests/unit_node/zlib_test.ts | 30 | ||||
-rw-r--r-- | ext/node/polyfills/_zlib.mjs | 21 |
2 files changed, 48 insertions, 3 deletions
diff --git a/cli/tests/unit_node/zlib_test.ts b/cli/tests/unit_node/zlib_test.ts index 1819be268..fa94493c1 100644 --- a/cli/tests/unit_node/zlib_test.ts +++ b/cli/tests/unit_node/zlib_test.ts @@ -9,6 +9,8 @@ import { createBrotliCompress, createBrotliDecompress, createDeflate, + gzipSync, + unzipSync, } from "node:zlib"; import { Buffer } from "node:buffer"; import { createReadStream, createWriteStream } from "node:fs"; @@ -32,6 +34,13 @@ Deno.test("brotli compression async", async () => { assertEquals(decompressed.toString(), "hello world"); }); +Deno.test("gzip compression sync", { sanitizeResources: false }, () => { + const buf = Buffer.from("hello world"); + const compressed = gzipSync(buf); + const decompressed = unzipSync(compressed); + assertEquals(decompressed.toString(), "hello world"); +}); + Deno.test("brotli compression", async () => { const { promise, resolve } = Promise.withResolvers<void>(); const compress = createBrotliCompress(); @@ -125,3 +134,24 @@ Deno.test("should work with a buffer from an encoded string", () => { const decompressed = brotliDecompressSync(compressed); assertEquals(decompressed.toString(), "hello world"); }); + +Deno.test( + "zlib compression with dataview", + { sanitizeResources: false }, + () => { + const buf = Buffer.from("hello world"); + const compressed = gzipSync(new DataView(buf.buffer)); + const decompressed = unzipSync(compressed); + assertEquals(decompressed.toString(), "hello world"); + }, +); + +Deno.test("zlib compression with an encoded string", { + sanitizeResources: false, +}, () => { + const encoder = new TextEncoder(); + const buffer = encoder.encode("hello world"); + const compressed = gzipSync(buffer); + const decompressed = unzipSync(compressed); + assertEquals(decompressed.toString(), "hello world"); +}); diff --git a/ext/node/polyfills/_zlib.mjs b/ext/node/polyfills/_zlib.mjs index a66ab6d04..15a0a51e3 100644 --- a/ext/node/polyfills/_zlib.mjs +++ b/ext/node/polyfills/_zlib.mjs @@ -155,10 +155,27 @@ export const inflateRawSync = function (buffer, opts) { return zlibBufferSync(new InflateRaw(opts), buffer); }; +function sanitizeInput(input) { + if (typeof input === "string") input = Buffer.from(input); + + if ( + !Buffer.isBuffer(input) && + (input.buffer && !input.buffer.constructor === ArrayBuffer) + ) throw new TypeError("Not a string, buffer or dataview"); + + if (input.buffer) { + input = new Uint8Array(input.buffer, input.byteOffset, input.byteLength); + } + + return input; +} + function zlibBuffer(engine, buffer, callback) { var buffers = []; var nread = 0; + buffer = sanitizeInput(buffer); + engine.on("error", onError); engine.on("end", onEnd); @@ -197,9 +214,7 @@ function zlibBuffer(engine, buffer, callback) { } function zlibBufferSync(engine, buffer) { - if (typeof buffer === "string") buffer = Buffer.from(buffer); - - if (!Buffer.isBuffer(buffer)) throw new TypeError("Not a string or buffer"); + buffer = sanitizeInput(buffer); var flushFlag = engine._finishFlushFlag; |