diff --git a/source/marathon/defl.rs b/source/marathon/defl.rs index d2c3f68..ebdcf24 100644 --- a/source/marathon/defl.rs +++ b/source/marathon/defl.rs @@ -1,13 +1,14 @@ //! DEFLATE loader. -use crate::durandal::err::*; +use crate::durandal::{bit::*, err::*}; +use std::cmp::Ordering; /// Loads a ZLIB file header. pub fn load_zlib_header(b: &[u8]) -> ResultS { - const CM: u8 = 0b00001111; - const CINFO: u8 = 0b11110000; - const FDICT: u8 = 0b00100000; + const CM: u8 = 0b0000_1111; + const CINFO: u8 = 0b1111_0000; + const FDICT: u8 = 0b0010_0000; read_data! { 2, BE in b => @@ -33,10 +34,11 @@ pub fn load_zlib_header(b: &[u8]) -> ResultS /// Loads a GZIP file header. pub fn load_gzip_header(b: &[u8]) -> ResultS { - const FHCRC: u8 = 1 << 1; - const FEXTRA: u8 = 1 << 2; - const FNAME: u8 = 1 << 3; - const FCOMMENT: u8 = 1 << 4; + const FHCRC: u8 = 1 << 1; + const FEXTRA: u8 = 1 << 2; + const FNAME: u8 = 1 << 3; + const FCOMMENT: u8 = 1 << 4; + const FRESERVED: u8 = 0xE0; read_data! { 10, LE in b => @@ -51,6 +53,10 @@ pub fn load_gzip_header(b: &[u8]) -> ResultS let mut p = 10; + if fl & FRESERVED != 0 { + bail!("reserved flags set"); + } + if fl & FEXTRA != 0 { read_data!(p + 2, LE in b => xlen = u16[p] usize;); check_data!(p + 2 + xlen, b); @@ -59,11 +65,11 @@ pub fn load_gzip_header(b: &[u8]) -> ResultS } if fl & FNAME != 0 { - p = skip_zero_terminated_item(&b[p..])?; + p += skip_zero_terminated_item(&b[p..])?; } if fl & FCOMMENT != 0 { - p = skip_zero_terminated_item(&b[p..])?; + p += skip_zero_terminated_item(&b[p..])?; } if fl & FHCRC != 0 { @@ -78,10 +84,315 @@ pub fn load_gzip_header(b: &[u8]) -> ResultS fn skip_zero_terminated_item(b: &[u8]) -> ResultS { if let Some(i) = b.iter().position(|&n| n == 0) { - Ok(i) + Ok(i + 1) } else { bail!("no end of zero terminated item"); } } +/// Decompresses a DEFLATE compressed bitstream. +pub fn load_deflate(b: &[u8]) -> ResultS<(usize, Vec)> +{ + let mut v = Vec::new(); + let p = stream_deflate(&mut v, b, 0)?; + + Ok((p / 8, v)) +} + +fn stream_deflate(v: &mut Vec, b: &[u8], p: usize) -> ResultS +{ + let bfinal = read_bits_l(b, p, 1)?; + let btype = read_bits_l(b, p + 1, 2)?; + + let p = p + 3; + + let p = match btype { + 0b10 => stream_dynamic(v, b, p)?, + 0b01 => stream_s_table(v, b, p)?, + 0b00 => stream_literal(v, b, p)?, + _ => bail!("bad btype"), + }; + + if bfinal == 0 { + stream_deflate(v, b, p) + } else { + Ok(p) + } +} + +fn stream_dynamic(v: &mut Vec, b: &[u8], mut p: usize) -> ResultS +{ + const CODE_ORDERING: [usize; NUM_CODES] = [ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 + ]; + + const NUM_CODES: usize = 19; + + const MAX_LIT_CODES: usize = 286; + const MAX_DST_CODES: usize = 30; + + // read header (number of literal alphabet codes, number of distance + // alphabet codes, and number of lengths for decoding the alphabet) + let hlit = read_bits_l(b, p, 5)?; p += 5; + let hdist = read_bits_l(b, p, 5)?; p += 5; + let hclen = read_bits_l(b, p, 4)?; p += 4; + + let hlit = 257 + hlit as usize; + let hdist = 1 + hdist as usize; + let hclen = 4 + hclen as usize; + + let alphabet_total = hlit + hdist; + + // first, get the huffman coding for the alphabet (which is also compressed) + let mut code_lengths = [0; NUM_CODES]; + + for i in 0..hclen { + let len = read_bits_l(b, p, 3)? as u16; + p += 3; + + code_lengths[CODE_ORDERING[i]] = len; + } + + let code_lengths = HuffmanTable::new(&code_lengths)?; + let mut alphabet = [0; MAX_LIT_CODES + MAX_DST_CODES]; + + // then, we decode the alphabet (doing both types at the same time, because + // they're encoded the same anyways) + let mut i = 0; + while i < alphabet_total { + let (bits, sym) = code_lengths.decode(b, p)?; + p += bits; + + match sym { + 0..=15 => { + // raw code + alphabet[i] = sym; + i += 1; + } + 16 => { + // copy previous code 3-6 times + if i == 0 {bail!("cannot copy on first alphabet code");} + + let len = usize::from(read_bits_l(b, p, 2)? as u8 + 3); + let lst = alphabet[i - 1]; + p += 2; + + for _ in 0..len { + alphabet[i] = lst; + i += 1; + } + } + 17 => { + // repeat '0' 3-10 times + let len = usize::from(read_bits_l(b, p, 3)? as u8 + 3); + p += 3; + + for _ in 0..len { + alphabet[i] = 0; + i += 1; + } + } + 18 => { + // repeat '0' 11-138 times + let len = usize::from(read_bits_l(b, p, 7)? as u8 + 11); + p += 7; + + for _ in 0..len { + alphabet[i] = 0; + i += 1; + } + } + _ => { + bail!("bad symbol in alphabet"); + } + } + + if i > alphabet_total { + bail!("too many codes"); + } + } + + if alphabet[256] == 0 { + bail!("no way to end block"); + } + + let len_sta = 0; + let len_end = hlit; + let dst_sta = len_end; + let dst_end = dst_sta + hdist; + + let table_len = HuffmanTable::new(&alphabet[len_sta..len_end])?; + let table_dst = HuffmanTable::new(&alphabet[dst_sta..dst_end])?; + + output_tables(v, b, p, table_len, table_dst) +} + +fn stream_s_table(_v: &mut Vec, _b: &[u8], _p: usize) -> ResultS +{ + unimplemented!() +} + +fn stream_literal(v: &mut Vec, b: &[u8], p: usize) -> ResultS +{ + // copy data directly from byte boundary + let mut p = p / 8 + 1; + + read_data! { + p + 4, LE in b => + len = u16[p] usize; + } + + p += 4; + v.extend_from_slice(ok!(b.get(p..p + len), "not enough data")?); + + Ok((p + len) * 8) +} + +fn output_tables(v: &mut Vec, + b: &[u8], + mut p: usize, + table_len: HuffmanTable, + table_dst: HuffmanTable) + -> ResultS +{ + const LEN_BASE: [usize; 29] = [ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, + 67, 83, 99, 115, 131, 163, 195, 227, 258 + ]; + + const LEN_EXTRA_BITS: [u8; 29] = [ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, + 5, 5, 5, 5, 0 + ]; + + const DST_BASE: [usize; 30] = [ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, + 769, 1025, 1537, 2049, 3073, 4097, 0x1801, 0x2001, 0x3001, 0x4001, 0x6001 + ]; + + const DST_EXTRA_BITS: [u8; 30] = [ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, + 11, 11, 12, 12, 13, 13 + ]; + + let (bits, sym) = table_len.decode(b, p)?; + p += bits; + + match sym.cmp(&256) { + Ordering::Less => { + v.push(sym as u8); + output_tables(v, b, p, table_len, table_dst) + } + Ordering::Equal => { + Ok(p) + } + Ordering::Greater => { + let sym = sym - 257; + + if sym > 29 { + Err(err_msg("invalid fixed code")) + } else { + let sym = usize::from(sym); + + let bits = LEN_EXTRA_BITS[sym]; + let leng = LEN_BASE[sym] + read_bits_l(b, p, bits)? as usize; + p += usize::from(bits); + + let (bits, sym) = table_dst.decode(b, p)?; + p += bits; + + let sym = usize::from(sym); + + let bits = DST_EXTRA_BITS[sym]; + let dist = DST_BASE[sym] + read_bits_l(b, p, bits)? as usize; + p += usize::from(bits); + + if dist > v.len() { + bail!("bad distance"); + } + + for _ in 0..leng { + v.push(v[v.len() - dist]); + } + + output_tables(v, b, p, table_len, table_dst) + } + } + } +} + +impl HuffmanTable +{ + fn new(table: &[u16]) -> ResultS + { + let mut syms = vec![0; table.len()]; + let mut nums = [0; 16]; + + // count the number of symbols for each bit length + for &length in table { + nums[usize::from(length)] += 1; + } + + if usize::from(nums[0]) == table.len() { + bail!("bad table lengths"); + } + + // make offsets into the symbol table for each bit count + let mut ofs = [0; 16]; + + for i in 1..=14 { + ofs[i + 1] = ofs[i] + usize::from(nums[i]); + } + + // make the actual bit pattern table + for (n, &length) in table.iter().enumerate() { + // length 0 means this code isn't used, so only try to make bit + // patterns for codes that actually exist + if length != 0 { + // make sure to make each offset unique + let offset = &mut ofs[usize::from(length)]; + syms[*offset] = n as u16; + *offset += 1; + } + } + + Ok(Self{nums, syms}) + } + + fn decode(&self, b: &[u8], mut p: usize) -> ResultS<(usize, u16)> + { + let mut code = 0_u16; + let mut first = 0_u16; + let mut index = 0_u16; + + for i in 1..=15 { + // add bit from file + code |= read_bits_l(b, p, 1)? as u16; + p += 1; + + // check our symbol table for this one (quick tree check) + let count = u16::from(self.nums[i]); + + if i32::from(code) - i32::from(count) < i32::from(first) { + return Ok((i, self.syms[usize::from(index + code - first)])); + } + + // continue on, trying to find the correct sequence + index += count; + first += count; + + first <<= 1; + code <<= 1; + } + + Err(err_msg("code not found in symbol tree")) + } +} + +struct HuffmanTable +{ + nums: [u8; 16], + syms: Vec, +} + // EOF diff --git a/tests/data/alice.out b/tests/data/alice.out new file mode 100644 index 0000000..40e14ca --- /dev/null +++ b/tests/data/alice.out @@ -0,0 +1,190 @@ +Alice was beginning to get very tired of sitting by her sister on the bank, and +of having nothing to do: once or twice she had peeped into the book her sister +was reading, but it had no pictures or conversations in it, 'and what is the +use of a book,' thought Alice 'without pictures or conversations?' + +So she was considering in her own mind (as well as she could, for the hot day +made her feel very sleepy and stupid), whether the pleasure of making a +daisy-chain would be worth the trouble of getting up and picking the daisies, +when suddenly a White Rabbit with pink eyes ran close by her. + +There was nothing so VERY remarkable in that; nor did Alice think it so VERY +much out of the way to hear the Rabbit say to itself, 'Oh dear! Oh dear! I +shall be late!' (when she thought it over afterwards, it occurred to her that +she ought to have wondered at this, but at the time it all seemed quite +natural); but when the Rabbit actually TOOK A WATCH OUT OF ITS +WAISTCOAT-POCKET, and looked at it, and then hurried on, Alice started to her +feet, for it flashed across her mind that she had never before seen a rabbit +with either a waistcoat-pocket, or a watch to take out of it, and burning with +curiosity, she ran across the field after it, and fortunately was just in time +to see it pop down a large rabbit-hole under the hedge. + +In another moment down went Alice after it, never once considering how in the +world she was to get out again. + +The rabbit-hole went straight on like a tunnel for some way, and then dipped +suddenly down, so suddenly that Alice had not a moment to think about stopping +herself before she found herself falling down a very deep well. + +Either the well was very deep, or she fell very slowly, for she had plenty of +time as she went down to look about her and to wonder what was going to happen +next. First, she tried to look down and make out what she was coming to, but it +was too dark to see anything; then she looked at the sides of the well, and +noticed that they were filled with cupboards and book-shelves; here and there +she saw maps and pictures hung upon pegs. She took down a jar from one of the +shelves as she passed; it was labelled 'ORANGE MARMALADE', but to her great +disappointment it was empty: she did not like to drop the jar for fear of +killing somebody, so managed to put it into one of the cupboards as she fell +past it. + +'Well!' thought Alice to herself, 'after such a fall as this, I shall think +nothing of tumbling down stairs! How brave they'll all think me at home! Why, I +wouldn't say anything about it, even if I fell off the top of the house!' +(Which was very likely true.) + +Down, down, down. Would the fall NEVER come to an end! 'I wonder how many miles +I've fallen by this time?' she said aloud. 'I must be getting somewhere near +the centre of the earth. Let me see: that would be four thousand miles down, I +think--' (for, you see, Alice had learnt several things of this sort in her +lessons in the schoolroom, and though this was not a VERY good opportunity for +showing off her knowledge, as there was no one to listen to her, still it was +good practice to say it over) '--yes, that's about the right distance--but then +I wonder what Latitude or Longitude I've got to?' (Alice had no idea what +Latitude was, or Longitude either, but thought they were nice grand words to +say.) + +Presently she began again. 'I wonder if I shall fall right THROUGH the earth! +How funny it'll seem to come out among the people that walk with their heads +downward! The Antipathies, I think--' (she was rather glad there WAS no one +listening, this time, as it didn't sound at all the right word) '--but I shall +have to ask them what the name of the country is, you know. Please, Ma'am, is +this New Zealand or Australia?' (and she tried to curtsey as she spoke--fancy +CURTSEYING as you're falling through the air! Do you think you could manage +it?) 'And what an ignorant little girl she'll think me for asking! No, it'll +never do to ask: perhaps I shall see it written up somewhere.' + +Down, down, down. There was nothing else to do, so Alice soon began talking +again. 'Dinah'll miss me very much to-night, I should think!' (Dinah was the +cat.) 'I hope they'll remember her saucer of milk at tea-time. Dinah my dear! I +wish you were down here with me! There are no mice in the air, I'm afraid, but +you might catch a bat, and that's very like a mouse, you know. But do cats eat +bats, I wonder?' And here Alice began to get rather sleepy, and went on saying +to herself, in a dreamy sort of way, 'Do cats eat bats? Do cats eat bats?' and +sometimes, 'Do bats eat cats?' for, you see, as she couldn't answer either +question, it didn't much matter which way she put it. She felt that she was +dozing off, and had just begun to dream that she was walking hand in hand with +Dinah, and saying to her very earnestly, 'Now, Dinah, tell me the truth: did +you ever eat a bat?' when suddenly, thump! thump! down she came upon a heap of +sticks and dry leaves, and the fall was over. + +Alice was not a bit hurt, and she jumped up on to her feet in a moment: she +looked up, but it was all dark overhead; before her was another long passage, +and the White Rabbit was still in sight, hurrying down it. There was not a +moment to be lost: away went Alice like the wind, and was just in time to hear +it say, as it turned a corner, 'Oh my ears and whiskers, how late it's +getting!' She was close behind it when she turned the corner, but the Rabbit +was no longer to be seen: she found herself in a long, low hall, which was lit +up by a row of lamps hanging from the roof. + +There were doors all round the hall, but they were all locked; and when Alice +had been all the way down one side and up the other, trying every door, she +walked sadly down the middle, wondering how she was ever to get out again. + +Suddenly she came upon a little three-legged table, all made of solid glass; +there was nothing on it except a tiny golden key, and Alice's first thought was +that it might belong to one of the doors of the hall; but, alas! either the +locks were too large, or the key was too small, but at any rate it would not +open any of them. However, on the second time round, she came upon a low +curtain she had not noticed before, and behind it was a little door about +fifteen inches high: she tried the little golden key in the lock, and to her +great delight it fitted! + +Alice opened the door and found that it led into a small passage, not much +larger than a rat-hole: she knelt down and looked along the passage into the +loveliest garden you ever saw. How she longed to get out of that dark hall, and +wander about among those beds of bright flowers and those cool fountains, but +she could not even get her head through the doorway; 'and even if my head would +go through,' thought poor Alice, 'it would be of very little use without my +shoulders. Oh, how I wish I could shut up like a telescope! I think I could, if +I only knew how to begin.' For, you see, so many out-of-the-way things had +happened lately, that Alice had begun to think that very few things indeed were +really impossible. + +There seemed to be no use in waiting by the little door, so she went back to +the table, half hoping she might find another key on it, or at any rate a book +of rules for shutting people up like telescopes: this time she found a little +bottle on it, ('which certainly was not here before,' said Alice,) and round +the neck of the bottle was a paper label, with the words 'DRINK ME' beautifully +printed on it in large letters. + +It was all very well to say 'Drink me,' but the wise little Alice was not going +to do THAT in a hurry. 'No, I'll look first,' she said, 'and see whether it's +marked "poison" or not'; for she had read several nice little histories about +children who had got burnt, and eaten up by wild beasts and other unpleasant +things, all because they WOULD not remember the simple rules their friends had +taught them: such as, that a red-hot poker will burn you if you hold it too +long; and that if you cut your finger VERY deeply with a knife, it usually +bleeds; and she had never forgotten that, if you drink much from a bottle +marked 'poison,' it is almost certain to disagree with you, sooner or later. + +However, this bottle was NOT marked 'poison,' so Alice ventured to taste it, +and finding it very nice, (it had, in fact, a sort of mixed flavour of +cherry-tart, custard, pine-apple, roast turkey, toffee, and hot buttered +toast,) she very soon finished it off. + + * * * * * * * + + * * * * * * + + * * * * * * * + +'What a curious feeling!' said Alice; 'I must be shutting up like a telescope.' + +And so it was indeed: she was now only ten inches high, and her face brightened +up at the thought that she was now the right size for going through the little +door into that lovely garden. First, however, she waited for a few minutes to +see if she was going to shrink any further: she felt a little nervous about +this; 'for it might end, you know,' said Alice to herself, 'in my going out +altogether, like a candle. I wonder what I should be like then?' And she tried +to fancy what the flame of a candle is like after the candle is blown out, for +she could not remember ever having seen such a thing. + +After a while, finding that nothing more happened, she decided on going into +the garden at once; but, alas for poor Alice! when she got to the door, she +found she had forgotten the little golden key, and when she went back to the +table for it, she found she could not possibly reach it: she could see it quite +plainly through the glass, and she tried her best to climb up one of the legs +of the table, but it was too slippery; and when she had tired herself out with +trying, the poor little thing sat down and cried. + +'Come, there's no use in crying like that!' said Alice to herself, rather +sharply; 'I advise you to leave off this minute!' She generally gave herself +very good advice, (though she very seldom followed it), and sometimes she +scolded herself so severely as to bring tears into her eyes; and once she +remembered trying to box her own ears for having cheated herself in a game of +croquet she was playing against herself, for this curious child was very fond +of pretending to be two people. 'But it's no use now,' thought poor Alice, 'to +pretend to be two people! Why, there's hardly enough of me left to make ONE +respectable person!' + +Soon her eye fell on a little glass box that was lying under the table: she +opened it, and found in it a very small cake, on which the words 'EAT ME' were +beautifully marked in currants. 'Well, I'll eat it,' said Alice, 'and if it +makes me grow larger, I can reach the key; and if it makes me grow smaller, I +can creep under the door; so either way I'll get into the garden, and I don't +care which happens!' + +She ate a little bit, and said anxiously to herself, 'Which way? Which way?', +holding her hand on the top of her head to feel which way it was growing, and +she was quite surprised to find that she remained the same size: to be sure, +this generally happens when one eats cake, but Alice had got so much into the +way of expecting nothing but out-of-the-way things to happen, that it seemed +quite dull and stupid for life to go on in the common way. + +So she set to work, and very soon finished off the cake. + + * * * * * * * + + * * * * * * + + * * * * * * * diff --git a/tests/data/alice1.in b/tests/data/alice1.in new file mode 100644 index 0000000..6a7d4f8 Binary files /dev/null and b/tests/data/alice1.in differ diff --git a/tests/data/alice2.in b/tests/data/alice2.in new file mode 100644 index 0000000..098c377 Binary files /dev/null and b/tests/data/alice2.in differ diff --git a/tests/data/gzipbad1.bin b/tests/data/gzbad1.bin similarity index 100% rename from tests/data/gzipbad1.bin rename to tests/data/gzbad1.bin diff --git a/tests/data/gzipbad2.bin b/tests/data/gzbad2.bin similarity index 100% rename from tests/data/gzipbad2.bin rename to tests/data/gzbad2.bin diff --git a/tests/data/gzipbad3.bin b/tests/data/gzbad3.bin similarity index 100% rename from tests/data/gzipbad3.bin rename to tests/data/gzbad3.bin diff --git a/tests/data/gzipbad4.bin b/tests/data/gzbad4.bin similarity index 100% rename from tests/data/gzipbad4.bin rename to tests/data/gzbad4.bin diff --git a/tests/data/gzipbad5.bin b/tests/data/gzbad5.bin similarity index 100% rename from tests/data/gzipbad5.bin rename to tests/data/gzbad5.bin diff --git a/tests/data/gzipbad6.bin b/tests/data/gzbad6.bin similarity index 100% rename from tests/data/gzipbad6.bin rename to tests/data/gzbad6.bin diff --git a/tests/data/gzipbad7.bin b/tests/data/gzbad7.bin similarity index 100% rename from tests/data/gzipbad7.bin rename to tests/data/gzbad7.bin diff --git a/tests/defl.rs b/tests/defl.rs index 58a503b..f73f402 100644 --- a/tests/defl.rs +++ b/tests/defl.rs @@ -1,13 +1,33 @@ -use maraiah::marathon::defl::{self, load_gzip_header}; +use maraiah::marathon::defl; include!("data/rand.rs"); +#[test] +fn defl_alice() +{ + const IN_1: &[u8] = include_bytes!("data/alice1.in"); + const IN_2: &[u8] = include_bytes!("data/alice2.in"); + const OUT: &[u8] = include_bytes!("data/alice.out"); + + let p = defl::load_gzip_header(IN_1).unwrap(); + assert_eq!(p, 0x14); + + let b = &IN_1[p..]; + assert_eq!(defl::load_deflate(b).unwrap().1, OUT.to_vec()); + + let p = defl::load_gzip_header(IN_2).unwrap(); + assert_eq!(p, 0x14); + + let b = &IN_2[p..]; + assert_eq!(defl::load_deflate(b).unwrap().1, OUT.to_vec()); +} + #[test] fn defl_must_succeed() { - assert!(load_gzip_header(include_bytes!("data/gzipok1.bin")).is_ok()); - assert!(load_gzip_header(include_bytes!("data/gzipok2.bin")).is_ok()); - assert!(load_gzip_header(include_bytes!("data/gzipok3.bin")).is_ok()); + assert!(defl::load_gzip_header(include_bytes!("data/gzipok1.bin")).is_ok()); + assert!(defl::load_gzip_header(include_bytes!("data/gzipok2.bin")).is_ok()); + assert!(defl::load_gzip_header(include_bytes!("data/gzipok3.bin")).is_ok()); } #[test] @@ -17,13 +37,13 @@ fn defl_must_not_succeed() assert!(defl::load_gzip_header(inp).is_err()); } - assert!(load_gzip_header(include_bytes!("data/gzipbad1.bin")).is_err()); - assert!(load_gzip_header(include_bytes!("data/gzipbad2.bin")).is_err()); - assert!(load_gzip_header(include_bytes!("data/gzipbad3.bin")).is_err()); - assert!(load_gzip_header(include_bytes!("data/gzipbad4.bin")).is_err()); - assert!(load_gzip_header(include_bytes!("data/gzipbad5.bin")).is_err()); - assert!(load_gzip_header(include_bytes!("data/gzipbad6.bin")).is_err()); - assert!(load_gzip_header(include_bytes!("data/gzipbad7.bin")).is_err()); + assert!(defl::load_gzip_header(include_bytes!("data/gzbad1.bin")).is_err()); + assert!(defl::load_gzip_header(include_bytes!("data/gzbad2.bin")).is_err()); + assert!(defl::load_gzip_header(include_bytes!("data/gzbad3.bin")).is_err()); + assert!(defl::load_gzip_header(include_bytes!("data/gzbad4.bin")).is_err()); + assert!(defl::load_gzip_header(include_bytes!("data/gzbad5.bin")).is_err()); + assert!(defl::load_gzip_header(include_bytes!("data/gzbad6.bin")).is_err()); + assert!(defl::load_gzip_header(include_bytes!("data/gzbad7.bin")).is_err()); } // EOF