1use crate::checksum;
23use crate::deflate;
24use crate::finish::{Complete, Finish};
25use crate::lz77;
26use no_std_io2::io;
27
28const COMPRESSION_METHOD_DEFLATE: u8 = 8;
29
30#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
32pub enum CompressionLevel {
33 Fastest = 0,
35
36 Fast = 1,
38
39 Default = 2,
41
42 Slowest = 3,
44}
45impl CompressionLevel {
46 fn from_u2(level: u8) -> Self {
47 match level {
48 0 => CompressionLevel::Fastest,
49 1 => CompressionLevel::Fast,
50 2 => CompressionLevel::Default,
51 3 => CompressionLevel::Slowest,
52 _ => unreachable!(),
53 }
54 }
55 fn as_u2(&self) -> u8 {
56 self.clone() as u8
57 }
58}
59impl From<lz77::CompressionLevel> for CompressionLevel {
60 fn from(f: lz77::CompressionLevel) -> Self {
61 match f {
62 lz77::CompressionLevel::None => CompressionLevel::Fastest,
63 lz77::CompressionLevel::Fast => CompressionLevel::Fast,
64 lz77::CompressionLevel::Balance => CompressionLevel::Default,
65 lz77::CompressionLevel::Best => CompressionLevel::Slowest,
66 }
67 }
68}
69
70#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
72#[allow(clippy::all)]
74pub enum Lz77WindowSize {
75 B256 = 0,
77
78 B512 = 1,
80
81 KB1 = 2,
83
84 KB2 = 3,
86
87 KB4 = 4,
89
90 KB8 = 5,
92
93 KB16 = 6,
95
96 KB32 = 7,
98}
99impl Lz77WindowSize {
100 fn from_u4(compression_info: u8) -> Option<Self> {
101 match compression_info {
102 0 => Some(Lz77WindowSize::B256),
103 1 => Some(Lz77WindowSize::B512),
104 2 => Some(Lz77WindowSize::KB1),
105 3 => Some(Lz77WindowSize::KB2),
106 4 => Some(Lz77WindowSize::KB4),
107 5 => Some(Lz77WindowSize::KB8),
108 6 => Some(Lz77WindowSize::KB16),
109 7 => Some(Lz77WindowSize::KB32),
110 _ => None,
111 }
112 }
113 fn as_u4(&self) -> u8 {
114 self.clone() as u8
115 }
116
117 pub fn from_u16(size: u16) -> Self {
133 use self::Lz77WindowSize::*;
134 if 16_384 < size {
135 KB32
136 } else if 8192 < size {
137 KB16
138 } else if 4096 < size {
139 KB8
140 } else if 2048 < size {
141 KB4
142 } else if 1024 < size {
143 KB2
144 } else if 512 < size {
145 KB1
146 } else if 256 < size {
147 B512
148 } else {
149 B256
150 }
151 }
152
153 pub fn to_u16(&self) -> u16 {
162 use self::Lz77WindowSize::*;
163 match *self {
164 B256 => 256,
165 B512 => 512,
166 KB1 => 1024,
167 KB2 => 2048,
168 KB4 => 4096,
169 KB8 => 8192,
170 KB16 => 16_384,
171 KB32 => 32_768,
172 }
173 }
174}
175
176#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
185pub enum FlushMode {
186 #[default]
191 None = 0,
192
193 Sync = 2,
195}
196
197#[derive(Debug, Clone, PartialEq, Eq, Hash)]
199pub struct Header {
200 window_size: Lz77WindowSize,
201 compression_level: CompressionLevel,
202}
203impl Header {
204 pub fn window_size(&self) -> Lz77WindowSize {
206 self.window_size.clone()
207 }
208 pub fn compression_level(&self) -> CompressionLevel {
210 self.compression_level.clone()
211 }
212 fn from_lz77<E>(lz77: &E) -> Self
213 where
214 E: lz77::Lz77Encode,
215 {
216 Header {
217 compression_level: From::from(lz77.compression_level()),
218 window_size: Lz77WindowSize::from_u16(lz77.window_size()),
219 }
220 }
221 pub(crate) fn read_from<R>(mut reader: R) -> io::Result<Self>
222 where
223 R: io::Read,
224 {
225 let mut buf = [0; 2];
226 reader.read_exact(&mut buf)?;
227 let [cmf, flg] = buf;
228 let check = (u16::from(cmf) << 8) + u16::from(flg);
229 if check % 31 != 0 {
230 return Err(invalid_data_error!(
231 "Inconsistent ZLIB check bits: `CMF({}) * 256 + \
232 FLG({})` must be a multiple of 31",
233 cmf,
234 flg
235 ));
236 }
237
238 let compression_method = cmf & 0b1111;
239 let compression_info = cmf >> 4;
240 if compression_method != COMPRESSION_METHOD_DEFLATE {
241 return Err(invalid_data_error!(
242 "Compression methods other than DEFLATE(8) are \
243 unsupported: method={}",
244 compression_method
245 ));
246 }
247 let window_size = Lz77WindowSize::from_u4(compression_info).ok_or_else(|| {
248 invalid_data_error!("CINFO above 7 are not allowed: value={}", compression_info)
249 })?;
250
251 let dict_flag = (flg & 0b10_0000) != 0;
252 if dict_flag {
253 let mut buf = [0; 4];
254 reader.read_exact(&mut buf)?;
255 return Err(invalid_data_error!(
256 "Preset dictionaries are not supported: \
257 dictionary_id=0x{:X}",
258 u32::from_be_bytes(buf)
259 ));
260 }
261 let compression_level = CompressionLevel::from_u2(flg >> 6);
262 Ok(Header {
263 window_size,
264 compression_level,
265 })
266 }
267 fn write_to<W>(&self, mut writer: W) -> io::Result<()>
268 where
269 W: io::Write,
270 {
271 let cmf = (self.window_size.as_u4() << 4) | COMPRESSION_METHOD_DEFLATE;
272 let mut flg = self.compression_level.as_u2() << 6;
273 let check = (u16::from(cmf) << 8) + u16::from(flg);
274 if check % 31 != 0 {
275 flg += (31 - check % 31) as u8;
276 }
277 writer.write_all(&[cmf, flg])?;
278 Ok(())
279 }
280}
281
282#[derive(Debug)]
284pub struct Decoder<R> {
285 header: Header,
286 reader: deflate::Decoder<R>,
287 adler32: checksum::Adler32,
288 eos: bool,
289}
290impl<R> Decoder<R>
291where
292 R: io::Read,
293{
294 pub fn new(mut inner: R) -> io::Result<Self> {
313 let header = Header::read_from(&mut inner)?;
314 Ok(Decoder {
315 header,
316 reader: deflate::Decoder::new(inner),
317 adler32: checksum::Adler32::new(),
318 eos: false,
319 })
320 }
321
322 pub fn header(&self) -> &Header {
336 &self.header
337 }
338
339 pub fn as_inner_ref(&self) -> &R {
341 self.reader.as_inner_ref()
342 }
343
344 pub fn as_inner_mut(&mut self) -> &mut R {
346 self.reader.as_inner_mut()
347 }
348
349 pub fn into_inner(self) -> R {
363 self.reader.into_inner()
364 }
365
366 pub fn unread_decoded_data(&self) -> &[u8] {
370 self.reader.unread_decoded_data()
371 }
372}
373impl<R> io::Read for Decoder<R>
374where
375 R: io::Read,
376{
377 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
378 if self.eos {
379 Ok(0)
380 } else {
381 let read_size = self.reader.read(buf)?;
382 if read_size == 0 {
383 if buf.is_empty() {
384 return Ok(0);
385 }
386
387 self.eos = true;
388 let mut buf = [0; 4];
389 self.reader.as_inner_mut().read_exact(&mut buf)?;
390 let adler32 = u32::from_be_bytes(buf);
391
392 if cfg!(not(fuzzing)) && adler32 != self.adler32.value() {
396 Err(invalid_data_error!(
397 "Adler32 checksum mismatched: value={}, expected={}",
398 self.adler32.value(),
399 adler32
400 ))
401 } else {
402 Ok(0)
403 }
404 } else {
405 self.adler32.update(&buf[..read_size]);
406 Ok(read_size)
407 }
408 }
409 }
410}
411
412#[derive(Debug)]
414pub struct EncodeOptions<E>
415where
416 E: lz77::Lz77Encode,
417{
418 header: Header,
419 options: deflate::EncodeOptions<E>,
420 flush_mode: FlushMode,
421}
422impl Default for EncodeOptions<lz77::DefaultLz77Encoder> {
423 fn default() -> Self {
424 EncodeOptions {
425 header: Header::from_lz77(&lz77::DefaultLz77Encoder::new()),
426 options: Default::default(),
427 flush_mode: FlushMode::None,
428 }
429 }
430}
431impl EncodeOptions<lz77::DefaultLz77Encoder> {
432 pub fn new() -> Self {
442 Self::default()
443 }
444}
445impl<E> EncodeOptions<E>
446where
447 E: lz77::Lz77Encode,
448{
449 pub fn with_lz77(lz77: E) -> Self {
460 EncodeOptions {
461 header: Header::from_lz77(&lz77),
462 options: deflate::EncodeOptions::with_lz77(lz77),
463 flush_mode: FlushMode::None,
464 }
465 }
466
467 pub fn no_compression(mut self) -> Self {
478 self.options = self.options.no_compression();
479 self.header.compression_level = CompressionLevel::Fastest;
480 self
481 }
482
483 pub fn block_size(mut self, size: usize) -> Self {
495 self.options = self.options.block_size(size);
496 self
497 }
498
499 pub fn fixed_huffman_codes(mut self) -> Self {
509 self.options = self.options.fixed_huffman_codes();
510 self
511 }
512
513 pub fn flush_mode(mut self, mode: FlushMode) -> Self {
515 self.flush_mode = mode;
516 self
517 }
518}
519
520#[derive(Debug)]
522pub struct Encoder<W, E = lz77::DefaultLz77Encoder> {
523 header: Header,
524 flush_mode: FlushMode,
525 writer: deflate::Encoder<W, E>,
526 adler32: checksum::Adler32,
527}
528impl<W> Encoder<W, lz77::DefaultLz77Encoder>
529where
530 W: io::Write,
531{
532 pub fn new(inner: W) -> io::Result<Self> {
552 Self::with_options(inner, EncodeOptions::default())
553 }
554}
555impl<W, E> Encoder<W, E>
556where
557 W: io::Write,
558 E: lz77::Lz77Encode,
559{
560 pub fn with_options(mut inner: W, options: EncodeOptions<E>) -> io::Result<Self> {
578 options.header.write_to(&mut inner)?;
579 Ok(Encoder {
580 header: options.header,
581 flush_mode: options.flush_mode,
582 writer: deflate::Encoder::with_options(inner, options.options),
583 adler32: checksum::Adler32::new(),
584 })
585 }
586
587 pub fn header(&self) -> &Header {
597 &self.header
598 }
599
600 pub fn finish(self) -> Finish<W, io::Error> {
631 let mut inner = finish_try!(self.writer.finish());
632 match inner
633 .write_all(&self.adler32.value().to_be_bytes())
634 .and_then(|_| inner.flush())
635 {
636 Ok(_) => Finish::new(inner, None),
637 Err(e) => Finish::new(inner, Some(e)),
638 }
639 }
640
641 pub fn as_inner_ref(&self) -> &W {
643 self.writer.as_inner_ref()
644 }
645
646 pub fn as_inner_mut(&mut self) -> &mut W {
648 self.writer.as_inner_mut()
649 }
650
651 pub fn into_inner(self) -> W {
653 self.writer.into_inner()
654 }
655}
656impl<W, E> io::Write for Encoder<W, E>
657where
658 W: io::Write,
659 E: lz77::Lz77Encode,
660{
661 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
662 let written_size = self.writer.write(buf)?;
663 self.adler32.update(&buf[..written_size]);
664 Ok(written_size)
665 }
666 fn flush(&mut self) -> io::Result<()> {
667 match self.flush_mode {
668 FlushMode::None => self.writer.flush(),
669 FlushMode::Sync => self.writer.zlib_sync_flush(),
670 }
671 }
672}
673impl<W, E> Complete for Encoder<W, E>
674where
675 W: io::Write,
676 E: lz77::Lz77Encode,
677{
678 fn complete(self) -> io::Result<()> {
679 self.finish().into_result().map(|_| ())
680 }
681}
682
683#[cfg(test)]
684mod tests {
685 use super::*;
686 use crate::finish::AutoFinish;
687 use alloc::{borrow::ToOwned, string::ToString, vec, vec::Vec};
688 use no_std_io2::io::{Read as _, Write as _};
689
690 fn decode_all(buf: &[u8]) -> io::Result<Vec<u8>> {
691 let mut decoder = Decoder::new(buf).unwrap();
692 let mut buf = Vec::with_capacity(buf.len());
693 decoder.read_to_end(&mut buf)?;
694 Ok(buf)
695 }
696 fn default_encode(buf: &[u8]) -> io::Result<Vec<u8>> {
697 let mut encoder = Encoder::new(Vec::new()).unwrap();
698 encoder.write_all(buf).unwrap();
699 encoder.finish().into_result()
700 }
701 macro_rules! assert_encode_decode {
702 ($input:expr) => {{
703 let encoded = default_encode(&$input[..]).unwrap();
704 assert_eq!(decode_all(&encoded).unwrap(), &$input[..]);
705 }};
706 }
707
708 const DECODE_WORKS_TESTDATA: [u8; 20] = [
709 120, 156, 243, 72, 205, 201, 201, 87, 8, 207, 47, 202, 73, 81, 4, 0, 28, 73, 4, 62,
710 ];
711 #[test]
712 fn decode_works() {
713 let encoded = DECODE_WORKS_TESTDATA;
714 let mut decoder = Decoder::new(&encoded[..]).unwrap();
715 assert_eq!(
716 *decoder.header(),
717 Header {
718 window_size: Lz77WindowSize::KB32,
719 compression_level: CompressionLevel::Default,
720 }
721 );
722
723 let mut buf = Vec::new();
724 decoder.read_to_end(&mut buf).unwrap();
725
726 let expected = b"Hello World!";
727 assert_eq!(buf, expected);
728 }
729
730 #[test]
731 fn default_encode_works() {
732 let plain = b"Hello World! Hello ZLIB!!";
733 let mut encoder = Encoder::new(Vec::new()).unwrap();
734 encoder.write_all(plain.as_ref()).unwrap();
735 let encoded = encoder.finish().into_result().unwrap();
736 assert_eq!(decode_all(&encoded).unwrap(), plain);
737 }
738
739 #[test]
740 fn best_speed_encode_works() {
741 let plain = b"Hello World! Hello ZLIB!!";
742 let mut encoder =
743 Encoder::with_options(Vec::new(), EncodeOptions::default().fixed_huffman_codes())
744 .unwrap();
745 encoder.write_all(plain.as_ref()).unwrap();
746 let encoded = encoder.finish().into_result().unwrap();
747 assert_eq!(decode_all(&encoded).unwrap(), plain);
748 }
749
750 const RAW_ENCODE_WORKS_EXPECTED: [u8; 23] = [
751 120, 1, 1, 12, 0, 243, 255, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 28, 73,
752 4, 62,
753 ];
754 #[test]
755 fn raw_encode_works() {
756 let plain = b"Hello World!";
757 let mut encoder =
758 Encoder::with_options(Vec::new(), EncodeOptions::new().no_compression()).unwrap();
759 encoder.write_all(plain.as_ref()).unwrap();
760 let encoded = encoder.finish().into_result().unwrap();
761 let expected = RAW_ENCODE_WORKS_EXPECTED;
762 assert_eq!(encoded, expected);
763 assert_eq!(decode_all(&encoded).unwrap(), plain);
764 }
765
766 #[test]
767 fn encoder_auto_finish_works() {
768 let plain = b"Hello World! Hello ZLIB!!";
769 let mut buf = Vec::new();
770 {
771 let mut encoder = AutoFinish::new(Encoder::new(&mut buf).unwrap());
772 encoder.write_all(plain.as_ref()).unwrap();
773 }
774 assert_eq!(decode_all(&buf).unwrap(), plain);
775 }
776
777 #[test]
778 fn test_issue_2() {
779 assert_encode_decode!([
781 163, 181, 167, 40, 62, 239, 41, 125, 189, 217, 61, 122, 20, 136, 160, 178, 119, 217,
782 217, 41, 125, 189, 97, 195, 101, 47, 170,
783 ]);
784 assert_encode_decode!([
785 162, 58, 99, 211, 7, 64, 96, 36, 57, 155, 53, 166, 76, 14, 238, 66, 66, 148, 154, 124,
786 162, 58, 99, 188, 138, 131, 171, 189, 54, 229, 192, 38, 29, 240, 122, 28,
787 ]);
788 assert_encode_decode!([
789 239, 238, 212, 42, 5, 46, 186, 67, 122, 247, 30, 61, 219, 62, 228, 202, 164, 205, 139,
790 109, 99, 181, 99, 181, 99, 122, 30, 12, 62, 46, 27, 145, 241, 183, 137,
791 ]);
792 assert_encode_decode!([
793 88, 202, 64, 12, 125, 108, 153, 49, 164, 250, 71, 19, 4, 108, 111, 108, 237, 205, 208,
794 77, 217, 100, 118, 49, 10, 64, 12, 125, 51, 202, 69, 67, 181, 146, 86,
795 ]);
796 }
797
798 #[test]
799 fn test_issues_16() {
800 let encoded =
803 include_bytes!("../data/issues_16/crash-1bb6d408475a5bd57247ee40f290830adfe2086e");
804 assert_eq!(
805 &decode_all(&encoded[..])
806 .err()
807 .map(|e| e.to_string())
808 .unwrap()[..31],
809 "The value of HDIST is too big: max=30, actual=32"[..31]
810 .to_owned()
811 .as_str()
812 );
813
814 let encoded =
815 include_bytes!("../data/issues_16/crash-369e8509a0e76356f4549c292ceedee429cfe125");
816 assert_eq!(
817 &decode_all(&encoded[..])
818 .err()
819 .map(|e| e.to_string())
820 .unwrap()[..31],
821 "The value of HDIST is too big: max=30, actual=32"[..31]
822 .to_owned()
823 .as_str()
824 );
825
826 let encoded =
827 include_bytes!("../data/issues_16/crash-e75959d935650306881140df7f6d1d73e33425cb");
828 assert_eq!(
829 &decode_all(&encoded[..])
830 .err()
831 .map(|e| e.to_string())
832 .unwrap()[..31],
833 "The value of HDIST is too big: max=30, actual=32"[..31]
834 .to_owned()
835 .as_str()
836 );
837 }
838
839 #[test]
840 fn test_issues_27() {
841 let writes = ["fooooooooooooooooo", "bar", "baz"];
844
845 let mut encoder = Encoder::new(Vec::new()).unwrap();
847 for _ in 0..2 {
848 for string in &writes {
849 encoder.write(string.as_bytes()).expect("Write failed");
850 }
851 encoder.flush().expect("Flush failed");
852 }
853 let finished = encoder.finish().unwrap();
854 let expected = vec![
855 120, 156, 92, 192, 161, 17, 0, 0, 0, 1, 192, 89, 9, 170, 59, 209, 244, 186, 151, 31, 17, 162,
857 227, 2, 14, 141, 0, 0, 0, 8, 0, 206, 74, 80, 221, 137, 166, 215, 189, 252, 136, 16, 93,
858 1, 112, 32, 0, 0, 0, 0, 0, 228, 255, 26, 246, 95, 20, 111,
859 ];
860 assert_eq!(finished.0, expected);
861
862 let mut output = Vec::new();
863 Decoder::new(&finished.0[..])
864 .unwrap()
865 .read_to_end(&mut output)
866 .unwrap();
867 assert_eq!(
868 output,
869 "fooooooooooooooooobarbazfooooooooooooooooobarbaz".as_bytes()
870 );
871
872 let mut encoder =
874 Encoder::with_options(Vec::new(), EncodeOptions::new().flush_mode(FlushMode::Sync))
875 .unwrap();
876 for _ in 0..2 {
877 for string in &writes {
878 encoder.write(string.as_bytes()).expect("Write failed");
879 }
880 encoder.flush().expect("Flush failed");
881 }
882 let finished = encoder.finish().unwrap();
883 let expected = vec![
884 120, 156, 92, 192, 161, 17, 0, 0, 0, 1, 192, 89, 9, 170, 59, 209, 244, 186, 151, 31, 17, 162, 3,
886 0, 0, 255, 255, 92, 192, 161, 17, 0, 0, 0, 1, 192, 89, 9, 170, 59, 209, 244, 186, 151, 31, 17, 162, 3,
888 0, 0, 255, 255, 5, 192, 129, 0, 0, 0, 0, 0, 144, 255, 107, 0, 246, 95, 20, 111,
890 ];
891 assert_eq!(finished.0, expected);
892
893 let mut output = Vec::new();
894 Decoder::new(&finished.0[..])
895 .unwrap()
896 .read_to_end(&mut output)
897 .unwrap();
898 assert_eq!(
899 output,
900 "fooooooooooooooooobarbazfooooooooooooooooobarbaz".as_bytes()
901 );
902 }
903
904 #[test]
905 #[cfg(feature = "std")]
906 fn issue_61() {
908 let data = default_encode(b"Hello World").unwrap();
909 let mut decoder = Decoder::new(&data[..]).unwrap();
910 let mut buf = Vec::new();
911 decoder.read(&mut buf).unwrap();
912 decoder.read_to_end(&mut buf).unwrap();
913 assert_eq!(buf, b"Hello World");
914 }
915
916 #[test]
917 fn issue71() {
918 let encoded_data = [
919 120, 218, 251, 255, 207, 144, 193, 138, 193, 151, 161, 146, 33, 143, 33, 149, 161, 156,
920 161, 24, 72, 38, 51, 148, 48, 100, 50, 228, 3, 69, 120, 25, 184, 24,
921 ];
922
923 let mut decoder = Decoder::new(&encoded_data[..]).unwrap();
924 let mut buf = Vec::new();
925 let result = decoder.read_to_end(&mut buf);
926 assert!(result.is_err());
927 buf.extend_from_slice(decoder.unread_decoded_data());
928
929 let decoded_data = [
930 255, 254, 49, 0, 58, 0, 77, 0, 121, 0, 110, 0, 101, 0, 119, 0, 115, 0, 101, 0, 99, 0,
931 116, 0, 105, 0, 111, 0, 110, 0, 13, 0, 10,
932 ];
933 assert_eq!(buf, decoded_data);
934 }
935
936 #[test]
937 #[cfg(feature = "std")]
938 fn issue_82() {
939 let encoded_data = [0x00, 0x00];
940 let error = Header::read_from(&encoded_data[..]).unwrap_err();
941 assert_eq!(error.kind(), io::ErrorKind::InvalidData);
942 assert!(error.to_string().contains("method=0"));
943 }
944}