From 1c836588d91c1b8bdccf8aa52d27e3910ace2520 Mon Sep 17 00:00:00 2001 From: devgianlu Date: Sat, 1 Mar 2025 18:03:36 +0100 Subject: [PATCH] LibWeb: Add some compression WPT tests These are relevant for the next commits. --- .../compression-bad-chunks.tentative.any.txt | 27 +++++++ .../compression-large-flush-output.any.txt | 8 ++ ...pression-multiple-chunks.tentative.any.txt | 50 +++++++++++++ ...ecompression-split-chunk.tentative.any.txt | 50 +++++++++++++ .../compression-bad-chunks.tentative.any.html | 15 ++++ .../compression-bad-chunks.tentative.any.js | 74 +++++++++++++++++++ .../compression-large-flush-output.any.html | 16 ++++ .../compression-large-flush-output.any.js | 41 ++++++++++ ...ression-multiple-chunks.tentative.any.html | 15 ++++ ...mpression-multiple-chunks.tentative.any.js | 67 +++++++++++++++++ ...compression-split-chunk.tentative.any.html | 15 ++++ ...decompression-split-chunk.tentative.any.js | 53 +++++++++++++ .../resources/concatenate-stream.js | 25 +++++++ .../third_party/pako/pako_inflate.min.js | 1 + 14 files changed, 457 insertions(+) create mode 100644 Tests/LibWeb/Text/expected/wpt-import/compression/compression-bad-chunks.tentative.any.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/compression/compression-large-flush-output.any.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/compression/compression-multiple-chunks.tentative.any.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/compression/decompression-split-chunk.tentative.any.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/compression/compression-bad-chunks.tentative.any.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/compression/compression-bad-chunks.tentative.any.js create mode 100644 Tests/LibWeb/Text/input/wpt-import/compression/compression-large-flush-output.any.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/compression/compression-large-flush-output.any.js create mode 100644 Tests/LibWeb/Text/input/wpt-import/compression/compression-multiple-chunks.tentative.any.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/compression/compression-multiple-chunks.tentative.any.js create mode 100644 Tests/LibWeb/Text/input/wpt-import/compression/decompression-split-chunk.tentative.any.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/compression/decompression-split-chunk.tentative.any.js create mode 100644 Tests/LibWeb/Text/input/wpt-import/compression/resources/concatenate-stream.js create mode 100644 Tests/LibWeb/Text/input/wpt-import/compression/third_party/pako/pako_inflate.min.js diff --git a/Tests/LibWeb/Text/expected/wpt-import/compression/compression-bad-chunks.tentative.any.txt b/Tests/LibWeb/Text/expected/wpt-import/compression/compression-bad-chunks.tentative.any.txt new file mode 100644 index 00000000000..2c8da675484 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/compression/compression-bad-chunks.tentative.any.txt @@ -0,0 +1,27 @@ +Harness status: Error + +Found 21 tests + +15 Pass +6 Fail +Pass chunk of type undefined should error the stream for gzip +Pass chunk of type undefined should error the stream for deflate +Pass chunk of type undefined should error the stream for deflate-raw +Pass chunk of type null should error the stream for gzip +Pass chunk of type null should error the stream for deflate +Pass chunk of type null should error the stream for deflate-raw +Pass chunk of type numeric should error the stream for gzip +Pass chunk of type numeric should error the stream for deflate +Pass chunk of type numeric should error the stream for deflate-raw +Pass chunk of type object, not BufferSource should error the stream for gzip +Pass chunk of type object, not BufferSource should error the stream for deflate +Pass chunk of type object, not BufferSource should error the stream for deflate-raw +Pass chunk of type array should error the stream for gzip +Pass chunk of type array should error the stream for deflate +Pass chunk of type array should error the stream for deflate-raw +Fail chunk of type SharedArrayBuffer should error the stream for gzip +Fail chunk of type SharedArrayBuffer should error the stream for deflate +Fail chunk of type SharedArrayBuffer should error the stream for deflate-raw +Fail chunk of type shared Uint8Array should error the stream for gzip +Fail chunk of type shared Uint8Array should error the stream for deflate +Fail chunk of type shared Uint8Array should error the stream for deflate-raw \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/compression/compression-large-flush-output.any.txt b/Tests/LibWeb/Text/expected/wpt-import/compression/compression-large-flush-output.any.txt new file mode 100644 index 00000000000..a3ab97e1de4 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/compression/compression-large-flush-output.any.txt @@ -0,0 +1,8 @@ +Harness status: OK + +Found 3 tests + +3 Fail +Fail deflate compression with large flush output +Fail gzip compression with large flush output +Fail deflate-raw compression with large flush output \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/compression/compression-multiple-chunks.tentative.any.txt b/Tests/LibWeb/Text/expected/wpt-import/compression/compression-multiple-chunks.tentative.any.txt new file mode 100644 index 00000000000..b0453770210 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/compression/compression-multiple-chunks.tentative.any.txt @@ -0,0 +1,50 @@ +Harness status: OK + +Found 45 tests + +45 Pass +Pass compressing 2 chunks with deflate should work +Pass compressing 2 chunks with gzip should work +Pass compressing 2 chunks with deflate-raw should work +Pass compressing 3 chunks with deflate should work +Pass compressing 3 chunks with gzip should work +Pass compressing 3 chunks with deflate-raw should work +Pass compressing 4 chunks with deflate should work +Pass compressing 4 chunks with gzip should work +Pass compressing 4 chunks with deflate-raw should work +Pass compressing 5 chunks with deflate should work +Pass compressing 5 chunks with gzip should work +Pass compressing 5 chunks with deflate-raw should work +Pass compressing 6 chunks with deflate should work +Pass compressing 6 chunks with gzip should work +Pass compressing 6 chunks with deflate-raw should work +Pass compressing 7 chunks with deflate should work +Pass compressing 7 chunks with gzip should work +Pass compressing 7 chunks with deflate-raw should work +Pass compressing 8 chunks with deflate should work +Pass compressing 8 chunks with gzip should work +Pass compressing 8 chunks with deflate-raw should work +Pass compressing 9 chunks with deflate should work +Pass compressing 9 chunks with gzip should work +Pass compressing 9 chunks with deflate-raw should work +Pass compressing 10 chunks with deflate should work +Pass compressing 10 chunks with gzip should work +Pass compressing 10 chunks with deflate-raw should work +Pass compressing 11 chunks with deflate should work +Pass compressing 11 chunks with gzip should work +Pass compressing 11 chunks with deflate-raw should work +Pass compressing 12 chunks with deflate should work +Pass compressing 12 chunks with gzip should work +Pass compressing 12 chunks with deflate-raw should work +Pass compressing 13 chunks with deflate should work +Pass compressing 13 chunks with gzip should work +Pass compressing 13 chunks with deflate-raw should work +Pass compressing 14 chunks with deflate should work +Pass compressing 14 chunks with gzip should work +Pass compressing 14 chunks with deflate-raw should work +Pass compressing 15 chunks with deflate should work +Pass compressing 15 chunks with gzip should work +Pass compressing 15 chunks with deflate-raw should work +Pass compressing 16 chunks with deflate should work +Pass compressing 16 chunks with gzip should work +Pass compressing 16 chunks with deflate-raw should work \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/compression/decompression-split-chunk.tentative.any.txt b/Tests/LibWeb/Text/expected/wpt-import/compression/decompression-split-chunk.tentative.any.txt new file mode 100644 index 00000000000..eb7282ce1e1 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/compression/decompression-split-chunk.tentative.any.txt @@ -0,0 +1,50 @@ +Harness status: Error + +Found 45 tests + +45 Fail +Fail decompressing splitted chunk into pieces of size 1 should work in deflate +Fail decompressing splitted chunk into pieces of size 1 should work in gzip +Fail decompressing splitted chunk into pieces of size 1 should work in deflate-raw +Fail decompressing splitted chunk into pieces of size 2 should work in deflate +Fail decompressing splitted chunk into pieces of size 2 should work in gzip +Fail decompressing splitted chunk into pieces of size 2 should work in deflate-raw +Fail decompressing splitted chunk into pieces of size 3 should work in deflate +Fail decompressing splitted chunk into pieces of size 3 should work in gzip +Fail decompressing splitted chunk into pieces of size 3 should work in deflate-raw +Fail decompressing splitted chunk into pieces of size 4 should work in deflate +Fail decompressing splitted chunk into pieces of size 4 should work in gzip +Fail decompressing splitted chunk into pieces of size 4 should work in deflate-raw +Fail decompressing splitted chunk into pieces of size 5 should work in deflate +Fail decompressing splitted chunk into pieces of size 5 should work in gzip +Fail decompressing splitted chunk into pieces of size 5 should work in deflate-raw +Fail decompressing splitted chunk into pieces of size 6 should work in deflate +Fail decompressing splitted chunk into pieces of size 6 should work in gzip +Fail decompressing splitted chunk into pieces of size 6 should work in deflate-raw +Fail decompressing splitted chunk into pieces of size 7 should work in deflate +Fail decompressing splitted chunk into pieces of size 7 should work in gzip +Fail decompressing splitted chunk into pieces of size 7 should work in deflate-raw +Fail decompressing splitted chunk into pieces of size 8 should work in deflate +Fail decompressing splitted chunk into pieces of size 8 should work in gzip +Fail decompressing splitted chunk into pieces of size 8 should work in deflate-raw +Fail decompressing splitted chunk into pieces of size 9 should work in deflate +Fail decompressing splitted chunk into pieces of size 9 should work in gzip +Fail decompressing splitted chunk into pieces of size 9 should work in deflate-raw +Fail decompressing splitted chunk into pieces of size 10 should work in deflate +Fail decompressing splitted chunk into pieces of size 10 should work in gzip +Fail decompressing splitted chunk into pieces of size 10 should work in deflate-raw +Fail decompressing splitted chunk into pieces of size 11 should work in deflate +Fail decompressing splitted chunk into pieces of size 11 should work in gzip +Fail decompressing splitted chunk into pieces of size 11 should work in deflate-raw +Fail decompressing splitted chunk into pieces of size 12 should work in deflate +Fail decompressing splitted chunk into pieces of size 12 should work in gzip +Fail decompressing splitted chunk into pieces of size 12 should work in deflate-raw +Fail decompressing splitted chunk into pieces of size 13 should work in deflate +Fail decompressing splitted chunk into pieces of size 13 should work in gzip +Fail decompressing splitted chunk into pieces of size 13 should work in deflate-raw +Fail decompressing splitted chunk into pieces of size 14 should work in deflate +Fail decompressing splitted chunk into pieces of size 14 should work in gzip +Fail decompressing splitted chunk into pieces of size 14 should work in deflate-raw +Fail decompressing splitted chunk into pieces of size 15 should work in deflate +Fail decompressing splitted chunk into pieces of size 15 should work in gzip +Fail decompressing splitted chunk into pieces of size 15 should work in deflate-raw \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/compression/compression-bad-chunks.tentative.any.html b/Tests/LibWeb/Text/input/wpt-import/compression/compression-bad-chunks.tentative.any.html new file mode 100644 index 00000000000..08632f26c4d --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/compression/compression-bad-chunks.tentative.any.html @@ -0,0 +1,15 @@ + + + + + + + +
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/compression/compression-bad-chunks.tentative.any.js b/Tests/LibWeb/Text/input/wpt-import/compression/compression-bad-chunks.tentative.any.js new file mode 100644 index 00000000000..2d0b5684733 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/compression/compression-bad-chunks.tentative.any.js @@ -0,0 +1,74 @@ +// META: global=window,worker,shadowrealm + +'use strict'; + +const badChunks = [ + { + name: 'undefined', + value: undefined + }, + { + name: 'null', + value: null + }, + { + name: 'numeric', + value: 3.14 + }, + { + name: 'object, not BufferSource', + value: {} + }, + { + name: 'array', + value: [65] + }, + { + name: 'SharedArrayBuffer', + // Use a getter to postpone construction so that all tests don't fail where + // SharedArrayBuffer is not yet implemented. + get value() { + // See https://github.com/whatwg/html/issues/5380 for why not `new SharedArrayBuffer()` + return new WebAssembly.Memory({ shared:true, initial:1, maximum:1 }).buffer; + } + }, + { + name: 'shared Uint8Array', + get value() { + // See https://github.com/whatwg/html/issues/5380 for why not `new SharedArrayBuffer()` + return new Uint8Array(new WebAssembly.Memory({ shared:true, initial:1, maximum:1 }).buffer) + } + }, +]; + +for (const chunk of badChunks) { + promise_test(async t => { + const cs = new CompressionStream('gzip'); + const reader = cs.readable.getReader(); + const writer = cs.writable.getWriter(); + const writePromise = writer.write(chunk.value); + const readPromise = reader.read(); + await promise_rejects_js(t, TypeError, writePromise, 'write should reject'); + await promise_rejects_js(t, TypeError, readPromise, 'read should reject'); + }, `chunk of type ${chunk.name} should error the stream for gzip`); + + promise_test(async t => { + const cs = new CompressionStream('deflate'); + const reader = cs.readable.getReader(); + const writer = cs.writable.getWriter(); + const writePromise = writer.write(chunk.value); + const readPromise = reader.read(); + await promise_rejects_js(t, TypeError, writePromise, 'write should reject'); + await promise_rejects_js(t, TypeError, readPromise, 'read should reject'); + }, `chunk of type ${chunk.name} should error the stream for deflate`); + + promise_test(async t => { + const cs = new CompressionStream('deflate-raw'); + const reader = cs.readable.getReader(); + const writer = cs.writable.getWriter(); + const writePromise = writer.write(chunk.value); + const readPromise = reader.read(); + await promise_rejects_js(t, TypeError, writePromise, 'write should reject'); + await promise_rejects_js(t, TypeError, readPromise, 'read should reject'); + }, `chunk of type ${chunk.name} should error the stream for deflate-raw`); +} diff --git a/Tests/LibWeb/Text/input/wpt-import/compression/compression-large-flush-output.any.html b/Tests/LibWeb/Text/input/wpt-import/compression/compression-large-flush-output.any.html new file mode 100644 index 00000000000..ebc301ce7e5 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/compression/compression-large-flush-output.any.html @@ -0,0 +1,16 @@ + + + + + + + + +
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/compression/compression-large-flush-output.any.js b/Tests/LibWeb/Text/input/wpt-import/compression/compression-large-flush-output.any.js new file mode 100644 index 00000000000..6afcb4d5287 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/compression/compression-large-flush-output.any.js @@ -0,0 +1,41 @@ +// META: global=window,worker,shadowrealm +// META: script=third_party/pako/pako_inflate.min.js +// META: script=resources/concatenate-stream.js +// META: timeout=long + +'use strict'; + +// This test verifies that a large flush output will not truncate the +// final results. + +async function compressData(chunk, format) { + const cs = new CompressionStream(format); + const writer = cs.writable.getWriter(); + writer.write(chunk); + writer.close(); + return await concatenateStream(cs.readable); +} + +// JSON-encoded array of 10 thousands numbers ("[0,1,2,...]"). This produces 48_891 bytes of data. +const fullData = new TextEncoder().encode(JSON.stringify(Array.from({ length: 10_000 }, (_, i) => i))); +const data = fullData.subarray(0, 35_579); +const expectedValue = data; + +promise_test(async t => { + const compressedData = await compressData(data, 'deflate'); + // decompress with pako, and check that we got the same result as our original string + assert_array_equals(expectedValue, pako.inflate(compressedData), 'value should match'); +}, `deflate compression with large flush output`); + +promise_test(async t => { + const compressedData = await compressData(data, 'gzip'); + // decompress with pako, and check that we got the same result as our original string + assert_array_equals(expectedValue, pako.inflate(compressedData), 'value should match'); +}, `gzip compression with large flush output`); + +promise_test(async t => { + const compressedData = await compressData(data, 'deflate-raw'); + // decompress with pako, and check that we got the same result as our original string + assert_array_equals(expectedValue, pako.inflateRaw(compressedData), 'value should match'); +}, `deflate-raw compression with large flush output`); + diff --git a/Tests/LibWeb/Text/input/wpt-import/compression/compression-multiple-chunks.tentative.any.html b/Tests/LibWeb/Text/input/wpt-import/compression/compression-multiple-chunks.tentative.any.html new file mode 100644 index 00000000000..b6bbf8085fb --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/compression/compression-multiple-chunks.tentative.any.html @@ -0,0 +1,15 @@ + + + + + + + +
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/compression/compression-multiple-chunks.tentative.any.js b/Tests/LibWeb/Text/input/wpt-import/compression/compression-multiple-chunks.tentative.any.js new file mode 100644 index 00000000000..28a90e5ca53 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/compression/compression-multiple-chunks.tentative.any.js @@ -0,0 +1,67 @@ +// META: global=window,worker,shadowrealm +// META: script=third_party/pako/pako_inflate.min.js +// META: timeout=long + +'use strict'; + +// This test asserts that compressing multiple chunks should work. + +// Example: ('Hello', 3) => TextEncoder().encode('HelloHelloHello') +function makeExpectedChunk(input, numberOfChunks) { + const expectedChunk = input.repeat(numberOfChunks); + return new TextEncoder().encode(expectedChunk); +} + +// Example: ('Hello', 3, 'deflate') => compress ['Hello', 'Hello', Hello'] +async function compressMultipleChunks(input, numberOfChunks, format) { + const cs = new CompressionStream(format); + const writer = cs.writable.getWriter(); + const chunk = new TextEncoder().encode(input); + for (let i = 0; i < numberOfChunks; ++i) { + writer.write(chunk); + } + const closePromise = writer.close(); + const out = []; + const reader = cs.readable.getReader(); + let totalSize = 0; + while (true) { + const { value, done } = await reader.read(); + if (done) + break; + out.push(value); + totalSize += value.byteLength; + } + await closePromise; + const concatenated = new Uint8Array(totalSize); + let offset = 0; + for (const array of out) { + concatenated.set(array, offset); + offset += array.byteLength; + } + return concatenated; +} + +const hello = 'Hello'; + +for (let numberOfChunks = 2; numberOfChunks <= 16; ++numberOfChunks) { + promise_test(async t => { + const compressedData = await compressMultipleChunks(hello, numberOfChunks, 'deflate'); + const expectedValue = makeExpectedChunk(hello, numberOfChunks); + // decompress with pako, and check that we got the same result as our original string + assert_array_equals(expectedValue, pako.inflate(compressedData), 'value should match'); + }, `compressing ${numberOfChunks} chunks with deflate should work`); + + promise_test(async t => { + const compressedData = await compressMultipleChunks(hello, numberOfChunks, 'gzip'); + const expectedValue = makeExpectedChunk(hello, numberOfChunks); + // decompress with pako, and check that we got the same result as our original string + assert_array_equals(expectedValue, pako.inflate(compressedData), 'value should match'); + }, `compressing ${numberOfChunks} chunks with gzip should work`); + + promise_test(async t => { + const compressedData = await compressMultipleChunks(hello, numberOfChunks, 'deflate-raw'); + const expectedValue = makeExpectedChunk(hello, numberOfChunks); + // decompress with pako, and check that we got the same result as our original string + assert_array_equals(expectedValue, pako.inflateRaw(compressedData), 'value should match'); + }, `compressing ${numberOfChunks} chunks with deflate-raw should work`); +} diff --git a/Tests/LibWeb/Text/input/wpt-import/compression/decompression-split-chunk.tentative.any.html b/Tests/LibWeb/Text/input/wpt-import/compression/decompression-split-chunk.tentative.any.html new file mode 100644 index 00000000000..727047f6b32 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/compression/decompression-split-chunk.tentative.any.html @@ -0,0 +1,15 @@ + + + + + + + +
+ diff --git a/Tests/LibWeb/Text/input/wpt-import/compression/decompression-split-chunk.tentative.any.js b/Tests/LibWeb/Text/input/wpt-import/compression/decompression-split-chunk.tentative.any.js new file mode 100644 index 00000000000..eb12c2a2360 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/compression/decompression-split-chunk.tentative.any.js @@ -0,0 +1,53 @@ +// META: global=window,worker,shadowrealm + +'use strict'; + +const compressedBytesWithDeflate = new Uint8Array([120, 156, 75, 173, 40, 72, 77, 46, 73, 77, 81, 200, 47, 45, 41, 40, 45, 1, 0, 48, 173, 6, 36]); +const compressedBytesWithGzip = new Uint8Array([31, 139, 8, 0, 0, 0, 0, 0, 0, 3, 75, 173, 40, 72, 77, 46, 73, 77, 81, 200, 47, 45, 41, 40, 45, 1, 0, 176, 1, 57, 179, 15, 0, 0, 0]); +const compressedBytesWithDeflateRaw = new Uint8Array([ + 0x4b, 0xad, 0x28, 0x48, 0x4d, 0x2e, 0x49, 0x4d, 0x51, 0xc8, + 0x2f, 0x2d, 0x29, 0x28, 0x2d, 0x01, 0x00, +]); +const expectedChunkValue = new TextEncoder().encode('expected output'); + +async function decompressArrayBuffer(input, format, chunkSize) { + const ds = new DecompressionStream(format); + const reader = ds.readable.getReader(); + const writer = ds.writable.getWriter(); + for (let beginning = 0; beginning < input.length; beginning += chunkSize) { + writer.write(input.slice(beginning, beginning + chunkSize)); + } + writer.close(); + const out = []; + let totalSize = 0; + while (true) { + const { value, done } = await reader.read(); + if (done) break; + out.push(value); + totalSize += value.byteLength; + } + const concatenated = new Uint8Array(totalSize); + let offset = 0; + for (const array of out) { + concatenated.set(array, offset); + offset += array.byteLength; + } + return concatenated; +} + +for (let chunkSize = 1; chunkSize < 16; ++chunkSize) { + promise_test(async t => { + const decompressedData = await decompressArrayBuffer(compressedBytesWithDeflate, 'deflate', chunkSize); + assert_array_equals(decompressedData, expectedChunkValue, "value should match"); + }, `decompressing splitted chunk into pieces of size ${chunkSize} should work in deflate`); + + promise_test(async t => { + const decompressedData = await decompressArrayBuffer(compressedBytesWithGzip, 'gzip', chunkSize); + assert_array_equals(decompressedData, expectedChunkValue, "value should match"); + }, `decompressing splitted chunk into pieces of size ${chunkSize} should work in gzip`); + + promise_test(async t => { + const decompressedData = await decompressArrayBuffer(compressedBytesWithDeflateRaw, 'deflate-raw', chunkSize); + assert_array_equals(decompressedData, expectedChunkValue, "value should match"); + }, `decompressing splitted chunk into pieces of size ${chunkSize} should work in deflate-raw`); +} diff --git a/Tests/LibWeb/Text/input/wpt-import/compression/resources/concatenate-stream.js b/Tests/LibWeb/Text/input/wpt-import/compression/resources/concatenate-stream.js new file mode 100644 index 00000000000..a35bb1416e7 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/compression/resources/concatenate-stream.js @@ -0,0 +1,25 @@ +'use strict'; + +// Read all the chunks from a stream that returns BufferSource objects and +// concatenate them into a single Uint8Array. +async function concatenateStream(readableStream) { + const reader = readableStream.getReader(); + let totalSize = 0; + const buffers = []; + while (true) { + const { value, done } = await reader.read(); + if (done) { + break; + } + buffers.push(value); + totalSize += value.byteLength; + } + reader.releaseLock(); + const concatenated = new Uint8Array(totalSize); + let offset = 0; + for (const buffer of buffers) { + concatenated.set(buffer, offset); + offset += buffer.byteLength; + } + return concatenated; +} diff --git a/Tests/LibWeb/Text/input/wpt-import/compression/third_party/pako/pako_inflate.min.js b/Tests/LibWeb/Text/input/wpt-import/compression/third_party/pako/pako_inflate.min.js new file mode 100644 index 00000000000..a191a78a895 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/compression/third_party/pako/pako_inflate.min.js @@ -0,0 +1 @@ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).pako=e()}}(function(){return function r(o,s,f){function l(t,e){if(!s[t]){if(!o[t]){var i="function"==typeof require&&require;if(!e&&i)return i(t,!0);if(d)return d(t,!0);var n=new Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}var a=s[t]={exports:{}};o[t][0].call(a.exports,function(e){return l(o[t][1][e]||e)},a,a.exports,r,o,s,f)}return s[t].exports}for(var d="function"==typeof require&&require,e=0;e>>6:(i<65536?t[r++]=224|i>>>12:(t[r++]=240|i>>>18,t[r++]=128|i>>>12&63),t[r++]=128|i>>>6&63),t[r++]=128|63&i);return t},i.buf2binstring=function(e){return d(e,e.length)},i.binstring2buf=function(e){for(var t=new f.Buf8(e.length),i=0,n=t.length;i>10&1023,s[n++]=56320|1023&a)}return d(s,n)},i.utf8border=function(e,t){var i;for((t=t||e.length)>e.length&&(t=e.length),i=t-1;0<=i&&128==(192&e[i]);)i--;return i<0?t:0===i?t:i+l[e[i]]>t?i:t}},{"./common":1}],3:[function(e,t,i){"use strict";t.exports=function(e,t,i,n){for(var a=65535&e|0,r=e>>>16&65535|0,o=0;0!==i;){for(i-=o=2e3>>1:e>>>1;t[i]=e}return t}();t.exports=function(e,t,i,n){var a=s,r=n+i;e^=-1;for(var o=n;o>>8^a[255&(e^t[o])];return-1^e}},{}],6:[function(e,t,i){"use strict";t.exports=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}},{}],7:[function(e,t,i){"use strict";t.exports=function(e,t){var i,n,a,r,o,s,f,l,d,c,u,h,b,m,w,k,_,g,v,p,x,y,S,E,Z;i=e.state,n=e.next_in,E=e.input,a=n+(e.avail_in-5),r=e.next_out,Z=e.output,o=r-(t-e.avail_out),s=r+(e.avail_out-257),f=i.dmax,l=i.wsize,d=i.whave,c=i.wnext,u=i.window,h=i.hold,b=i.bits,m=i.lencode,w=i.distcode,k=(1<>>=v=g>>>24,b-=v,0===(v=g>>>16&255))Z[r++]=65535&g;else{if(!(16&v)){if(0==(64&v)){g=m[(65535&g)+(h&(1<>>=v,b-=v),b<15&&(h+=E[n++]<>>=v=g>>>24,b-=v,!(16&(v=g>>>16&255))){if(0==(64&v)){g=w[(65535&g)+(h&(1<>>=v,b-=v,(v=r-o)>3,h&=(1<<(b-=p<<3))-1,e.next_in=n,e.next_out=r,e.avail_in=n>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function r(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new z.Buf16(320),this.work=new z.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function o(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=F,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new z.Buf32(n),t.distcode=t.distdyn=new z.Buf32(a),t.sane=1,t.back=-1,T):U}function s(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,o(e)):U}function f(e,t){var i,n;return e&&e.state?(n=e.state,t<0?(i=0,t=-t):(i=1+(t>>4),t<48&&(t&=15)),t&&(t<8||15=r.wsize?(z.arraySet(r.window,t,i-r.wsize,r.wsize,0),r.wnext=0,r.whave=r.wsize):(n<(a=r.wsize-r.wnext)&&(a=n),z.arraySet(r.window,t,i-n,a,r.wnext),(n-=a)?(z.arraySet(r.window,t,i-n,n,0),r.wnext=n,r.whave=r.wsize):(r.wnext+=a,r.wnext===r.wsize&&(r.wnext=0),r.whave>>8&255,i.check=N(i.check,B,2,0),d=l=0,i.mode=2;break}if(i.flags=0,i.head&&(i.head.done=!1),!(1&i.wrap)||(((255&l)<<8)+(l>>8))%31){e.msg="incorrect header check",i.mode=30;break}if(8!=(15&l)){e.msg="unknown compression method",i.mode=30;break}if(d-=4,x=8+(15&(l>>>=4)),0===i.wbits)i.wbits=x;else if(x>i.wbits){e.msg="invalid window size",i.mode=30;break}i.dmax=1<>8&1),512&i.flags&&(B[0]=255&l,B[1]=l>>>8&255,i.check=N(i.check,B,2,0)),d=l=0,i.mode=3;case 3:for(;d<32;){if(0===s)break e;s--,l+=n[r++]<>>8&255,B[2]=l>>>16&255,B[3]=l>>>24&255,i.check=N(i.check,B,4,0)),d=l=0,i.mode=4;case 4:for(;d<16;){if(0===s)break e;s--,l+=n[r++]<>8),512&i.flags&&(B[0]=255&l,B[1]=l>>>8&255,i.check=N(i.check,B,2,0)),d=l=0,i.mode=5;case 5:if(1024&i.flags){for(;d<16;){if(0===s)break e;s--,l+=n[r++]<>>8&255,i.check=N(i.check,B,2,0)),d=l=0}else i.head&&(i.head.extra=null);i.mode=6;case 6:if(1024&i.flags&&(s<(h=i.length)&&(h=s),h&&(i.head&&(x=i.head.extra_len-i.length,i.head.extra||(i.head.extra=new Array(i.head.extra_len)),z.arraySet(i.head.extra,n,r,h,x)),512&i.flags&&(i.check=N(i.check,n,h,r)),s-=h,r+=h,i.length-=h),i.length))break e;i.length=0,i.mode=7;case 7:if(2048&i.flags){if(0===s)break e;for(h=0;x=n[r+h++],i.head&&x&&i.length<65536&&(i.head.name+=String.fromCharCode(x)),x&&h>9&1,i.head.done=!0),e.adler=i.check=0,i.mode=12;break;case 10:for(;d<32;){if(0===s)break e;s--,l+=n[r++]<>>=7&d,d-=7&d,i.mode=27;break}for(;d<3;){if(0===s)break e;s--,l+=n[r++]<>>=1)){case 0:i.mode=14;break;case 1:if(H(i),i.mode=20,6!==t)break;l>>>=2,d-=2;break e;case 2:i.mode=17;break;case 3:e.msg="invalid block type",i.mode=30}l>>>=2,d-=2;break;case 14:for(l>>>=7&d,d-=7&d;d<32;){if(0===s)break e;s--,l+=n[r++]<>>16^65535)){e.msg="invalid stored block lengths",i.mode=30;break}if(i.length=65535&l,d=l=0,i.mode=15,6===t)break e;case 15:i.mode=16;case 16:if(h=i.length){if(s>>=5,d-=5,i.ndist=1+(31&l),l>>>=5,d-=5,i.ncode=4+(15&l),l>>>=4,d-=4,286>>=3,d-=3}for(;i.have<19;)i.lens[A[i.have++]]=0;if(i.lencode=i.lendyn,i.lenbits=7,S={bits:i.lenbits},y=C(0,i.lens,0,19,i.lencode,0,i.work,S),i.lenbits=S.bits,y){e.msg="invalid code lengths set",i.mode=30;break}i.have=0,i.mode=19;case 19:for(;i.have>>16&255,_=65535&Z,!((w=Z>>>24)<=d);){if(0===s)break e;s--,l+=n[r++]<>>=w,d-=w,i.lens[i.have++]=_;else{if(16===_){for(E=w+2;d>>=w,d-=w,0===i.have){e.msg="invalid bit length repeat",i.mode=30;break}x=i.lens[i.have-1],h=3+(3&l),l>>>=2,d-=2}else if(17===_){for(E=w+3;d>>=w)),l>>>=3,d-=3}else{for(E=w+7;d>>=w)),l>>>=7,d-=7}if(i.have+h>i.nlen+i.ndist){e.msg="invalid bit length repeat",i.mode=30;break}for(;h--;)i.lens[i.have++]=x}}if(30===i.mode)break;if(0===i.lens[256]){e.msg="invalid code -- missing end-of-block",i.mode=30;break}if(i.lenbits=9,S={bits:i.lenbits},y=C(I,i.lens,0,i.nlen,i.lencode,0,i.work,S),i.lenbits=S.bits,y){e.msg="invalid literal/lengths set",i.mode=30;break}if(i.distbits=6,i.distcode=i.distdyn,S={bits:i.distbits},y=C(D,i.lens,i.nlen,i.ndist,i.distcode,0,i.work,S),i.distbits=S.bits,y){e.msg="invalid distances set",i.mode=30;break}if(i.mode=20,6===t)break e;case 20:i.mode=21;case 21:if(6<=s&&258<=f){e.next_out=o,e.avail_out=f,e.next_in=r,e.avail_in=s,i.hold=l,i.bits=d,O(e,u),o=e.next_out,a=e.output,f=e.avail_out,r=e.next_in,n=e.input,s=e.avail_in,l=i.hold,d=i.bits,12===i.mode&&(i.back=-1);break}for(i.back=0;k=(Z=i.lencode[l&(1<>>16&255,_=65535&Z,!((w=Z>>>24)<=d);){if(0===s)break e;s--,l+=n[r++]<>g)])>>>16&255,_=65535&Z,!(g+(w=Z>>>24)<=d);){if(0===s)break e;s--,l+=n[r++]<>>=g,d-=g,i.back+=g}if(l>>>=w,d-=w,i.back+=w,i.length=_,0===k){i.mode=26;break}if(32&k){i.back=-1,i.mode=12;break}if(64&k){e.msg="invalid literal/length code",i.mode=30;break}i.extra=15&k,i.mode=22;case 22:if(i.extra){for(E=i.extra;d>>=i.extra,d-=i.extra,i.back+=i.extra}i.was=i.length,i.mode=23;case 23:for(;k=(Z=i.distcode[l&(1<>>16&255,_=65535&Z,!((w=Z>>>24)<=d);){if(0===s)break e;s--,l+=n[r++]<>g)])>>>16&255,_=65535&Z,!(g+(w=Z>>>24)<=d);){if(0===s)break e;s--,l+=n[r++]<>>=g,d-=g,i.back+=g}if(l>>>=w,d-=w,i.back+=w,64&k){e.msg="invalid distance code",i.mode=30;break}i.offset=_,i.extra=15&k,i.mode=24;case 24:if(i.extra){for(E=i.extra;d>>=i.extra,d-=i.extra,i.back+=i.extra}if(i.offset>i.dmax){e.msg="invalid distance too far back",i.mode=30;break}i.mode=25;case 25:if(0===f)break e;if(h=u-f,i.offset>h){if((h=i.offset-h)>i.whave&&i.sane){e.msg="invalid distance too far back",i.mode=30;break}h>i.wnext?(h-=i.wnext,b=i.wsize-h):b=i.wnext-h,h>i.length&&(h=i.length),m=i.window}else m=a,b=o-i.offset,h=i.length;for(fh?(m=O[C+o[g]],w=A[z+o[g]]):(m=96,w=0),f=1<<_-S,v=l=1<>S)+(l-=f)]=b<<24|m<<16|w|0,0!==l;);for(f=1<<_-1;B&f;)f>>=1;if(0!==f?(B&=f-1,B+=f):B=0,g++,0==--R[_]){if(_===p)break;_=t[i+o[g]]}if(x<_&&(B&c)!==d){for(0===S&&(S=x),u+=v,E=1<<(y=_-S);y+S