瀏覽代碼

LibCompress: Check and fail for input stream errors in DeflateDecompressor

Since we were not checking for error flags set by read_bits we would
just always read 0 as the bits' value, which in some edge cases could
lead to an infinite loop.
Idan Horowitz 4 年之前
父節點
當前提交
be5a8d9c7f
共有 1 個文件被更改,包括 25 次插入0 次删除
  1. 25 0
      Userland/Libraries/LibCompress/Deflate.cpp

+ 25 - 0
Userland/Libraries/LibCompress/Deflate.cpp

@@ -218,12 +218,22 @@ size_t DeflateDecompressor::read(Bytes bytes)
         m_read_final_bock = m_input_stream.read_bit();
         const auto block_type = m_input_stream.read_bits(2);
 
+        if (m_input_stream.has_any_error()) {
+            set_fatal_error();
+            return 0;
+        }
+
         if (block_type == 0b00) {
             m_input_stream.align_to_byte_boundary();
 
             LittleEndian<u16> length, negated_length;
             m_input_stream >> length >> negated_length;
 
+            if (m_input_stream.has_any_error()) {
+                set_fatal_error();
+                return 0;
+            }
+
             if ((length ^ 0xffff) != negated_length) {
                 set_fatal_error();
                 return 0;
@@ -247,6 +257,11 @@ size_t DeflateDecompressor::read(Bytes bytes)
             Optional<CanonicalCode> distance_codes;
             decode_codes(literal_codes, distance_codes);
 
+            if (m_input_stream.has_any_error()) {
+                set_fatal_error();
+                return 0;
+            }
+
             m_state = State::ReadingCompressedBlock;
             new (&m_compressed_block) CompressedBlock(*this, literal_codes, distance_codes);
 
@@ -264,6 +279,11 @@ size_t DeflateDecompressor::read(Bytes bytes)
             nread += m_output_stream.read(bytes.slice(nread));
         }
 
+        if (m_input_stream.has_any_error()) {
+            set_fatal_error();
+            return 0;
+        }
+
         if (nread == bytes.size())
             return nread;
 
@@ -280,6 +300,11 @@ size_t DeflateDecompressor::read(Bytes bytes)
             nread += m_output_stream.read(bytes.slice(nread));
         }
 
+        if (m_input_stream.has_any_error()) {
+            set_fatal_error();
+            return 0;
+        }
+
         if (nread == bytes.size())
             return nread;