diff --git a/Userland/Libraries/LibCompress/Gzip.cpp b/Userland/Libraries/LibCompress/Gzip.cpp index 8feb409cf1..5035245d09 100644 --- a/Userland/Libraries/LibCompress/Gzip.cpp +++ b/Userland/Libraries/LibCompress/Gzip.cpp @@ -106,14 +106,20 @@ size_t GzipDecompressor::read(Bytes bytes) return nread; } else { - BlockHeader header; - m_input_stream >> Bytes { &header, sizeof(header) }; + m_partial_header_offset += m_input_stream.read(Bytes { m_partial_header, sizeof(BlockHeader) }.slice(m_partial_header_offset)); - if (m_input_stream.handle_any_error()) { + if (m_input_stream.handle_any_error() || m_input_stream.unreliable_eof()) { m_eof = true; return 0; } + if (m_partial_header_offset < sizeof(BlockHeader)) { + return 0; // partial header read + } + m_partial_header_offset = 0; + + BlockHeader header = *(reinterpret_cast(m_partial_header)); + if (!header.valid_magic_number() || !header.supported_by_implementation()) { set_fatal_error(); return 0; diff --git a/Userland/Libraries/LibCompress/Gzip.h b/Userland/Libraries/LibCompress/Gzip.h index 0b7d21068a..921a2fb7b6 100644 --- a/Userland/Libraries/LibCompress/Gzip.h +++ b/Userland/Libraries/LibCompress/Gzip.h @@ -91,6 +91,8 @@ private: Member& current_member() { return m_current_member.value(); } InputStream& m_input_stream; + u8 m_partial_header[sizeof(BlockHeader)]; + size_t m_partial_header_offset { 0 }; Optional m_current_member; bool m_eof { false };