1#![allow(non_snake_case)] #![allow(clippy::missing_safety_doc)] use core::ffi::{c_char, c_int, c_long, c_ulong};
5use core::marker::PhantomData;
6use core::mem::MaybeUninit;
7use core::ops::ControlFlow;
8
9mod bitreader;
10mod inffixed_tbl;
11mod inftrees;
12mod window;
13mod writer;
14
15use crate::allocate::Allocator;
16use crate::c_api::internal_state;
17use crate::cpu_features::CpuFeatures;
18use crate::{
19 adler32::adler32,
20 c_api::{gz_header, z_checksum, z_size, z_stream, Z_DEFLATED},
21 inflate::writer::Writer,
22 Code, InflateFlush, ReturnCode, DEF_WBITS, MAX_WBITS, MIN_WBITS,
23};
24
25use crate::crc32::{crc32, Crc32Fold};
26
27use self::{
28 bitreader::BitReader,
29 inftrees::{inflate_table, CodeType, InflateTable},
30 window::Window,
31};
32
33const INFLATE_STRICT: bool = false;
34
35#[repr(C)]
38pub struct InflateStream<'a> {
39 pub(crate) next_in: *mut crate::c_api::Bytef,
40 pub(crate) avail_in: crate::c_api::uInt,
41 pub(crate) total_in: crate::c_api::z_size,
42 pub(crate) next_out: *mut crate::c_api::Bytef,
43 pub(crate) avail_out: crate::c_api::uInt,
44 pub(crate) total_out: crate::c_api::z_size,
45 pub(crate) msg: *mut c_char,
46 pub(crate) state: &'a mut State<'a>,
47 pub(crate) alloc: Allocator<'a>,
48 pub(crate) data_type: c_int,
49 pub(crate) adler: crate::c_api::z_checksum,
50 pub(crate) reserved: crate::c_api::uLong,
51}
52
53#[cfg(feature = "__internal-test")]
54#[doc(hidden)]
55pub const INFLATE_STATE_SIZE: usize = core::mem::size_of::<crate::inflate::State>();
56
57#[cfg(feature = "__internal-test")]
58#[doc(hidden)]
59pub unsafe fn set_mode_dict(strm: &mut z_stream) {
60 unsafe {
61 (*(strm.state as *mut State)).mode = Mode::Dict;
62 }
63}
64
65impl<'a> InflateStream<'a> {
66 const _S: () = assert!(core::mem::size_of::<z_stream>() == core::mem::size_of::<Self>());
69 const _A: () = assert!(core::mem::align_of::<z_stream>() == core::mem::align_of::<Self>());
70
71 #[inline(always)]
80 pub unsafe fn from_stream_ref(strm: *const z_stream) -> Option<&'a Self> {
81 {
82 let stream = unsafe { strm.as_ref() }?;
84
85 if stream.zalloc.is_none() || stream.zfree.is_none() {
86 return None;
87 }
88
89 if stream.state.is_null() {
90 return None;
91 }
92 }
93
94 strm.cast::<InflateStream>().as_ref()
96 }
97
98 #[inline(always)]
107 pub unsafe fn from_stream_mut(strm: *mut z_stream) -> Option<&'a mut Self> {
108 {
109 let stream = unsafe { strm.as_ref() }?;
111
112 if stream.zalloc.is_none() || stream.zfree.is_none() {
113 return None;
114 }
115
116 if stream.state.is_null() {
117 return None;
118 }
119 }
120
121 strm.cast::<InflateStream>().as_mut()
123 }
124
125 fn as_z_stream_mut(&mut self) -> &mut z_stream {
126 unsafe { &mut *(self as *mut _ as *mut z_stream) }
128 }
129}
130
131const MAX_BITS: u8 = 15; const MAX_DIST_EXTRA_BITS: u8 = 13; pub fn uncompress_slice<'a>(
135 output: &'a mut [u8],
136 input: &[u8],
137 config: InflateConfig,
138) -> (&'a mut [u8], ReturnCode) {
139 let output_uninit = unsafe {
141 core::slice::from_raw_parts_mut(output.as_mut_ptr() as *mut MaybeUninit<u8>, output.len())
142 };
143
144 uncompress(output_uninit, input, config)
145}
146
147pub fn uncompress<'a>(
149 output: &'a mut [MaybeUninit<u8>],
150 input: &[u8],
151 config: InflateConfig,
152) -> (&'a mut [u8], ReturnCode) {
153 let mut dest_len_ptr = output.len() as z_checksum;
154
155 let mut buf = [0u8];
157
158 let mut left;
159 let mut len = input.len() as u64;
160
161 let dest = if output.is_empty() {
162 left = 1;
163
164 buf.as_mut_ptr()
165 } else {
166 left = output.len() as u64;
167 dest_len_ptr = 0;
168
169 output.as_mut_ptr() as *mut u8
170 };
171
172 let mut stream = z_stream {
173 next_in: input.as_ptr() as *mut u8,
174 avail_in: 0,
175
176 zalloc: None,
177 zfree: None,
178 opaque: core::ptr::null_mut(),
179
180 ..z_stream::default()
181 };
182
183 let err = init(&mut stream, config);
184 if err != ReturnCode::Ok {
185 return (&mut [], err);
186 }
187
188 stream.next_out = dest;
189 stream.avail_out = 0;
190
191 let Some(stream) = (unsafe { InflateStream::from_stream_mut(&mut stream) }) else {
192 return (&mut [], ReturnCode::StreamError);
193 };
194
195 let err = loop {
196 if stream.avail_out == 0 {
197 stream.avail_out = Ord::min(left, u32::MAX as u64) as u32;
198 left -= stream.avail_out as u64;
199 }
200
201 if stream.avail_in == 0 {
202 stream.avail_in = Ord::min(len, u32::MAX as u64) as u32;
203 len -= stream.avail_in as u64;
204 }
205
206 let err = unsafe { inflate(stream, InflateFlush::NoFlush) };
207
208 if err != ReturnCode::Ok {
209 break err;
210 }
211 };
212
213 if !output.is_empty() {
214 dest_len_ptr = stream.total_out;
215 } else if stream.total_out != 0 && err == ReturnCode::BufError {
216 left = 1;
217 }
218
219 let avail_out = stream.avail_out;
220
221 end(stream);
222
223 let ret = match err {
224 ReturnCode::StreamEnd => ReturnCode::Ok,
225 ReturnCode::NeedDict => ReturnCode::DataError,
226 ReturnCode::BufError if (left + avail_out as u64) != 0 => ReturnCode::DataError,
227 _ => err,
228 };
229
230 let output_slice = unsafe {
232 core::slice::from_raw_parts_mut(output.as_mut_ptr() as *mut u8, dest_len_ptr as usize)
233 };
234
235 (output_slice, ret)
236}
237
238#[derive(Debug, Clone, Copy)]
239#[repr(u8)]
240pub enum Mode {
241 Head,
242 Flags,
243 Time,
244 Os,
245 ExLen,
246 Extra,
247 Name,
248 Comment,
249 HCrc,
250 Sync,
251 Mem,
252 Length,
253 Type,
254 TypeDo,
255 Stored,
256 CopyBlock,
257 Check,
258 Len_,
259 Len,
260 Lit,
261 LenExt,
262 Dist,
263 DistExt,
264 Match,
265 Table,
266 LenLens,
267 CodeLens,
268 DictId,
269 Dict,
270 Done,
271 Bad,
272}
273
274#[derive(Default, Clone, Copy)]
275#[allow(clippy::enum_variant_names)]
276enum Codes {
277 #[default]
278 Fixed,
279 Codes,
280 Len,
281 Dist,
282}
283
284#[derive(Default, Clone, Copy)]
285struct Table {
286 codes: Codes,
287 bits: usize,
288}
289
290#[derive(Clone, Copy)]
291struct Flags(u8);
292
293impl Default for Flags {
294 fn default() -> Self {
295 Self::SANE
296 }
297}
298
299impl Flags {
300 const IS_LAST_BLOCK: Self = Self(0b0000_0001);
302
303 const HAVE_DICT: Self = Self(0b0000_0010);
305
306 const SANE: Self = Self(0b0000_0100);
308
309 pub(crate) const fn contains(self, other: Self) -> bool {
310 debug_assert!(other.0.count_ones() == 1);
311
312 self.0 & other.0 != 0
313 }
314
315 #[inline(always)]
316 pub(crate) fn update(&mut self, other: Self, value: bool) {
317 if value {
318 *self = Self(self.0 | other.0);
319 } else {
320 *self = Self(self.0 & !other.0);
321 }
322 }
323}
324
325#[repr(C, align(64))]
326pub(crate) struct State<'a> {
327 mode: Mode,
329
330 flags: Flags,
331
332 wbits: u8,
334
335 wrap: u8,
341
342 flush: InflateFlush,
343
344 window: Window<'a>,
346
347 ncode: usize,
350 nlen: usize,
352 ndist: usize,
354 have: usize,
356 next: usize, bit_reader: BitReader<'a>,
361
362 writer: Writer<'a>,
363 total: usize,
364
365 length: usize,
367 offset: usize,
369
370 extra: usize,
372
373 back: usize,
375
376 was: usize,
378
379 chunksize: usize,
381
382 in_available: usize,
383 out_available: usize,
384
385 gzip_flags: i32,
386
387 checksum: u32,
388 crc_fold: Crc32Fold,
389
390 error_message: Option<&'static str>,
391
392 head: Option<&'a mut gz_header>,
394 dmax: usize,
395
396 len_table: Table,
398
399 dist_table: Table,
401
402 codes_codes: [Code; crate::ENOUGH_LENS],
403 len_codes: [Code; crate::ENOUGH_LENS],
404 dist_codes: [Code; crate::ENOUGH_DISTS],
405
406 lens: [u16; 320],
408 work: [u16; 288],
410}
411
412impl<'a> State<'a> {
413 fn new(reader: &'a [u8], writer: Writer<'a>) -> Self {
414 let in_available = reader.len();
415 let out_available = writer.capacity();
416
417 Self {
418 flush: InflateFlush::NoFlush,
419
420 flags: Flags::default(),
421 wrap: 0,
422 mode: Mode::Head,
423 length: 0,
424
425 len_table: Table::default(),
426 dist_table: Table::default(),
427
428 wbits: 0,
429 offset: 0,
430 extra: 0,
431 back: 0,
432 was: 0,
433 chunksize: 0,
434 in_available,
435 out_available,
436
437 bit_reader: BitReader::new(reader),
438
439 writer,
440 total: 0,
441
442 window: Window::empty(),
443 head: None,
444
445 lens: [0u16; 320],
446 work: [0u16; 288],
447
448 ncode: 0,
449 nlen: 0,
450 ndist: 0,
451 have: 0,
452 next: 0,
453
454 error_message: None,
455
456 checksum: 0,
457 crc_fold: Crc32Fold::new(),
458
459 dmax: 0,
460 gzip_flags: 0,
461
462 codes_codes: [Code::default(); crate::ENOUGH_LENS],
463 len_codes: [Code::default(); crate::ENOUGH_LENS],
464 dist_codes: [Code::default(); crate::ENOUGH_DISTS],
465 }
466 }
467
468 fn len_table_ref(&self) -> &[Code] {
469 match self.len_table.codes {
470 Codes::Fixed => &self::inffixed_tbl::LENFIX,
471 Codes::Codes => &self.codes_codes,
472 Codes::Len => &self.len_codes,
473 Codes::Dist => &self.dist_codes,
474 }
475 }
476
477 fn dist_table_ref(&self) -> &[Code] {
478 match self.dist_table.codes {
479 Codes::Fixed => &self::inffixed_tbl::DISTFIX,
480 Codes::Codes => &self.codes_codes,
481 Codes::Len => &self.len_codes,
482 Codes::Dist => &self.dist_codes,
483 }
484 }
485
486 fn len_table_get(&self, index: usize) -> Code {
487 self.len_table_ref()[index]
488 }
489
490 fn dist_table_get(&self, index: usize) -> Code {
491 self.dist_table_ref()[index]
492 }
493}
494
495macro_rules! pull_byte {
496 ($self:expr) => {
497 match $self.bit_reader.pull_byte() {
498 Err(return_code) => return $self.inflate_leave(return_code),
499 Ok(_) => (),
500 }
501 };
502}
503
504macro_rules! need_bits {
505 ($self:expr, $n:expr) => {
506 match $self.bit_reader.need_bits($n) {
507 Err(return_code) => return $self.inflate_leave(return_code),
508 Ok(v) => v,
509 }
510 };
511}
512
513const fn zswap32(q: u32) -> u32 {
515 u32::from_be(q.to_le())
516}
517
518const INFLATE_FAST_MIN_HAVE: usize = 15;
519const INFLATE_FAST_MIN_LEFT: usize = 260;
520
521impl State<'_> {
522 fn len_and_friends(&mut self) -> ControlFlow<ReturnCode, ()> {
532 let avail_in = self.bit_reader.bytes_remaining();
533 let avail_out = self.writer.remaining();
534
535 if avail_in >= INFLATE_FAST_MIN_HAVE && avail_out >= INFLATE_FAST_MIN_LEFT {
536 inflate_fast_help(self, 0);
537 match self.mode {
538 Mode::Len => {}
539 _ => return ControlFlow::Continue(()),
540 }
541 }
542
543 let mut mode;
544 let mut writer;
545 let mut bit_reader;
546
547 macro_rules! load {
548 () => {
549 mode = self.mode;
550 writer = core::mem::replace(&mut self.writer, Writer::new(&mut []));
551 bit_reader = self.bit_reader;
552 };
553 }
554
555 macro_rules! restore {
556 () => {
557 self.mode = mode;
558 self.writer = writer;
559 self.bit_reader = bit_reader;
560 };
561 }
562
563 load!();
564
565 let len_table = match self.len_table.codes {
566 Codes::Fixed => &self::inffixed_tbl::LENFIX[..],
567 Codes::Codes => &self.codes_codes,
568 Codes::Len => &self.len_codes,
569 Codes::Dist => &self.dist_codes,
570 };
571
572 let dist_table = match self.dist_table.codes {
573 Codes::Fixed => &self::inffixed_tbl::DISTFIX[..],
574 Codes::Codes => &self.codes_codes,
575 Codes::Len => &self.len_codes,
576 Codes::Dist => &self.dist_codes,
577 };
578
579 'top: loop {
580 match mode {
581 Mode::Len => {
582 let avail_in = bit_reader.bytes_remaining();
583 let avail_out = writer.remaining();
584
585 if avail_in >= INFLATE_FAST_MIN_HAVE && avail_out >= INFLATE_FAST_MIN_LEFT {
590 restore!();
591 inflate_fast_help(self, 0);
592 return ControlFlow::Continue(());
593 }
594
595 self.back = 0;
596
597 let mut here;
599 loop {
600 let bits = bit_reader.bits(self.len_table.bits);
601 here = len_table[bits as usize];
602
603 if here.bits <= bit_reader.bits_in_buffer() {
604 break;
605 }
606
607 if let Err(return_code) = bit_reader.pull_byte() {
608 restore!();
609 return ControlFlow::Break(return_code);
610 };
611 }
612
613 if here.op != 0 && here.op & 0xf0 == 0 {
614 let last = here;
615 loop {
616 let bits = bit_reader.bits((last.bits + last.op) as usize) as u16;
617 here = len_table[(last.val + (bits >> last.bits)) as usize];
618 if last.bits + here.bits <= bit_reader.bits_in_buffer() {
619 break;
620 }
621
622 if let Err(return_code) = bit_reader.pull_byte() {
623 restore!();
624 return ControlFlow::Break(return_code);
625 };
626 }
627
628 bit_reader.drop_bits(last.bits);
629 self.back += last.bits as usize;
630 }
631
632 bit_reader.drop_bits(here.bits);
633 self.back += here.bits as usize;
634 self.length = here.val as usize;
635
636 if here.op == 0 {
637 mode = Mode::Lit;
638 continue 'top;
639 } else if here.op & 32 != 0 {
640 self.back = usize::MAX;
645 mode = Mode::Type;
646
647 restore!();
648 return ControlFlow::Continue(());
649 } else if here.op & 64 != 0 {
650 mode = Mode::Bad;
651 {
652 restore!();
653 let this = &mut *self;
654 let msg: &'static str = "invalid literal/length code\0";
655 #[cfg(all(feature = "std", test))]
656 dbg!(msg);
657 this.error_message = Some(msg);
658 return ControlFlow::Break(ReturnCode::DataError);
659 }
660 } else {
661 self.extra = (here.op & MAX_BITS) as usize;
663 mode = Mode::LenExt;
664 continue 'top;
665 }
666 }
667 Mode::Lit => {
668 if writer.is_full() {
670 restore!();
671 #[cfg(all(test, feature = "std"))]
672 eprintln!("Ok: writer is full ({} bytes)", self.writer.capacity());
673 return ControlFlow::Break(ReturnCode::Ok);
674 }
675
676 writer.push(self.length as u8);
677
678 mode = Mode::Len;
679
680 continue 'top;
681 }
682 Mode::LenExt => {
683 let extra = self.extra;
685
686 if extra != 0 {
688 match bit_reader.need_bits(extra) {
689 Err(return_code) => {
690 restore!();
691 return ControlFlow::Break(return_code);
692 }
693 Ok(v) => v,
694 };
695 self.length += bit_reader.bits(extra) as usize;
696 bit_reader.drop_bits(extra as u8);
697 self.back += extra;
698 }
699
700 self.was = self.length;
703 mode = Mode::Dist;
704
705 continue 'top;
706 }
707 Mode::Dist => {
708 let mut here;
712 loop {
713 let bits = bit_reader.bits(self.dist_table.bits) as usize;
714 here = dist_table[bits];
715 if here.bits <= bit_reader.bits_in_buffer() {
716 break;
717 }
718
719 if let Err(return_code) = bit_reader.pull_byte() {
720 restore!();
721 return ControlFlow::Break(return_code);
722 };
723 }
724
725 if here.op & 0xf0 == 0 {
726 let last = here;
727
728 loop {
729 let bits = bit_reader.bits((last.bits + last.op) as usize);
730 here = dist_table[last.val as usize + ((bits as usize) >> last.bits)];
731
732 if last.bits + here.bits <= bit_reader.bits_in_buffer() {
733 break;
734 }
735
736 if let Err(return_code) = bit_reader.pull_byte() {
737 restore!();
738 return ControlFlow::Break(return_code);
739 };
740 }
741
742 bit_reader.drop_bits(last.bits);
743 self.back += last.bits as usize;
744 }
745
746 bit_reader.drop_bits(here.bits);
747
748 if here.op & 64 != 0 {
749 restore!();
750 self.mode = Mode::Bad;
751 return ControlFlow::Break(self.bad("invalid distance code\0"));
752 }
753
754 self.offset = here.val as usize;
755
756 self.extra = (here.op & MAX_BITS) as usize;
757 mode = Mode::DistExt;
758
759 continue 'top;
760 }
761 Mode::DistExt => {
762 let extra = self.extra;
764
765 if extra > 0 {
766 match bit_reader.need_bits(extra) {
767 Err(return_code) => {
768 restore!();
769 return ControlFlow::Break(return_code);
770 }
771 Ok(v) => v,
772 };
773 self.offset += bit_reader.bits(extra) as usize;
774 bit_reader.drop_bits(extra as u8);
775 self.back += extra;
776 }
777
778 if INFLATE_STRICT && self.offset > self.dmax {
779 restore!();
780 self.mode = Mode::Bad;
781 return ControlFlow::Break(
782 self.bad("invalid distance code too far back\0"),
783 );
784 }
785
786 mode = Mode::Match;
789
790 continue 'top;
791 }
792 Mode::Match => {
793 if writer.is_full() {
795 restore!();
796 #[cfg(all(feature = "std", test))]
797 eprintln!(
798 "BufError: writer is full ({} bytes)",
799 self.writer.capacity()
800 );
801 return ControlFlow::Break(ReturnCode::Ok);
802 }
803
804 let left = writer.remaining();
805 let copy = writer.len();
806
807 let copy = if self.offset > copy {
808 let mut copy = self.offset - copy;
811
812 if copy > self.window.have() {
813 if self.flags.contains(Flags::SANE) {
814 restore!();
815 self.mode = Mode::Bad;
816 return ControlFlow::Break(
817 self.bad("invalid distance too far back\0"),
818 );
819 }
820
821 panic!("INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR")
823 }
824
825 let wnext = self.window.next();
826 let wsize = self.window.size();
827
828 let from = if copy > wnext {
829 copy -= wnext;
830 wsize - copy
831 } else {
832 wnext - copy
833 };
834
835 copy = Ord::min(copy, self.length);
836 copy = Ord::min(copy, left);
837
838 writer.extend_from_window(&self.window, from..from + copy);
839
840 copy
841 } else {
842 let copy = Ord::min(self.length, left);
843 writer.copy_match(self.offset, copy);
844
845 copy
846 };
847
848 self.length -= copy;
849
850 if self.length == 0 {
851 mode = Mode::Len;
852 continue 'top;
853 } else {
854 continue 'top;
857 }
858 }
859 _ => unsafe { core::hint::unreachable_unchecked() },
860 }
861 }
862 }
863
864 fn dispatch(&mut self) -> ReturnCode {
865 'label: loop {
866 match self.mode {
867 Mode::Head => {
868 if self.wrap == 0 {
869 self.mode = Mode::TypeDo;
870
871 continue 'label;
872 }
873
874 need_bits!(self, 16);
875
876 if (self.wrap & 2) != 0 && self.bit_reader.hold() == 0x8b1f {
878 if self.wbits == 0 {
879 self.wbits = 15;
880 }
881
882 let b0 = self.bit_reader.bits(8) as u8;
883 let b1 = (self.bit_reader.hold() >> 8) as u8;
884 self.checksum = crc32(crate::CRC32_INITIAL_VALUE, &[b0, b1]);
885 self.bit_reader.init_bits();
886
887 self.mode = Mode::Flags;
888
889 continue 'label;
890 }
891
892 if let Some(header) = &mut self.head {
893 header.done = -1;
894 }
895
896 if (self.wrap & 1) == 0
898 || ((self.bit_reader.bits(8) << 8) + (self.bit_reader.hold() >> 8)) % 31
899 != 0
900 {
901 self.mode = Mode::Bad;
902 break 'label self.bad("incorrect header check\0");
903 }
904
905 if self.bit_reader.bits(4) != Z_DEFLATED as u64 {
906 self.mode = Mode::Bad;
907 break 'label self.bad("unknown compression method\0");
908 }
909
910 self.bit_reader.drop_bits(4);
911 let len = self.bit_reader.bits(4) as u8 + 8;
912
913 if self.wbits == 0 {
914 self.wbits = len;
915 }
916
917 if len as i32 > MAX_WBITS || len > self.wbits {
918 self.mode = Mode::Bad;
919 break 'label self.bad("invalid window size\0");
920 }
921
922 self.dmax = 1 << len;
923 self.gzip_flags = 0; self.checksum = crate::ADLER32_INITIAL_VALUE as _;
925
926 if self.bit_reader.hold() & 0x200 != 0 {
927 self.bit_reader.init_bits();
928
929 self.mode = Mode::DictId;
930
931 continue 'label;
932 } else {
933 self.bit_reader.init_bits();
934
935 self.mode = Mode::Type;
936
937 continue 'label;
938 }
939 }
940 Mode::Flags => {
941 need_bits!(self, 16);
942 self.gzip_flags = self.bit_reader.hold() as i32;
943
944 if self.gzip_flags & 0xff != Z_DEFLATED {
946 self.mode = Mode::Bad;
947 break 'label self.bad("unknown compression method\0");
948 }
949
950 if self.gzip_flags & 0xe000 != 0 {
951 self.mode = Mode::Bad;
952 break 'label self.bad("unknown header flags set\0");
953 }
954
955 if let Some(head) = self.head.as_mut() {
956 head.text = ((self.bit_reader.hold() >> 8) & 1) as i32;
957 }
958
959 if (self.gzip_flags & 0x0200) != 0 && (self.wrap & 4) != 0 {
960 let b0 = self.bit_reader.bits(8) as u8;
961 let b1 = (self.bit_reader.hold() >> 8) as u8;
962 self.checksum = crc32(self.checksum, &[b0, b1]);
963 }
964
965 self.bit_reader.init_bits();
966 self.mode = Mode::Time;
967
968 continue 'label;
969 }
970 Mode::Time => {
971 need_bits!(self, 32);
972 if let Some(head) = self.head.as_mut() {
973 head.time = self.bit_reader.hold() as z_size;
974 }
975
976 if (self.gzip_flags & 0x0200) != 0 && (self.wrap & 4) != 0 {
977 let bytes = (self.bit_reader.hold() as u32).to_le_bytes();
978 self.checksum = crc32(self.checksum, &bytes);
979 }
980
981 self.bit_reader.init_bits();
982 self.mode = Mode::Os;
983
984 continue 'label;
985 }
986 Mode::Os => {
987 need_bits!(self, 16);
988 if let Some(head) = self.head.as_mut() {
989 head.xflags = (self.bit_reader.hold() & 0xff) as i32;
990 head.os = (self.bit_reader.hold() >> 8) as i32;
991 }
992
993 if (self.gzip_flags & 0x0200) != 0 && (self.wrap & 4) != 0 {
994 let bytes = (self.bit_reader.hold() as u16).to_le_bytes();
995 self.checksum = crc32(self.checksum, &bytes);
996 }
997
998 self.bit_reader.init_bits();
999 self.mode = Mode::ExLen;
1000
1001 continue 'label;
1002 }
1003 Mode::ExLen => {
1004 if (self.gzip_flags & 0x0400) != 0 {
1005 need_bits!(self, 16);
1006
1007 self.length = self.bit_reader.hold() as usize;
1009 if let Some(head) = self.head.as_mut() {
1010 head.extra_len = self.length as u32;
1011 }
1012
1013 if (self.gzip_flags & 0x0200) != 0 && (self.wrap & 4) != 0 {
1014 let bytes = (self.bit_reader.hold() as u16).to_le_bytes();
1015 self.checksum = crc32(self.checksum, &bytes);
1016 }
1017 self.bit_reader.init_bits();
1018 } else if let Some(head) = self.head.as_mut() {
1019 head.extra = core::ptr::null_mut();
1020 }
1021
1022 self.mode = Mode::Extra;
1023
1024 continue 'label;
1025 }
1026 Mode::Extra => {
1027 if (self.gzip_flags & 0x0400) != 0 {
1028 let extra_available =
1030 Ord::min(self.length, self.bit_reader.bytes_remaining());
1031
1032 if extra_available > 0 {
1033 if let Some(head) = self.head.as_mut() {
1034 if !head.extra.is_null() {
1035 let written_so_far = head.extra_len as usize - self.length;
1042
1043 let count = Ord::min(
1045 (head.extra_max as usize).saturating_sub(written_so_far),
1046 extra_available,
1047 );
1048
1049 let next_write_offset =
1052 Ord::min(written_so_far, head.extra_max as usize);
1053
1054 unsafe {
1055 core::ptr::copy_nonoverlapping(
1059 self.bit_reader.as_mut_ptr(),
1060 head.extra.add(next_write_offset),
1061 count,
1062 );
1063 }
1064 }
1065 }
1066
1067 if (self.gzip_flags & 0x0200) != 0 && (self.wrap & 4) != 0 {
1069 let extra_slice = &self.bit_reader.as_slice()[..extra_available];
1070 self.checksum = crc32(self.checksum, extra_slice)
1071 }
1072
1073 self.in_available -= extra_available;
1074 self.bit_reader.advance(extra_available);
1075 self.length -= extra_available;
1076 }
1077
1078 if self.length != 0 {
1080 break 'label self.inflate_leave(ReturnCode::Ok);
1081 }
1082 }
1083
1084 self.length = 0;
1085 self.mode = Mode::Name;
1086
1087 continue 'label;
1088 }
1089 Mode::Name => {
1090 if (self.gzip_flags & 0x0800) != 0 {
1091 if self.in_available == 0 {
1092 break 'label self.inflate_leave(ReturnCode::Ok);
1093 }
1094
1095 let slice = self.bit_reader.as_slice();
1098 let null_terminator_index = slice.iter().position(|c| *c == 0);
1099
1100 let name_slice = match null_terminator_index {
1102 Some(i) => &slice[..=i],
1103 None => slice,
1104 };
1105
1106 if let Some(head) = self.head.as_mut() {
1108 if !head.name.is_null() {
1109 let remaining_name_bytes = (head.name_max as usize)
1110 .checked_sub(self.length)
1111 .expect("name out of bounds");
1112 let copy = Ord::min(name_slice.len(), remaining_name_bytes);
1113
1114 unsafe {
1115 core::ptr::copy_nonoverlapping(
1118 name_slice.as_ptr(),
1119 head.name.add(self.length),
1120 copy,
1121 )
1122 };
1123
1124 self.length += copy;
1125 }
1126 }
1127
1128 if (self.gzip_flags & 0x0200) != 0 && (self.wrap & 4) != 0 {
1129 self.checksum = crc32(self.checksum, name_slice);
1130 }
1131
1132 let reached_end = name_slice.last() == Some(&0);
1133 self.bit_reader.advance(name_slice.len());
1134
1135 if !reached_end && self.bit_reader.bytes_remaining() == 0 {
1136 break 'label self.inflate_leave(ReturnCode::Ok);
1137 }
1138 } else if let Some(head) = self.head.as_mut() {
1139 head.name = core::ptr::null_mut();
1140 }
1141
1142 self.length = 0;
1143 self.mode = Mode::Comment;
1144
1145 continue 'label;
1146 }
1147 Mode::Comment => {
1148 if (self.gzip_flags & 0x01000) != 0 {
1149 if self.in_available == 0 {
1150 break 'label self.inflate_leave(ReturnCode::Ok);
1151 }
1152
1153 let slice = self.bit_reader.as_slice();
1156 let null_terminator_index = slice.iter().position(|c| *c == 0);
1157
1158 let comment_slice = match null_terminator_index {
1160 Some(i) => &slice[..=i],
1161 None => slice,
1162 };
1163
1164 if let Some(head) = self.head.as_mut() {
1166 if !head.comment.is_null() {
1167 let remaining_comm_bytes = (head.comm_max as usize)
1168 .checked_sub(self.length)
1169 .expect("comm out of bounds");
1170 let copy = Ord::min(comment_slice.len(), remaining_comm_bytes);
1171
1172 unsafe {
1173 core::ptr::copy_nonoverlapping(
1176 comment_slice.as_ptr(),
1177 head.comment.add(self.length),
1178 copy,
1179 )
1180 };
1181
1182 self.length += copy;
1183 }
1184 }
1185
1186 if (self.gzip_flags & 0x0200) != 0 && (self.wrap & 4) != 0 {
1187 self.checksum = crc32(self.checksum, comment_slice);
1188 }
1189
1190 let reached_end = comment_slice.last() == Some(&0);
1191 self.bit_reader.advance(comment_slice.len());
1192
1193 if !reached_end && self.bit_reader.bytes_remaining() == 0 {
1194 break 'label self.inflate_leave(ReturnCode::Ok);
1195 }
1196 } else if let Some(head) = self.head.as_mut() {
1197 head.comment = core::ptr::null_mut();
1198 }
1199
1200 self.mode = Mode::HCrc;
1201
1202 continue 'label;
1203 }
1204 Mode::HCrc => {
1205 if (self.gzip_flags & 0x0200) != 0 {
1206 need_bits!(self, 16);
1207
1208 if (self.wrap & 4) != 0
1209 && self.bit_reader.hold() as u32 != (self.checksum & 0xffff)
1210 {
1211 self.mode = Mode::Bad;
1212 break 'label self.bad("header crc mismatch\0");
1213 }
1214
1215 self.bit_reader.init_bits();
1216 }
1217
1218 if let Some(head) = self.head.as_mut() {
1219 head.hcrc = (self.gzip_flags >> 9) & 1;
1220 head.done = 1;
1221 }
1222
1223 if (self.wrap & 4 != 0) && self.gzip_flags != 0 {
1225 self.crc_fold = Crc32Fold::new();
1226 self.checksum = crate::CRC32_INITIAL_VALUE;
1227 }
1228
1229 self.mode = Mode::Type;
1230
1231 continue 'label;
1232 }
1233 Mode::Type => {
1234 use InflateFlush::*;
1235
1236 match self.flush {
1237 Block | Trees => break 'label ReturnCode::Ok,
1238 NoFlush | SyncFlush | Finish => {
1239 self.mode = Mode::TypeDo;
1241 continue 'label;
1242 }
1243 }
1244 }
1245 Mode::TypeDo => {
1246 if self.flags.contains(Flags::IS_LAST_BLOCK) {
1247 self.bit_reader.next_byte_boundary();
1248 self.mode = Mode::Check;
1249
1250 continue 'label;
1251 }
1252
1253 need_bits!(self, 3);
1254 self.flags
1256 .update(Flags::IS_LAST_BLOCK, self.bit_reader.bits(1) != 0);
1257 self.bit_reader.drop_bits(1);
1258
1259 match self.bit_reader.bits(2) {
1260 0b00 => {
1261 self.bit_reader.drop_bits(2);
1264
1265 self.mode = Mode::Stored;
1266
1267 continue 'label;
1268 }
1269 0b01 => {
1270 self.len_table = Table {
1273 codes: Codes::Fixed,
1274 bits: 9,
1275 };
1276
1277 self.dist_table = Table {
1278 codes: Codes::Fixed,
1279 bits: 5,
1280 };
1281
1282 self.mode = Mode::Len_;
1283
1284 self.bit_reader.drop_bits(2);
1285
1286 if let InflateFlush::Trees = self.flush {
1287 break 'label self.inflate_leave(ReturnCode::Ok);
1288 } else {
1289 continue 'label;
1290 }
1291 }
1292 0b10 => {
1293 self.bit_reader.drop_bits(2);
1296
1297 self.mode = Mode::Table;
1298
1299 continue 'label;
1300 }
1301 0b11 => {
1302 self.bit_reader.drop_bits(2);
1305
1306 self.mode = Mode::Bad;
1307 break 'label self.bad("invalid block type\0");
1308 }
1309 _ => {
1310 unreachable!("BitReader::bits(2) only yields a value of two bits, so this match is already exhaustive")
1312 }
1313 }
1314 }
1315 Mode::Stored => {
1316 self.bit_reader.next_byte_boundary();
1317
1318 need_bits!(self, 32);
1319
1320 let hold = self.bit_reader.bits(32) as u32;
1321
1322 if hold as u16 != !((hold >> 16) as u16) {
1325 self.mode = Mode::Bad;
1326 break 'label self.bad("invalid stored block lengths\0");
1327 }
1328
1329 self.length = hold as usize & 0xFFFF;
1330 self.bit_reader.init_bits();
1333
1334 if let InflateFlush::Trees = self.flush {
1335 break 'label self.inflate_leave(ReturnCode::Ok);
1336 } else {
1337 self.mode = Mode::CopyBlock;
1338
1339 continue 'label;
1340 }
1341 }
1342 Mode::CopyBlock => {
1343 loop {
1344 let mut copy = self.length;
1345
1346 if copy == 0 {
1347 break;
1348 }
1349
1350 copy = Ord::min(copy, self.writer.remaining());
1351 copy = Ord::min(copy, self.bit_reader.bytes_remaining());
1352
1353 if copy == 0 {
1354 break 'label self.inflate_leave(ReturnCode::Ok);
1355 }
1356
1357 self.writer.extend(&self.bit_reader.as_slice()[..copy]);
1358 self.bit_reader.advance(copy);
1359
1360 self.length -= copy;
1361 }
1362
1363 self.mode = Mode::Type;
1364
1365 continue 'label;
1366 }
1367 Mode::Check => {
1368 if !cfg!(feature = "__internal-fuzz-disable-checksum") && self.wrap != 0 {
1369 need_bits!(self, 32);
1370
1371 self.total += self.writer.len();
1372
1373 if self.wrap & 4 != 0 {
1374 if self.gzip_flags != 0 {
1375 self.crc_fold.fold(self.writer.filled(), self.checksum);
1376 self.checksum = self.crc_fold.finish();
1377 } else {
1378 self.checksum = adler32(self.checksum, self.writer.filled());
1379 }
1380 }
1381
1382 let given_checksum = if self.gzip_flags != 0 {
1383 self.bit_reader.hold() as u32
1384 } else {
1385 zswap32(self.bit_reader.hold() as u32)
1386 };
1387
1388 self.out_available = self.writer.capacity() - self.writer.len();
1389
1390 if self.wrap & 4 != 0 && given_checksum != self.checksum {
1391 self.mode = Mode::Bad;
1392 break 'label self.bad("incorrect data check\0");
1393 }
1394
1395 self.bit_reader.init_bits();
1396 }
1397 self.mode = Mode::Length;
1398
1399 continue 'label;
1400 }
1401 Mode::Len_ => {
1402 self.mode = Mode::Len;
1403
1404 continue 'label;
1405 }
1406 Mode::Len => match self.len_and_friends() {
1407 ControlFlow::Break(return_code) => break 'label return_code,
1408 ControlFlow::Continue(()) => continue 'label,
1409 },
1410 Mode::LenExt => {
1411 let extra = self.extra;
1413
1414 if extra != 0 {
1416 need_bits!(self, extra);
1417 self.length += self.bit_reader.bits(extra) as usize;
1418 self.bit_reader.drop_bits(extra as u8);
1419 self.back += extra;
1420 }
1421
1422 self.was = self.length;
1425 self.mode = Mode::Dist;
1426
1427 continue 'label;
1428 }
1429 Mode::Lit => {
1430 if self.writer.is_full() {
1432 #[cfg(all(test, feature = "std"))]
1433 eprintln!("Ok: writer is full ({} bytes)", self.writer.capacity());
1434 break 'label self.inflate_leave(ReturnCode::Ok);
1435 }
1436
1437 self.writer.push(self.length as u8);
1438
1439 self.mode = Mode::Len;
1440
1441 continue 'label;
1442 }
1443 Mode::Dist => {
1444 let mut here;
1448 loop {
1449 let bits = self.bit_reader.bits(self.dist_table.bits) as usize;
1450 here = self.dist_table_get(bits);
1451 if here.bits <= self.bit_reader.bits_in_buffer() {
1452 break;
1453 }
1454
1455 pull_byte!(self);
1456 }
1457
1458 if here.op & 0xf0 == 0 {
1459 let last = here;
1460
1461 loop {
1462 let bits = self.bit_reader.bits((last.bits + last.op) as usize);
1463 here = self
1464 .dist_table_get(last.val as usize + ((bits as usize) >> last.bits));
1465
1466 if last.bits + here.bits <= self.bit_reader.bits_in_buffer() {
1467 break;
1468 }
1469
1470 pull_byte!(self);
1471 }
1472
1473 self.bit_reader.drop_bits(last.bits);
1474 self.back += last.bits as usize;
1475 }
1476
1477 self.bit_reader.drop_bits(here.bits);
1478
1479 if here.op & 64 != 0 {
1480 self.mode = Mode::Bad;
1481 break 'label self.bad("invalid distance code\0");
1482 }
1483
1484 self.offset = here.val as usize;
1485
1486 self.extra = (here.op & MAX_BITS) as usize;
1487 self.mode = Mode::DistExt;
1488
1489 continue 'label;
1490 }
1491 Mode::DistExt => {
1492 let extra = self.extra;
1494
1495 if extra > 0 {
1496 need_bits!(self, extra);
1497 self.offset += self.bit_reader.bits(extra) as usize;
1498 self.bit_reader.drop_bits(extra as u8);
1499 self.back += extra;
1500 }
1501
1502 if INFLATE_STRICT && self.offset > self.dmax {
1503 self.mode = Mode::Bad;
1504 break 'label self.bad("invalid distance code too far back\0");
1505 }
1506
1507 self.mode = Mode::Match;
1510
1511 continue 'label;
1512 }
1513 Mode::Match => {
1514 'match_: loop {
1517 if self.writer.is_full() {
1518 #[cfg(all(feature = "std", test))]
1519 eprintln!(
1520 "BufError: writer is full ({} bytes)",
1521 self.writer.capacity()
1522 );
1523 break 'label self.inflate_leave(ReturnCode::Ok);
1524 }
1525
1526 let left = self.writer.remaining();
1527 let copy = self.writer.len();
1528
1529 let copy = if self.offset > copy {
1530 let mut copy = self.offset - copy;
1533
1534 if copy > self.window.have() {
1535 if self.flags.contains(Flags::SANE) {
1536 self.mode = Mode::Bad;
1537 break 'label self.bad("invalid distance too far back\0");
1538 }
1539
1540 panic!("INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR")
1542 }
1543
1544 let wnext = self.window.next();
1545 let wsize = self.window.size();
1546
1547 let from = if copy > wnext {
1548 copy -= wnext;
1549 wsize - copy
1550 } else {
1551 wnext - copy
1552 };
1553
1554 copy = Ord::min(copy, self.length);
1555 copy = Ord::min(copy, left);
1556
1557 self.writer
1558 .extend_from_window(&self.window, from..from + copy);
1559
1560 copy
1561 } else {
1562 let copy = Ord::min(self.length, left);
1563 self.writer.copy_match(self.offset, copy);
1564
1565 copy
1566 };
1567
1568 self.length -= copy;
1569
1570 if self.length == 0 {
1571 self.mode = Mode::Len;
1572
1573 continue 'label;
1574 } else {
1575 continue 'match_;
1577 }
1578 }
1579 }
1580 Mode::Done => todo!(),
1581 Mode::Table => {
1582 need_bits!(self, 14);
1583 self.nlen = self.bit_reader.bits(5) as usize + 257;
1584 self.bit_reader.drop_bits(5);
1585 self.ndist = self.bit_reader.bits(5) as usize + 1;
1586 self.bit_reader.drop_bits(5);
1587 self.ncode = self.bit_reader.bits(4) as usize + 4;
1588 self.bit_reader.drop_bits(4);
1589
1590 if self.nlen > 286 || self.ndist > 30 {
1592 self.mode = Mode::Bad;
1593 break 'label self.bad("too many length or distance symbols\0");
1594 }
1595
1596 self.have = 0;
1597 self.mode = Mode::LenLens;
1598
1599 continue 'label;
1600 }
1601 Mode::LenLens => {
1602 const ORDER: [u16; 19] = [
1604 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15,
1605 ];
1606
1607 while self.have < self.ncode {
1608 need_bits!(self, 3);
1609 self.lens[ORDER[self.have] as usize] = self.bit_reader.bits(3) as u16;
1610 self.have += 1;
1611 self.bit_reader.drop_bits(3);
1612 }
1613
1614 while self.have < 19 {
1615 self.lens[ORDER[self.have] as usize] = 0;
1616 self.have += 1;
1617 }
1618
1619 self.len_table.bits = 7;
1620
1621 let InflateTable::Success(root) = inflate_table(
1622 CodeType::Codes,
1623 &self.lens,
1624 19,
1625 &mut self.codes_codes,
1626 self.len_table.bits,
1627 &mut self.work,
1628 ) else {
1629 self.mode = Mode::Bad;
1630 break 'label self.bad("invalid code lengths set\0");
1631 };
1632
1633 self.len_table.codes = Codes::Codes;
1634 self.len_table.bits = root;
1635
1636 self.have = 0;
1637 self.mode = Mode::CodeLens;
1638
1639 continue 'label;
1640 }
1641 Mode::CodeLens => {
1642 while self.have < self.nlen + self.ndist {
1643 let here = loop {
1644 let bits = self.bit_reader.bits(self.len_table.bits);
1645 let here = self.len_table_get(bits as usize);
1646 if here.bits <= self.bit_reader.bits_in_buffer() {
1647 break here;
1648 }
1649
1650 pull_byte!(self);
1651 };
1652
1653 let here_bits = here.bits;
1654
1655 match here.val {
1656 0..=15 => {
1657 self.bit_reader.drop_bits(here_bits);
1658 self.lens[self.have] = here.val;
1659 self.have += 1;
1660 }
1661 16 => {
1662 need_bits!(self, here_bits as usize + 2);
1663 self.bit_reader.drop_bits(here_bits);
1664 if self.have == 0 {
1665 self.mode = Mode::Bad;
1666 break 'label self.bad("invalid bit length repeat\0");
1667 }
1668
1669 let len = self.lens[self.have - 1];
1670 let copy = 3 + self.bit_reader.bits(2) as usize;
1671 self.bit_reader.drop_bits(2);
1672
1673 if self.have + copy > self.nlen + self.ndist {
1674 self.mode = Mode::Bad;
1675 break 'label self.bad("invalid bit length repeat\0");
1676 }
1677
1678 for _ in 0..copy {
1679 self.lens[self.have] = len;
1680 self.have += 1;
1681 }
1682 }
1683 17 => {
1684 need_bits!(self, here_bits as usize + 3);
1685 self.bit_reader.drop_bits(here_bits);
1686 let len = 0;
1687 let copy = 3 + self.bit_reader.bits(3) as usize;
1688 self.bit_reader.drop_bits(3);
1689
1690 if self.have + copy > self.nlen + self.ndist {
1691 self.mode = Mode::Bad;
1692 break 'label self.bad("invalid bit length repeat\0");
1693 }
1694
1695 for _ in 0..copy {
1696 self.lens[self.have] = len as u16;
1697 self.have += 1;
1698 }
1699 }
1700 18.. => {
1701 need_bits!(self, here_bits as usize + 7);
1702 self.bit_reader.drop_bits(here_bits);
1703 let len = 0;
1704 let copy = 11 + self.bit_reader.bits(7) as usize;
1705 self.bit_reader.drop_bits(7);
1706
1707 if self.have + copy > self.nlen + self.ndist {
1708 self.mode = Mode::Bad;
1709 break 'label self.bad("invalid bit length repeat\0");
1710 }
1711
1712 for _ in 0..copy {
1713 self.lens[self.have] = len as u16;
1714 self.have += 1;
1715 }
1716 }
1717 }
1718 }
1719
1720 if self.lens[256] == 0 {
1722 self.mode = Mode::Bad;
1723 break 'label self.bad("invalid code -- missing end-of-block\0");
1724 }
1725
1726 self.len_table.bits = 10;
1729
1730 let InflateTable::Success(root) = inflate_table(
1731 CodeType::Lens,
1732 &self.lens,
1733 self.nlen,
1734 &mut self.len_codes,
1735 self.len_table.bits,
1736 &mut self.work,
1737 ) else {
1738 self.mode = Mode::Bad;
1739 break 'label self.bad("invalid literal/lengths set\0");
1740 };
1741
1742 self.len_table.codes = Codes::Len;
1743 self.len_table.bits = root;
1744
1745 self.dist_table.bits = 9;
1746
1747 let InflateTable::Success(root) = inflate_table(
1748 CodeType::Dists,
1749 &self.lens[self.nlen..],
1750 self.ndist,
1751 &mut self.dist_codes,
1752 self.dist_table.bits,
1753 &mut self.work,
1754 ) else {
1755 self.mode = Mode::Bad;
1756 break 'label self.bad("invalid distances set\0");
1757 };
1758
1759 self.dist_table.bits = root;
1760 self.dist_table.codes = Codes::Dist;
1761
1762 self.mode = Mode::Len_;
1763
1764 if matches!(self.flush, InflateFlush::Trees) {
1765 break 'label self.inflate_leave(ReturnCode::Ok);
1766 }
1767
1768 continue 'label;
1769 }
1770 Mode::Dict => {
1771 if !self.flags.contains(Flags::HAVE_DICT) {
1772 break 'label self.inflate_leave(ReturnCode::NeedDict);
1773 }
1774
1775 self.checksum = crate::ADLER32_INITIAL_VALUE as _;
1776
1777 self.mode = Mode::Type;
1778
1779 continue 'label;
1780 }
1781 Mode::DictId => {
1782 need_bits!(self, 32);
1783
1784 self.checksum = zswap32(self.bit_reader.hold() as u32);
1785
1786 self.bit_reader.init_bits();
1787
1788 self.mode = Mode::Dict;
1789
1790 continue 'label;
1791 }
1792 Mode::Bad => {
1793 let msg = "repeated call with bad state\0";
1794 #[cfg(all(feature = "std", test))]
1795 dbg!(msg);
1796 self.error_message = Some(msg);
1797
1798 break 'label ReturnCode::DataError;
1799 }
1800 Mode::Mem => {
1801 break 'label ReturnCode::MemError;
1802 }
1803 Mode::Sync => {
1804 break 'label ReturnCode::StreamError;
1805 }
1806 Mode::Length => {
1807 if self.wrap != 0 && self.gzip_flags != 0 {
1809 need_bits!(self, 32);
1810 if (self.wrap & 4) != 0 && self.bit_reader.hold() != self.total as u64 {
1811 self.mode = Mode::Bad;
1812 break 'label self.bad("incorrect length check\0");
1813 }
1814
1815 self.bit_reader.init_bits();
1816 }
1817
1818 break 'label ReturnCode::StreamEnd;
1820 }
1821 };
1822 }
1823 }
1824
1825 fn bad(&mut self, msg: &'static str) -> ReturnCode {
1826 #[cfg(all(feature = "std", test))]
1827 dbg!(msg);
1828 self.error_message = Some(msg);
1829 self.inflate_leave(ReturnCode::DataError)
1830 }
1831
1832 fn inflate_leave(&mut self, return_code: ReturnCode) -> ReturnCode {
1835 return_code
1837 }
1838
1839 fn decoding_state(&self) -> i32 {
1841 let bit_reader_bits = self.bit_reader.bits_in_buffer() as i32;
1842 debug_assert!(bit_reader_bits < 64);
1843
1844 let last = if self.flags.contains(Flags::IS_LAST_BLOCK) {
1845 64
1846 } else {
1847 0
1848 };
1849
1850 let mode = match self.mode {
1851 Mode::Type => 128,
1852 Mode::Len_ | Mode::CopyBlock => 256,
1853 _ => 0,
1854 };
1855
1856 bit_reader_bits | last | mode
1857 }
1858}
1859
1860fn inflate_fast_help(state: &mut State, start: usize) {
1861 #[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
1862 if crate::cpu_features::is_enabled_avx2() {
1863 return unsafe { inflate_fast_help_avx2(state, start) };
1865 }
1866
1867 inflate_fast_help_vanilla(state, start);
1868}
1869
1870#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
1871#[target_feature(enable = "avx2")]
1872unsafe fn inflate_fast_help_avx2(state: &mut State, start: usize) {
1873 inflate_fast_help_impl::<{ CpuFeatures::AVX2 }>(state, start);
1874}
1875
1876fn inflate_fast_help_vanilla(state: &mut State, start: usize) {
1877 inflate_fast_help_impl::<{ CpuFeatures::NONE }>(state, start);
1878}
1879
1880#[inline(always)]
1881fn inflate_fast_help_impl<const FEATURES: usize>(state: &mut State, _start: usize) {
1882 let mut bit_reader = BitReader::new(&[]);
1883 core::mem::swap(&mut bit_reader, &mut state.bit_reader);
1884
1885 let mut writer = Writer::new(&mut []);
1886 core::mem::swap(&mut writer, &mut state.writer);
1887
1888 let lcode = state.len_table_ref();
1889 let dcode = state.dist_table_ref();
1890
1891 let lmask = (1u64 << state.len_table.bits) - 1;
1893 let dmask = (1u64 << state.dist_table.bits) - 1;
1894
1895 let extra_safe = false;
1897
1898 let window_size = state.window.size();
1899
1900 let mut bad = None;
1901
1902 if bit_reader.bits_in_buffer() < 10 {
1903 bit_reader.refill();
1904 }
1905
1906 'outer: loop {
1907 let mut here = {
1908 let bits = bit_reader.bits_in_buffer();
1909 let hold = bit_reader.hold();
1910
1911 bit_reader.refill();
1912
1913 if bits as usize >= state.len_table.bits {
1916 lcode[(hold & lmask) as usize]
1917 } else {
1918 lcode[(bit_reader.hold() & lmask) as usize]
1919 }
1920 };
1921
1922 if here.op == 0 {
1923 writer.push(here.val as u8);
1924 bit_reader.drop_bits(here.bits);
1925 here = lcode[(bit_reader.hold() & lmask) as usize];
1926
1927 if here.op == 0 {
1928 writer.push(here.val as u8);
1929 bit_reader.drop_bits(here.bits);
1930 here = lcode[(bit_reader.hold() & lmask) as usize];
1931 }
1932 }
1933
1934 'dolen: loop {
1935 bit_reader.drop_bits(here.bits);
1936 let op = here.op;
1937
1938 if op == 0 {
1939 writer.push(here.val as u8);
1940 } else if op & 16 != 0 {
1941 let op = op & MAX_BITS;
1942 let mut len = here.val + bit_reader.bits(op as usize) as u16;
1943 bit_reader.drop_bits(op);
1944
1945 here = dcode[(bit_reader.hold() & dmask) as usize];
1946
1947 if bit_reader.bits_in_buffer() < MAX_BITS + MAX_DIST_EXTRA_BITS {
1950 bit_reader.refill();
1951 }
1952
1953 'dodist: loop {
1954 bit_reader.drop_bits(here.bits);
1955 let op = here.op;
1956
1957 if op & 16 != 0 {
1958 let op = op & MAX_BITS;
1959 let dist = here.val + bit_reader.bits(op as usize) as u16;
1960
1961 if INFLATE_STRICT && dist as usize > state.dmax {
1962 bad = Some("invalid distance too far back\0");
1963 state.mode = Mode::Bad;
1964 break 'outer;
1965 }
1966
1967 bit_reader.drop_bits(op);
1968
1969 let written = writer.len();
1971
1972 if dist as usize > written {
1973 if (dist as usize - written) > state.window.have() {
1975 if state.flags.contains(Flags::SANE) {
1976 bad = Some("invalid distance too far back\0");
1977 state.mode = Mode::Bad;
1978 break 'outer;
1979 }
1980
1981 panic!("INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR")
1982 }
1983
1984 let mut op = dist as usize - written;
1985 let mut from;
1986
1987 let window_next = state.window.next();
1988
1989 if window_next == 0 {
1990 from = window_size - op;
1997 } else if window_next >= op {
1998 from = window_next - op;
2000 } else {
2001 op -= window_next;
2006 from = window_size - op;
2007
2008 if op < len as usize {
2009 len -= op as u16;
2013 writer.extend_from_window_with_features::<FEATURES>(
2014 &state.window,
2015 from..from + op,
2016 );
2017 from = 0;
2018 op = window_next;
2019 }
2020 }
2021
2022 let copy = Ord::min(op, len as usize);
2023 writer.extend_from_window_with_features::<FEATURES>(
2024 &state.window,
2025 from..from + copy,
2026 );
2027
2028 if op < len as usize {
2029 writer.copy_match_with_features::<FEATURES>(
2031 dist as usize,
2032 len as usize - op,
2033 );
2034 }
2035 } else if extra_safe {
2036 todo!()
2037 } else {
2038 writer.copy_match_with_features::<FEATURES>(dist as usize, len as usize)
2039 }
2040 } else if (op & 64) == 0 {
2041 here = dcode[(here.val + bit_reader.bits(op as usize) as u16) as usize];
2043 continue 'dodist;
2044 } else {
2045 bad = Some("invalid distance code\0");
2046 state.mode = Mode::Bad;
2047 break 'outer;
2048 }
2049
2050 break 'dodist;
2051 }
2052 } else if (op & 64) == 0 {
2053 here = lcode[(here.val + bit_reader.bits(op as usize) as u16) as usize];
2055 continue 'dolen;
2056 } else if op & 32 != 0 {
2057 state.mode = Mode::Type;
2059 break 'outer;
2060 } else {
2061 bad = Some("invalid literal/length code\0");
2062 state.mode = Mode::Bad;
2063 break 'outer;
2064 }
2065
2066 break 'dolen;
2067 }
2068
2069 let remaining = bit_reader.bytes_remaining_including_buffer();
2071 if remaining >= INFLATE_FAST_MIN_HAVE && writer.remaining() >= INFLATE_FAST_MIN_LEFT {
2072 continue;
2073 }
2074
2075 break 'outer;
2076 }
2077
2078 bit_reader.return_unused_bytes();
2080
2081 state.bit_reader = bit_reader;
2082 state.writer = writer;
2083
2084 if let Some(error_message) = bad {
2085 debug_assert!(matches!(state.mode, Mode::Bad));
2086 state.bad(error_message);
2087 }
2088}
2089
2090pub fn prime(stream: &mut InflateStream, bits: i32, value: i32) -> ReturnCode {
2091 if bits == 0 {
2092 } else if bits < 0 {
2094 stream.state.bit_reader.init_bits();
2095 } else if bits > 16 || stream.state.bit_reader.bits_in_buffer() + bits as u8 > 32 {
2096 return ReturnCode::StreamError;
2097 } else {
2098 stream.state.bit_reader.prime(bits as u8, value as u64);
2099 }
2100
2101 ReturnCode::Ok
2102}
2103
2104#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
2105pub struct InflateConfig {
2106 pub window_bits: i32,
2107}
2108
2109impl Default for InflateConfig {
2110 fn default() -> Self {
2111 Self {
2112 window_bits: DEF_WBITS,
2113 }
2114 }
2115}
2116
2117pub fn init(stream: &mut z_stream, config: InflateConfig) -> ReturnCode {
2119 stream.msg = core::ptr::null_mut();
2120
2121 #[cfg(feature = "rust-allocator")]
2125 if stream.zalloc.is_none() || stream.zfree.is_none() {
2126 stream.configure_default_rust_allocator()
2127 }
2128
2129 #[cfg(feature = "c-allocator")]
2130 if stream.zalloc.is_none() || stream.zfree.is_none() {
2131 stream.configure_default_c_allocator()
2132 }
2133
2134 if stream.zalloc.is_none() || stream.zfree.is_none() {
2135 return ReturnCode::StreamError;
2136 }
2137
2138 let mut state = State::new(&[], Writer::new(&mut []));
2139
2140 state.chunksize = 32;
2142
2143 let alloc = Allocator {
2144 zalloc: stream.zalloc.unwrap(),
2145 zfree: stream.zfree.unwrap(),
2146 opaque: stream.opaque,
2147 _marker: PhantomData,
2148 };
2149
2150 let Some(state_allocation) = alloc.allocate_raw::<State>() else {
2152 return ReturnCode::MemError;
2153 };
2154
2155 unsafe { state_allocation.as_ptr().write(state) };
2157 stream.state = state_allocation.as_ptr() as *mut internal_state;
2158
2159 let ret = if let Some(stream) = unsafe { InflateStream::from_stream_mut(stream) } {
2161 reset_with_config(stream, config)
2162 } else {
2163 ReturnCode::StreamError
2164 };
2165
2166 if ret != ReturnCode::Ok {
2167 let ptr = stream.state;
2168 stream.state = core::ptr::null_mut();
2169 unsafe { alloc.deallocate(ptr, 1) };
2171 }
2172
2173 ret
2174}
2175
2176pub fn reset_with_config(stream: &mut InflateStream, config: InflateConfig) -> ReturnCode {
2177 let mut window_bits = config.window_bits;
2178 let wrap;
2179
2180 if window_bits < 0 {
2181 wrap = 0;
2182
2183 if window_bits < -MAX_WBITS {
2184 return ReturnCode::StreamError;
2185 }
2186
2187 window_bits = -window_bits;
2188 } else {
2189 wrap = (window_bits >> 4) + 5; if window_bits < 48 {
2192 window_bits &= MAX_WBITS;
2193 }
2194 }
2195
2196 if window_bits != 0 && !(MIN_WBITS..=MAX_WBITS).contains(&window_bits) {
2197 #[cfg(feature = "std")]
2198 eprintln!("invalid windowBits");
2199 return ReturnCode::StreamError;
2200 }
2201
2202 if stream.state.window.size() != 0 && stream.state.wbits as i32 != window_bits {
2203 let mut window = Window::empty();
2204 core::mem::swap(&mut window, &mut stream.state.window);
2205
2206 let (ptr, len) = window.into_raw_parts();
2207 assert_ne!(len, 0);
2208 unsafe { stream.alloc.deallocate(ptr, len) };
2210 }
2211
2212 stream.state.wrap = wrap as u8;
2213 stream.state.wbits = window_bits as _;
2214
2215 reset(stream)
2216}
2217
2218pub fn reset(stream: &mut InflateStream) -> ReturnCode {
2219 stream.state.window.clear();
2221
2222 stream.state.error_message = None;
2223
2224 reset_keep(stream)
2225}
2226
2227pub fn reset_keep(stream: &mut InflateStream) -> ReturnCode {
2228 stream.total_in = 0;
2229 stream.total_out = 0;
2230 stream.state.total = 0;
2231
2232 stream.msg = core::ptr::null_mut();
2233
2234 let state = &mut stream.state;
2235
2236 if state.wrap != 0 {
2237 stream.adler = (state.wrap & 1) as _;
2239 }
2240
2241 state.mode = Mode::Head;
2242 state.checksum = crate::ADLER32_INITIAL_VALUE as u32;
2243
2244 state.flags.update(Flags::IS_LAST_BLOCK, false);
2245 state.flags.update(Flags::HAVE_DICT, false);
2246 state.flags.update(Flags::SANE, true);
2247 state.gzip_flags = -1;
2248 state.dmax = 32768;
2249 state.head = None;
2250 state.bit_reader = BitReader::new(&[]);
2251
2252 state.next = 0;
2253 state.len_table = Table::default();
2254 state.dist_table = Table::default();
2255
2256 state.back = usize::MAX;
2257
2258 ReturnCode::Ok
2259}
2260
2261pub unsafe fn inflate(stream: &mut InflateStream, flush: InflateFlush) -> ReturnCode {
2262 if stream.next_out.is_null() || (stream.next_in.is_null() && stream.avail_in != 0) {
2263 return ReturnCode::StreamError as _;
2264 }
2265
2266 let state = &mut stream.state;
2267
2268 if let Mode::Type = state.mode {
2270 state.mode = Mode::TypeDo;
2271 }
2272
2273 state.flush = flush;
2274
2275 unsafe {
2276 state
2277 .bit_reader
2278 .update_slice(stream.next_in, stream.avail_in as usize)
2279 };
2280 state.writer = Writer::new_uninit(stream.next_out.cast(), stream.avail_out as usize);
2281
2282 state.in_available = stream.avail_in as _;
2283 state.out_available = stream.avail_out as _;
2284
2285 let mut err = state.dispatch();
2286
2287 let in_read = state.bit_reader.as_ptr() as usize - stream.next_in as usize;
2288 let out_written = state.out_available - (state.writer.capacity() - state.writer.len());
2289
2290 stream.total_in += in_read as z_size;
2291 state.total += out_written;
2292 stream.total_out = state.total as _;
2293
2294 stream.avail_in = state.bit_reader.bytes_remaining() as u32;
2295 stream.next_in = state.bit_reader.as_ptr() as *mut u8;
2296
2297 stream.avail_out = (state.writer.capacity() - state.writer.len()) as u32;
2298 stream.next_out = state.writer.next_out() as *mut u8;
2299
2300 stream.adler = state.checksum as z_checksum;
2301
2302 let valid_mode = |mode| !matches!(mode, Mode::Bad | Mode::Mem | Mode::Sync);
2303 let not_done = |mode| {
2304 !matches!(
2305 mode,
2306 Mode::Check | Mode::Length | Mode::Bad | Mode::Mem | Mode::Sync
2307 )
2308 };
2309
2310 let must_update_window = state.window.size() != 0
2311 || (out_written != 0
2312 && valid_mode(state.mode)
2313 && (not_done(state.mode) || !matches!(state.flush, InflateFlush::Finish)));
2314
2315 let update_checksum = state.wrap & 4 != 0;
2316
2317 if must_update_window {
2318 'blk: {
2319 if state.window.size() == 0 {
2321 match Window::new_in(&stream.alloc, state.wbits as usize) {
2322 Some(window) => state.window = window,
2323 None => {
2324 state.mode = Mode::Mem;
2325 err = ReturnCode::MemError;
2326 break 'blk;
2327 }
2328 }
2329 }
2330
2331 state.window.extend(
2332 &state.writer.filled()[..out_written],
2333 state.gzip_flags,
2334 update_checksum,
2335 &mut state.checksum,
2336 &mut state.crc_fold,
2337 );
2338 }
2339 }
2340
2341 if let Some(msg) = state.error_message {
2342 assert!(msg.ends_with('\0'));
2343 stream.msg = msg.as_ptr() as *mut u8 as *mut core::ffi::c_char;
2344 }
2345
2346 stream.data_type = state.decoding_state();
2347
2348 if ((in_read == 0 && out_written == 0) || flush == InflateFlush::Finish as _)
2349 && err == (ReturnCode::Ok as _)
2350 {
2351 ReturnCode::BufError as _
2352 } else {
2353 err as _
2354 }
2355}
2356
2357fn syncsearch(mut got: usize, buf: &[u8]) -> (usize, usize) {
2358 let len = buf.len();
2359 let mut next = 0;
2360
2361 while next < len && got < 4 {
2362 if buf[next] == if got < 2 { 0 } else { 0xff } {
2363 got += 1;
2364 } else if buf[next] != 0 {
2365 got = 0;
2366 } else {
2367 got = 4 - got;
2368 }
2369 next += 1;
2370 }
2371
2372 (got, next)
2373}
2374
2375pub fn sync(stream: &mut InflateStream) -> ReturnCode {
2376 let state = &mut stream.state;
2377
2378 if stream.avail_in == 0 && state.bit_reader.bits_in_buffer() < 8 {
2379 return ReturnCode::BufError;
2380 }
2381 if !matches!(state.mode, Mode::Sync) {
2383 state.mode = Mode::Sync;
2384
2385 let (buf, len) = state.bit_reader.start_sync_search();
2386
2387 (state.have, _) = syncsearch(0, &buf[..len]);
2388 }
2389
2390 let slice = unsafe { core::slice::from_raw_parts(stream.next_in, stream.avail_in as usize) };
2393
2394 let len;
2395 (state.have, len) = syncsearch(state.have, slice);
2396 stream.next_in = unsafe { stream.next_in.add(len) };
2398 stream.avail_in -= len as u32;
2399 stream.total_in += len as z_size;
2400
2401 if state.have != 4 {
2403 return ReturnCode::DataError;
2404 }
2405
2406 if state.gzip_flags == -1 {
2407 state.wrap = 0; } else {
2409 state.wrap &= !4; }
2411
2412 let flags = state.gzip_flags;
2413 let total_in = stream.total_in;
2414 let total_out = stream.total_out;
2415
2416 reset(stream);
2417
2418 stream.total_in = total_in;
2419 stream.total_out = total_out;
2420
2421 stream.state.gzip_flags = flags;
2422 stream.state.mode = Mode::Type;
2423
2424 ReturnCode::Ok
2425}
2426
2427pub fn sync_point(stream: &mut InflateStream) -> bool {
2436 matches!(stream.state.mode, Mode::Stored) && stream.state.bit_reader.bits_in_buffer() == 0
2437}
2438
2439pub unsafe fn copy<'a>(
2440 dest: &mut MaybeUninit<InflateStream<'a>>,
2441 source: &InflateStream<'a>,
2442) -> ReturnCode {
2443 if source.next_out.is_null() || (source.next_in.is_null() && source.avail_in != 0) {
2444 return ReturnCode::StreamError;
2445 }
2446
2447 unsafe {
2450 core::ptr::copy_nonoverlapping(source, dest.as_mut_ptr(), 1);
2451 }
2452
2453 let Some(state_allocation) = source.alloc.allocate_raw::<State>() else {
2455 return ReturnCode::MemError;
2456 };
2457
2458 let state = &source.state;
2459
2460 let writer: MaybeUninit<Writer> =
2462 unsafe { core::ptr::read(&state.writer as *const _ as *const MaybeUninit<Writer>) };
2463
2464 let mut copy = State {
2465 mode: state.mode,
2466 flags: state.flags,
2467 wrap: state.wrap,
2468 len_table: state.len_table,
2469 dist_table: state.dist_table,
2470 wbits: state.wbits,
2471 window: Window::empty(),
2472 head: None,
2473 ncode: state.ncode,
2474 nlen: state.nlen,
2475 ndist: state.ndist,
2476 have: state.have,
2477 next: state.next,
2478 bit_reader: state.bit_reader,
2479 writer: Writer::new(&mut []),
2480 total: state.total,
2481 length: state.length,
2482 offset: state.offset,
2483 extra: state.extra,
2484 back: state.back,
2485 was: state.was,
2486 chunksize: state.chunksize,
2487 in_available: state.in_available,
2488 out_available: state.out_available,
2489 lens: state.lens,
2490 work: state.work,
2491 error_message: state.error_message,
2492 flush: state.flush,
2493 checksum: state.checksum,
2494 crc_fold: state.crc_fold,
2495 dmax: state.dmax,
2496 gzip_flags: state.gzip_flags,
2497 codes_codes: state.codes_codes,
2498 len_codes: state.len_codes,
2499 dist_codes: state.dist_codes,
2500 };
2501
2502 if !state.window.is_empty() {
2503 let Some(window) = state.window.clone_in(&source.alloc) else {
2504 source.alloc.deallocate(state_allocation.as_ptr(), 1);
2506 return ReturnCode::MemError;
2507 };
2508
2509 copy.window = window;
2510 }
2511
2512 unsafe { state_allocation.as_ptr().write(copy) }; let field_ptr = unsafe { core::ptr::addr_of_mut!((*dest.as_mut_ptr()).state) };
2517 unsafe { core::ptr::write(field_ptr as *mut *mut State, state_allocation.as_ptr()) };
2518
2519 let field_ptr = unsafe { core::ptr::addr_of_mut!((*dest.as_mut_ptr()).state.writer) };
2521 unsafe { core::ptr::copy(writer.as_ptr(), field_ptr, 1) };
2522
2523 let field_ptr = unsafe { core::ptr::addr_of_mut!((*dest.as_mut_ptr()).state.head) };
2525 unsafe { core::ptr::copy(&source.state.head, field_ptr, 1) };
2526
2527 ReturnCode::Ok
2528}
2529
2530pub fn undermine(stream: &mut InflateStream, subvert: i32) -> ReturnCode {
2531 stream.state.flags.update(Flags::SANE, (!subvert) != 0);
2532
2533 ReturnCode::Ok
2534}
2535
2536pub fn mark(stream: &InflateStream) -> c_long {
2537 if stream.next_out.is_null() || (stream.next_in.is_null() && stream.avail_in != 0) {
2538 return c_long::MIN;
2539 }
2540
2541 let state = &stream.state;
2542
2543 let length = match state.mode {
2544 Mode::CopyBlock => state.length,
2545 Mode::Match => state.was - state.length,
2546 _ => 0,
2547 };
2548
2549 (((state.back as c_long) as c_ulong) << 16) as c_long + length as c_long
2550}
2551
2552pub fn set_dictionary(stream: &mut InflateStream, dictionary: &[u8]) -> ReturnCode {
2553 if stream.state.wrap != 0 && !matches!(stream.state.mode, Mode::Dict) {
2554 return ReturnCode::StreamError;
2555 }
2556
2557 if matches!(stream.state.mode, Mode::Dict) {
2559 let dictid = adler32(1, dictionary);
2560
2561 if dictid != stream.state.checksum {
2562 return ReturnCode::DataError;
2563 }
2564 }
2565
2566 let err = 'blk: {
2567 if stream.state.window.size() == 0 {
2569 match Window::new_in(&stream.alloc, stream.state.wbits as usize) {
2570 None => break 'blk ReturnCode::MemError,
2571 Some(window) => stream.state.window = window,
2572 }
2573 }
2574
2575 stream.state.window.extend(
2576 dictionary,
2577 stream.state.gzip_flags,
2578 false,
2579 &mut stream.state.checksum,
2580 &mut stream.state.crc_fold,
2581 );
2582
2583 ReturnCode::Ok
2584 };
2585
2586 if err != ReturnCode::Ok {
2587 stream.state.mode = Mode::Mem;
2588 return ReturnCode::MemError;
2589 }
2590
2591 stream.state.flags.update(Flags::HAVE_DICT, true);
2592
2593 ReturnCode::Ok
2594}
2595
2596pub fn end<'a>(stream: &'a mut InflateStream<'a>) -> &'a mut z_stream {
2597 let alloc = stream.alloc;
2598
2599 let mut window = Window::empty();
2600 core::mem::swap(&mut window, &mut stream.state.window);
2601
2602 if !window.is_empty() {
2604 let (ptr, len) = window.into_raw_parts();
2605 unsafe { alloc.deallocate(ptr, len) };
2606 }
2607
2608 let stream = stream.as_z_stream_mut();
2609
2610 let state_ptr = core::mem::replace(&mut stream.state, core::ptr::null_mut());
2611
2612 unsafe { alloc.deallocate(state_ptr as *mut State, 1) };
2614
2615 stream
2616}
2617
2618pub unsafe fn get_header<'a>(
2627 stream: &mut InflateStream<'a>,
2628 head: Option<&'a mut gz_header>,
2629) -> ReturnCode {
2630 if (stream.state.wrap & 2) == 0 {
2631 return ReturnCode::StreamError;
2632 }
2633
2634 stream.state.head = head.map(|head| {
2635 head.done = 0;
2636 head
2637 });
2638 ReturnCode::Ok
2639}
2640#[cfg(test)]
2641mod tests {
2642 use super::*;
2643
2644 #[test]
2645 fn uncompress_buffer_overflow() {
2646 let mut output = [0; 1 << 13];
2647 let input = [
2648 72, 137, 58, 0, 3, 39, 255, 255, 255, 255, 255, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
2649 14, 14, 184, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 184, 14, 14,
2650 14, 14, 14, 14, 14, 63, 14, 14, 14, 14, 14, 14, 14, 14, 184, 14, 14, 255, 14, 103, 14,
2651 14, 14, 14, 14, 14, 61, 14, 255, 255, 63, 14, 14, 14, 14, 14, 14, 14, 14, 184, 14, 14,
2652 255, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 6, 14, 14, 14, 14, 14, 14, 14, 14, 71,
2653 4, 137, 106,
2654 ];
2655
2656 let config = InflateConfig { window_bits: 15 };
2657
2658 let (_decompressed, err) = uncompress_slice(&mut output, &input, config);
2659 assert_eq!(err, ReturnCode::DataError);
2660 }
2661}