libflate/deflate/
decode.rs

1use super::symbol;
2use crate::bit;
3use crate::lz77;
4use core2::io::{self, Read};
5
6/// DEFLATE decoder.
7#[derive(Debug)]
8pub struct Decoder<R> {
9    bit_reader: bit::BitReader<R>,
10    lz77_decoder: lz77::Lz77Decoder,
11    eos: bool,
12}
13impl<R> Decoder<R>
14where
15    R: Read,
16{
17    /// Makes a new decoder instance.
18    ///
19    /// `inner` is to be decoded DEFLATE stream.
20    ///
21    /// # Examples
22    /// ```
23    /// # extern crate alloc;
24    /// # use alloc::vec::Vec;
25    /// use core2::io::{Cursor, Read};
26    /// use libflate::deflate::Decoder;
27    ///
28    /// let encoded_data = [243, 72, 205, 201, 201, 87, 8, 207, 47, 202, 73, 81, 4, 0];
29    /// let mut decoder = Decoder::new(&encoded_data[..]);
30    /// let mut buf = Vec::new();
31    /// decoder.read_to_end(&mut buf).unwrap();
32    ///
33    /// assert_eq!(buf, b"Hello World!");
34    /// ```
35    pub fn new(inner: R) -> Self {
36        Decoder {
37            bit_reader: bit::BitReader::new(inner),
38            lz77_decoder: lz77::Lz77Decoder::new(),
39            eos: false,
40        }
41    }
42
43    /// Returns the immutable reference to the inner stream.
44    pub fn as_inner_ref(&self) -> &R {
45        self.bit_reader.as_inner_ref()
46    }
47
48    /// Returns the mutable reference to the inner stream.
49    pub fn as_inner_mut(&mut self) -> &mut R {
50        self.bit_reader.as_inner_mut()
51    }
52
53    /// Unwraps this `Decoder`, returning the underlying reader.
54    ///
55    /// # Examples
56    /// ```
57    /// use core2::io::Cursor;
58    /// use libflate::deflate::Decoder;
59    ///
60    /// let encoded_data = [243, 72, 205, 201, 201, 87, 8, 207, 47, 202, 73, 81, 4, 0];
61    /// let decoder = Decoder::new(Cursor::new(&encoded_data));
62    /// assert_eq!(decoder.into_inner().into_inner(), &encoded_data);
63    /// ```
64    pub fn into_inner(self) -> R {
65        self.bit_reader.into_inner()
66    }
67
68    /// Returns the data that has been decoded but has not yet been read.
69    ///
70    /// This method is useful to retrieve partial decoded data when the decoding process is failed.
71    pub fn unread_decoded_data(&self) -> &[u8] {
72        self.lz77_decoder.buffer()
73    }
74
75    pub(crate) fn reset(&mut self) {
76        self.bit_reader.reset();
77        self.lz77_decoder.clear();
78        self.eos = false
79    }
80
81    fn read_non_compressed_block(&mut self) -> io::Result<()> {
82        self.bit_reader.reset();
83        let mut buf = [0; 2];
84        self.bit_reader.as_inner_mut().read_exact(&mut buf)?;
85        let len = u16::from_le_bytes(buf);
86        self.bit_reader.as_inner_mut().read_exact(&mut buf)?;
87        let nlen = u16::from_le_bytes(buf);
88        if !len != nlen {
89            Err(invalid_data_error!(
90                "LEN={} is not the one's complement of NLEN={}",
91                len,
92                nlen
93            ))
94        } else {
95            self.lz77_decoder
96                .extend_from_reader(self.bit_reader.as_inner_mut().take(len.into()))
97                .and_then(|used| {
98                    if used != len.into() {
99                        Err(io::Error::new(
100                            io::ErrorKind::UnexpectedEof,
101                            #[cfg(feature = "std")]
102                            format!("The reader has incorrect length: expected {len}, read {used}"),
103                            #[cfg(not(feature = "std"))]
104                            "The reader has incorrect length",
105                        ))
106                    } else {
107                        Ok(())
108                    }
109                })
110        }
111    }
112    fn read_compressed_block<H>(&mut self, huffman: &H) -> io::Result<()>
113    where
114        H: symbol::HuffmanCodec,
115    {
116        let symbol_decoder = huffman.load(&mut self.bit_reader)?;
117        loop {
118            let s = symbol_decoder.decode_unchecked(&mut self.bit_reader);
119            self.bit_reader.check_last_error()?;
120            match s {
121                symbol::Symbol::Code(code) => {
122                    self.lz77_decoder.decode(code)?;
123                }
124                symbol::Symbol::EndOfBlock => {
125                    break;
126                }
127            }
128        }
129        Ok(())
130    }
131}
132impl<R> Read for Decoder<R>
133where
134    R: Read,
135{
136    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
137        if !self.lz77_decoder.buffer().is_empty() {
138            self.lz77_decoder.read(buf)
139        } else if self.eos {
140            Ok(0)
141        } else {
142            let bfinal = self.bit_reader.read_bit()?;
143            let btype = self.bit_reader.read_bits(2)?;
144            self.eos = bfinal;
145            match btype {
146                0b00 => {
147                    self.read_non_compressed_block()?;
148                    self.read(buf)
149                }
150                0b01 => {
151                    self.read_compressed_block(&symbol::FixedHuffmanCodec)?;
152                    self.read(buf)
153                }
154                0b10 => {
155                    self.read_compressed_block(&symbol::DynamicHuffmanCodec)?;
156                    self.read(buf)
157                }
158                0b11 => Err(invalid_data_error!(
159                    "btype 0x11 of DEFLATE is reserved(error) value"
160                )),
161                _ => unreachable!(),
162            }
163        }
164    }
165}
166
167#[cfg(test)]
168mod tests {
169    #[cfg(feature = "std")]
170    use super::*;
171    use crate::deflate::symbol::{DynamicHuffmanCodec, HuffmanCodec};
172    #[cfg(feature = "std")]
173    use std::io;
174
175    #[test]
176    fn test_issues_3() {
177        // see: https://github.com/sile/libflate/issues/3
178        let input = [
179            180, 253, 73, 143, 28, 201, 150, 46, 8, 254, 150, 184, 139, 75, 18, 69, 247, 32, 157,
180            51, 27, 141, 132, 207, 78, 210, 167, 116, 243, 160, 223, 136, 141, 66, 205, 76, 221,
181            76, 195, 213, 84, 236, 234, 224, 78, 227, 34, 145, 221, 139, 126, 232, 69, 173, 170,
182            208, 192, 219, 245, 67, 3, 15, 149, 120, 171, 70, 53, 106, 213, 175, 23, 21, 153, 139,
183            254, 27, 249, 75, 234, 124, 71, 116, 56, 71, 68, 212, 204, 121, 115, 64, 222, 160, 203,
184            119, 142, 170, 169, 138, 202, 112, 228, 140, 38,
185        ];
186        let mut bit_reader = crate::bit::BitReader::new(&input[..]);
187        assert_eq!(bit_reader.read_bit().unwrap(), false); // not final block
188        assert_eq!(bit_reader.read_bits(2).unwrap(), 0b10); // DynamicHuffmanCodec
189        DynamicHuffmanCodec.load(&mut bit_reader).unwrap();
190    }
191
192    #[test]
193    #[cfg(feature = "std")]
194    fn it_works() {
195        let input = [
196            180, 253, 73, 143, 28, 201, 150, 46, 8, 254, 150, 184, 139, 75, 18, 69, 247, 32, 157,
197            51, 27, 141, 132, 207, 78, 210, 167, 116, 243, 160, 223, 136, 141, 66, 205, 76, 221,
198            76, 195, 213, 84, 236, 234, 224, 78, 227, 34, 145, 221, 139, 126, 232, 69, 173, 170,
199            208, 192, 219, 245, 67, 3, 15, 149, 120, 171, 70, 53, 106, 213, 175, 23, 21, 153, 139,
200            254, 27, 249, 75, 234, 124, 71, 116, 56, 71, 68, 212, 204, 121, 115, 64, 222, 160, 203,
201            119, 142, 170, 169, 138, 202, 112, 228, 140, 38, 171, 162, 88, 212, 235, 56, 136, 231,
202            233, 239, 113, 249, 163, 252, 16, 42, 138, 49, 226, 108, 73, 28, 153,
203        ];
204        let mut decoder = Decoder::new(&input[..]);
205
206        let result = io::copy(&mut decoder, &mut io::sink());
207        assert!(result.is_err());
208
209        let error = result.err().unwrap();
210        assert_eq!(error.kind(), io::ErrorKind::InvalidData);
211        assert!(error.to_string().starts_with("Too long backword reference"));
212    }
213
214    #[test]
215    #[cfg(feature = "std")]
216    fn test_issue_64() {
217        let input = b"\x04\x04\x04\x05:\x1az*\xfc\x06\x01\x90\x01\x06\x01";
218        let mut decoder = Decoder::new(&input[..]);
219        assert!(io::copy(&mut decoder, &mut io::sink()).is_err());
220    }
221}