mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 15:10:19 +00:00
LibCompress: Don't assume zlib header is available right away
Some checks are pending
CI / Lagom (false, FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (true, NO_FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Push notes / build (push) Waiting to run
Some checks are pending
CI / Lagom (false, FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (true, NO_FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Push notes / build (push) Waiting to run
Instead of checking the header in ZlibDecompressor::create(), we now check it in read_some() when it is called for the first time. This resolves a FIXME in the new DecompressionStream implementation.
This commit is contained in:
parent
be09893fa7
commit
135daeb8bb
Notes:
github-actions[bot]
2024-11-19 00:56:46 +00:00
Author: https://github.com/vkoskiv Commit: https://github.com/LadybirdBrowser/ladybird/commit/135daeb8bb2 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2427 Reviewed-by: https://github.com/trflynn89 ✅
6 changed files with 45 additions and 24 deletions
|
@ -17,31 +17,35 @@ namespace Compress {
|
|||
|
||||
ErrorOr<NonnullOwnPtr<ZlibDecompressor>> ZlibDecompressor::create(MaybeOwned<Stream> stream)
|
||||
{
|
||||
auto header = TRY(stream->read_value<ZlibHeader>());
|
||||
|
||||
if (header.compression_method != ZlibCompressionMethod::Deflate || header.compression_info > 7)
|
||||
return Error::from_string_literal("Non-DEFLATE compression inside Zlib is not supported");
|
||||
|
||||
if (header.present_dictionary)
|
||||
return Error::from_string_literal("Zlib compression with a pre-defined dictionary is currently not supported");
|
||||
|
||||
if (header.as_u16 % 31 != 0)
|
||||
return Error::from_string_literal("Zlib error correction code does not match");
|
||||
|
||||
auto bit_stream = make<LittleEndianInputBitStream>(move(stream));
|
||||
auto deflate_stream = TRY(Compress::DeflateDecompressor::construct(move(bit_stream)));
|
||||
|
||||
return adopt_nonnull_own_or_enomem(new (nothrow) ZlibDecompressor(header, move(deflate_stream)));
|
||||
return adopt_nonnull_own_or_enomem(new (nothrow) ZlibDecompressor(move(stream)));
|
||||
}
|
||||
|
||||
ZlibDecompressor::ZlibDecompressor(ZlibHeader header, NonnullOwnPtr<Stream> stream)
|
||||
: m_header(header)
|
||||
ZlibDecompressor::ZlibDecompressor(MaybeOwned<Stream> stream)
|
||||
: m_has_seen_header(false)
|
||||
, m_stream(move(stream))
|
||||
{
|
||||
}
|
||||
|
||||
ErrorOr<Bytes> ZlibDecompressor::read_some(Bytes bytes)
|
||||
{
|
||||
if (!m_has_seen_header) {
|
||||
auto header = TRY(m_stream->read_value<ZlibHeader>());
|
||||
|
||||
if (header.compression_method != ZlibCompressionMethod::Deflate || header.compression_info > 7)
|
||||
return Error::from_string_literal("Non-DEFLATE compression inside Zlib is not supported");
|
||||
|
||||
if (header.present_dictionary)
|
||||
return Error::from_string_literal("Zlib compression with a pre-defined dictionary is currently not supported");
|
||||
|
||||
if (header.as_u16 % 31 != 0)
|
||||
return Error::from_string_literal("Zlib error correction code does not match");
|
||||
|
||||
auto bit_stream = make<LittleEndianInputBitStream>(move(m_stream));
|
||||
auto deflate_stream = TRY(Compress::DeflateDecompressor::construct(move(bit_stream)));
|
||||
|
||||
m_stream = move(deflate_stream);
|
||||
m_has_seen_header = true;
|
||||
}
|
||||
return m_stream->read_some(bytes);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,10 +55,10 @@ public:
|
|||
virtual void close() override;
|
||||
|
||||
private:
|
||||
ZlibDecompressor(ZlibHeader, NonnullOwnPtr<Stream>);
|
||||
ZlibDecompressor(MaybeOwned<Stream>);
|
||||
|
||||
ZlibHeader m_header;
|
||||
NonnullOwnPtr<Stream> m_stream;
|
||||
bool m_has_seen_header { false };
|
||||
MaybeOwned<Stream> m_stream;
|
||||
};
|
||||
|
||||
class ZlibCompressor : public Stream {
|
||||
|
|
|
@ -32,8 +32,6 @@ WebIDL::ExceptionOr<GC::Ref<DecompressionStream>> DecompressionStream::construct
|
|||
auto decompressor = [&, input_stream = MaybeOwned<Stream> { *input_stream }]() mutable -> ErrorOr<Decompressor> {
|
||||
switch (format) {
|
||||
case Bindings::CompressionFormat::Deflate:
|
||||
// FIXME: Our zlib decompressor assumes the initial data contains the zlib header. We don't have any data yet,
|
||||
// so this will always fail.
|
||||
return TRY(Compress::ZlibDecompressor::create(move(input_stream)));
|
||||
case Bindings::CompressionFormat::DeflateRaw:
|
||||
return TRY(Compress::DeflateDecompressor::construct(make<LittleEndianInputBitStream>(move(input_stream))));
|
||||
|
|
|
@ -27,6 +27,25 @@ TEST_CASE(zlib_decompress_simple)
|
|||
EXPECT(decompressed.bytes() == (ReadonlyBytes { uncompressed, sizeof(uncompressed) - 1 }));
|
||||
}
|
||||
|
||||
TEST_CASE(zlib_decompress_stream)
|
||||
{
|
||||
Array<u8, 40> const compressed {
|
||||
0x78, 0x01, 0x01, 0x1D, 0x00, 0xE2, 0xFF, 0x54, 0x68, 0x69, 0x73, 0x20,
|
||||
0x69, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6D, 0x70, 0x6C, 0x65, 0x20,
|
||||
0x74, 0x65, 0x78, 0x74, 0x20, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x3A, 0x29,
|
||||
0x99, 0x5E, 0x09, 0xE8
|
||||
};
|
||||
|
||||
u8 const uncompressed[] = "This is a simple text file :)";
|
||||
|
||||
auto stream = make<AllocatingMemoryStream>();
|
||||
auto input = MaybeOwned<Stream> { *stream };
|
||||
auto decompressor = TRY_OR_FAIL(Compress::ZlibDecompressor::create(move(input)));
|
||||
TRY_OR_FAIL(stream->write_until_depleted(compressed));
|
||||
auto decompressed = TRY_OR_FAIL(decompressor->read_until_eof());
|
||||
EXPECT(decompressed.bytes() == (ReadonlyBytes { uncompressed, sizeof(uncompressed) - 1 }));
|
||||
}
|
||||
|
||||
TEST_CASE(zlib_compress_simple)
|
||||
{
|
||||
// Note: This is just the output of our compression function from an arbitrary point in time.
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
format=deflate: Well hello friends!
|
||||
format=deflate-raw: Well hello friends!
|
||||
format=gzip: Well hello friends!
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
<script>
|
||||
asyncTest(async done => {
|
||||
const data = [
|
||||
// FIXME: Enable this case when our DecompressionStream is functioning with the zlib format.
|
||||
// { format: "deflate", text: "eJwLT83JUchIzcnJV0grykzNSylWBABGEQb1" },
|
||||
{ format: "deflate", text: "eJwLT83JUchIzcnJV0grykzNSylWBABGEQb1" },
|
||||
{ format: "deflate-raw", text: "C0/NyVHISM3JyVdIK8pMzUspVgQA" },
|
||||
{ format: "gzip", text: "H4sIAAAAAAADAwtPzclRyEjNyclXSCvKTM1LKVYEAHN0w4sTAAAA" },
|
||||
];
|
||||
|
|
Loading…
Reference in a new issue