diff --git a/Tests/LibCompress/TestXz.cpp b/Tests/LibCompress/TestXz.cpp index 8bb6af4f011..ec8dc31f1f0 100644 --- a/Tests/LibCompress/TestXz.cpp +++ b/Tests/LibCompress/TestXz.cpp @@ -118,8 +118,9 @@ TEST_CASE(xz_utils_bad_0_header_magic) }; auto stream = MUST(try_make(compressed)); - auto decompressor_or_error = Compress::XzDecompressor::create(move(stream)); - EXPECT(decompressor_or_error.is_error()); + auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); + auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); + EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_0_nonempty_index) @@ -695,8 +696,9 @@ TEST_CASE(xz_utils_bad_1_stream_flags_2) }; auto stream = MUST(try_make(compressed)); - auto decompressor_or_error = Compress::XzDecompressor::create(move(stream)); - EXPECT(decompressor_or_error.is_error()); + auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); + auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); + EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_stream_flags_3) diff --git a/Userland/Libraries/LibCompress/Xz.cpp b/Userland/Libraries/LibCompress/Xz.cpp index 7fabb841f32..cf996111e4b 100644 --- a/Userland/Libraries/LibCompress/Xz.cpp +++ b/Userland/Libraries/LibCompress/Xz.cpp @@ -165,17 +165,13 @@ ErrorOr> XzDecompressor::create(MaybeOwned { auto counting_stream = TRY(try_make(move(stream))); - auto stream_header = TRY(counting_stream->read_value()); - TRY(stream_header.validate()); - - auto decompressor = TRY(adopt_nonnull_own_or_enomem(new (nothrow) XzDecompressor(move(counting_stream), stream_header.flags))); + auto decompressor = TRY(adopt_nonnull_own_or_enomem(new (nothrow) XzDecompressor(move(counting_stream)))); return decompressor; } -XzDecompressor::XzDecompressor(NonnullOwnPtr stream, XzStreamFlags stream_flags) +XzDecompressor::XzDecompressor(NonnullOwnPtr stream) : m_stream(move(stream)) - , m_stream_flags(stream_flags) { } @@ -184,6 +180,13 @@ ErrorOr XzDecompressor::read_some(Bytes bytes) if (m_found_stream_footer) return bytes.trim(0); + if (!m_stream_flags.has_value()) { + auto stream_header = TRY(m_stream->read_value()); + TRY(stream_header.validate()); + + m_stream_flags = stream_header.flags; + } + if (!m_current_block_stream.has_value() || (*m_current_block_stream)->is_eof()) { if (m_current_block_stream.has_value()) { // We have already processed a block, so we weed to clean up trailing data before the next block starts. @@ -212,7 +215,7 @@ ErrorOr XzDecompressor::read_some(Bytes bytes) // indicate a warning or error." // TODO: Block content checks are currently unimplemented as a whole, independent of the check type. // For now, we only make sure to remove the correct amount of bytes from the stream. - switch (m_stream_flags.check_type) { + switch (m_stream_flags->check_type) { case XzStreamCheckType::None: break; case XzStreamCheckType::CRC32: @@ -329,7 +332,7 @@ ErrorOr XzDecompressor::read_some(Bytes bytes) // when parsing the Stream backwards. The decoder MUST compare // the Stream Flags fields in both Stream Header and Stream // Footer, and indicate an error if they are not identical." - if (Bytes { &m_stream_flags, sizeof(m_stream_flags) } != Bytes { &stream_footer.flags, sizeof(stream_footer.flags) }) + if (Bytes { &*m_stream_flags, sizeof(XzStreamFlags) } != Bytes { &stream_footer.flags, sizeof(stream_footer.flags) }) return Error::from_string_literal("XZ stream header flags don't match the stream footer"); m_found_stream_footer = true; diff --git a/Userland/Libraries/LibCompress/Xz.h b/Userland/Libraries/LibCompress/Xz.h index 1e95a7ea862..8decf077997 100644 --- a/Userland/Libraries/LibCompress/Xz.h +++ b/Userland/Libraries/LibCompress/Xz.h @@ -108,10 +108,10 @@ public: virtual void close() override; private: - XzDecompressor(NonnullOwnPtr, XzStreamFlags); + XzDecompressor(NonnullOwnPtr); NonnullOwnPtr m_stream; - XzStreamFlags m_stream_flags; + Optional m_stream_flags; bool m_found_stream_footer { false }; Optional> m_current_block_stream {};