From e09d21848f5e96aed34fa60d81a27906877f6bdf Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 15 Jun 2020 09:02:41 -0700 Subject: [PATCH 1/2] Flag `miniz_oxide` as a `#![no_std]` library This commit conversion the `miniz_oxide` crate to a `#![no_std]` library, and is as a result a breaking change for the library. Currently the only dependency on the `std` crate is the `std::io::Cursor` type, which is pretty easily replaced with a `usize` parameter in a few locations. The goal of this commit is to eventually enable this library to be included into the standard library itself. Dependencies of the standard library can't depend on the standard library as well! The reason for including this in the standard library is that the `backtrace` crate wants to decompress DWARF information in executables, which can be compressed with zlib. --- miniz_oxide/Cargo.toml | 2 +- miniz_oxide/src/deflate/core.rs | 112 ++++++++++++++++++------------ miniz_oxide/src/deflate/mod.rs | 6 +- miniz_oxide/src/deflate/stream.rs | 5 +- miniz_oxide/src/inflate/core.rs | 49 ++++--------- miniz_oxide/src/inflate/mod.rs | 17 +++-- miniz_oxide/src/inflate/stream.rs | 25 ++++--- miniz_oxide/src/lib.rs | 11 ++- miniz_oxide/tests/test.rs | 4 +- src/tinfl.rs | 17 ++--- 10 files changed, 125 insertions(+), 123 deletions(-) diff --git a/miniz_oxide/Cargo.toml b/miniz_oxide/Cargo.toml index c3a3e653..0b03c3b2 100644 --- a/miniz_oxide/Cargo.toml +++ b/miniz_oxide/Cargo.toml @@ -17,4 +17,4 @@ exclude = ["benches/*", "tests/*"] name = "miniz_oxide" [dependencies] -adler32 = "1.0.4" +adler32 = { version = "1.0.4", default-features = false } diff --git a/miniz_oxide/src/deflate/core.rs b/miniz_oxide/src/deflate/core.rs index 400baf92..d25ea522 100644 --- a/miniz_oxide/src/deflate/core.rs +++ b/miniz_oxide/src/deflate/core.rs @@ -1,8 +1,8 @@ //! Streaming compression functionality. -use std::convert::TryInto; -use std::io::{self, Cursor, Seek, SeekFrom, Write}; -use std::{cmp, mem}; +use alloc::boxed::Box; +use core::convert::TryInto; +use core::{cmp, mem}; use super::super::*; use super::deflate_flags::*; @@ -14,6 +14,11 @@ use crate::deflate::buffer::{ use crate::shared::{update_adler32, HUFFMAN_LENGTH_ORDER, MZ_ADLER32_INIT}; use crate::DataFormat; +// Currently not bubbled up outside this module, so can fill in with more +// context eventually if needed. +type Result = core::result::Result; +struct Error {} + const MAX_PROBES_MASK: i32 = 0xFFF; const MAX_SUPPORTED_HUFF_CODESIZE: usize = 32; @@ -549,12 +554,12 @@ impl<'a> CallbackBuf<'a> { .copy_from_slice(¶ms.local_buf.b[..n]); params.out_buf_ofs += n; - if saved_output.pos != n as u64 { + if saved_output.pos != n { params.flush_ofs = n as u32; - params.flush_remaining = (saved_output.pos - n as u64) as u32; + params.flush_remaining = (saved_output.pos - n) as u32; } } else { - params.out_buf_ofs += saved_output.pos as usize; + params.out_buf_ofs += saved_output.pos; } params.flush_remaining as i32 @@ -585,9 +590,9 @@ impl<'a> CallbackOut<'a> { } }; - let cursor = Cursor::new(chosen_buffer); OutputBufferOxide { - inner: cursor, + inner: chosen_buffer, + inner_pos: 0, local: is_local, bit_buffer: 0, bits_in: 0, @@ -649,7 +654,8 @@ impl<'a> CallbackOxide<'a> { } struct OutputBufferOxide<'a> { - pub inner: Cursor<&'a mut [u8]>, + pub inner: &'a mut [u8], + pub inner_pos: usize, pub local: bool, pub bit_buffer: u32, @@ -662,9 +668,8 @@ impl<'a> OutputBufferOxide<'a> { self.bit_buffer |= bits << self.bits_in; self.bits_in += len; while self.bits_in >= 8 { - let pos = self.inner.position(); - self.inner.get_mut()[pos as usize] = self.bit_buffer as u8; - self.inner.set_position(pos + 1); + self.inner[self.inner_pos] = self.bit_buffer as u8; + self.inner_pos += 1; self.bit_buffer >>= 8; self.bits_in -= 8; } @@ -672,7 +677,7 @@ impl<'a> OutputBufferOxide<'a> { fn save(&self) -> SavedOutputBufferOxide { SavedOutputBufferOxide { - pos: self.inner.position(), + pos: self.inner_pos, bit_buffer: self.bit_buffer, bits_in: self.bits_in, local: self.local, @@ -680,7 +685,7 @@ impl<'a> OutputBufferOxide<'a> { } fn load(&mut self, saved: SavedOutputBufferOxide) { - self.inner.set_position(saved.pos); + self.inner_pos = saved.pos; self.bit_buffer = saved.bit_buffer; self.bits_in = saved.bits_in; self.local = saved.local; @@ -695,7 +700,7 @@ impl<'a> OutputBufferOxide<'a> { } struct SavedOutputBufferOxide { - pub pos: u64, + pub pos: usize, pub bit_buffer: u32, pub bits_in: u32, pub local: bool, @@ -712,17 +717,18 @@ impl BitBuffer { self.bits_in += len; } - fn flush(&mut self, output: &mut OutputBufferOxide) -> io::Result<()> { - let pos = output.inner.position() as usize; + fn flush(&mut self, output: &mut OutputBufferOxide) -> Result<()> { + let pos = output.inner_pos; { // isolation to please borrow checker - let inner = &mut (*output.inner.get_mut())[pos..pos + 8]; + let inner = &mut output.inner[pos..pos + 8]; let bytes = u64::to_le_bytes(self.bit_buffer); inner.copy_from_slice(&bytes); } - output - .inner - .seek(SeekFrom::Current(i64::from(self.bits_in >> 3)))?; + match output.inner_pos.checked_add((self.bits_in >> 3) as usize) { + Some(n) if n <= output.inner.len() => output.inner_pos = n, + _ => return Err(Error {}), + } self.bit_buffer >>= self.bits_in & !7; self.bits_in &= 7; Ok(()) @@ -760,19 +766,21 @@ struct RLE { impl RLE { fn prev_code_size( &mut self, - packed_code_sizes: &mut Cursor<&mut [u8]>, + packed_code_sizes: &mut [u8], + packed_pos: &mut usize, h: &mut HuffmanOxide, - ) -> io::Result<()> { + ) -> Result<()> { + let mut write = |buf| write(buf, packed_code_sizes, packed_pos); let counts = &mut h.count[HUFF_CODES_TABLE]; if self.repeat_count != 0 { if self.repeat_count < 3 { counts[self.prev_code_size as usize] = counts[self.prev_code_size as usize].wrapping_add(self.repeat_count as u16); let code = self.prev_code_size; - packed_code_sizes.write_all(&[code, code, code][..self.repeat_count as usize])?; + write(&[code, code, code][..self.repeat_count as usize])?; } else { counts[16] = counts[16].wrapping_add(1); - packed_code_sizes.write_all(&[16, (self.repeat_count - 3) as u8][..])?; + write(&[16, (self.repeat_count - 3) as u8][..])?; } self.repeat_count = 0; } @@ -782,20 +790,22 @@ impl RLE { fn zero_code_size( &mut self, - packed_code_sizes: &mut Cursor<&mut [u8]>, + packed_code_sizes: &mut [u8], + packed_pos: &mut usize, h: &mut HuffmanOxide, - ) -> io::Result<()> { + ) -> Result<()> { + let mut write = |buf| write(buf, packed_code_sizes, packed_pos); let counts = &mut h.count[HUFF_CODES_TABLE]; if self.z_count != 0 { if self.z_count < 3 { counts[0] = counts[0].wrapping_add(self.z_count as u16); - packed_code_sizes.write_all(&[0, 0, 0][..self.z_count as usize])?; + write(&[0, 0, 0][..self.z_count as usize])?; } else if self.z_count <= 10 { counts[17] = counts[17].wrapping_add(1); - packed_code_sizes.write_all(&[17, (self.z_count - 3) as u8][..])?; + write(&[17, (self.z_count - 3) as u8][..])?; } else { counts[18] = counts[18].wrapping_add(1); - packed_code_sizes.write_all(&[18, (self.z_count - 11) as u8][..])?; + write(&[18, (self.z_count - 11) as u8][..])?; } self.z_count = 0; } @@ -804,6 +814,15 @@ impl RLE { } } +fn write(src: &[u8], dst: &mut [u8], dst_pos: &mut usize) -> Result<()> { + match dst.get_mut(*dst_pos..*dst_pos + src.len()) { + Some(s) => s.copy_from_slice(src), + None => return Err(Error {}), + } + *dst_pos += src.len(); + Ok(()) +} + impl Default for HuffmanOxide { fn default() -> Self { HuffmanOxide { @@ -1036,7 +1055,7 @@ impl HuffmanOxide { output.put_bits(0b01, 2) } - fn start_dynamic_block(&mut self, output: &mut OutputBufferOxide) -> io::Result<()> { + fn start_dynamic_block(&mut self, output: &mut OutputBufferOxide) -> Result<()> { // There will always be one, and only one end of block code. self.count[0][256] = 1; @@ -1075,25 +1094,25 @@ impl HuffmanOxide { memset(&mut self.count[HUFF_CODES_TABLE][..MAX_HUFF_SYMBOLS_2], 0); - let mut packed_code_sizes_cursor = Cursor::new(&mut packed_code_sizes[..]); + let mut packed_pos = 0; for &code_size in &code_sizes_to_pack[..total_code_sizes_to_pack] { if code_size == 0 { - rle.prev_code_size(&mut packed_code_sizes_cursor, self)?; + rle.prev_code_size(&mut packed_code_sizes, &mut packed_pos, self)?; rle.z_count += 1; if rle.z_count == 138 { - rle.zero_code_size(&mut packed_code_sizes_cursor, self)?; + rle.zero_code_size(&mut packed_code_sizes, &mut packed_pos, self)?; } } else { - rle.zero_code_size(&mut packed_code_sizes_cursor, self)?; + rle.zero_code_size(&mut packed_code_sizes, &mut packed_pos, self)?; if code_size != rle.prev_code_size { - rle.prev_code_size(&mut packed_code_sizes_cursor, self)?; + rle.prev_code_size(&mut packed_code_sizes, &mut packed_pos, self)?; self.count[HUFF_CODES_TABLE][code_size as usize] = self.count[HUFF_CODES_TABLE][code_size as usize].wrapping_add(1); - packed_code_sizes_cursor.write_all(&[code_size][..])?; + write(&[code_size], &mut packed_code_sizes, &mut packed_pos)?; } else { rle.repeat_count += 1; if rle.repeat_count == 6 { - rle.prev_code_size(&mut packed_code_sizes_cursor, self)?; + rle.prev_code_size(&mut packed_code_sizes, &mut packed_pos, self)?; } } } @@ -1101,9 +1120,9 @@ impl HuffmanOxide { } if rle.repeat_count != 0 { - rle.prev_code_size(&mut packed_code_sizes_cursor, self)?; + rle.prev_code_size(&mut packed_code_sizes, &mut packed_pos, self)?; } else { - rle.zero_code_size(&mut packed_code_sizes_cursor, self)?; + rle.zero_code_size(&mut packed_code_sizes, &mut packed_pos, self)?; } self.optimize_table(2, MAX_HUFF_SYMBOLS_2, 7, false); @@ -1130,8 +1149,7 @@ impl HuffmanOxide { } let mut packed_code_size_index = 0 as usize; - let packed_code_sizes = packed_code_sizes_cursor.get_ref(); - while packed_code_size_index < packed_code_sizes_cursor.position() as usize { + while packed_code_size_index < packed_pos { let code = packed_code_sizes[packed_code_size_index] as usize; packed_code_size_index += 1; assert!(code < MAX_HUFF_SYMBOLS_2); @@ -1474,7 +1492,7 @@ fn compress_lz_codes( huff: &HuffmanOxide, output: &mut OutputBufferOxide, lz_code_buf: &[u8], -) -> io::Result { +) -> Result { let mut flags = 1; let mut bb = BitBuffer { bit_buffer: u64::from(output.bit_buffer), @@ -1573,7 +1591,7 @@ fn compress_block( output: &mut OutputBufferOxide, lz: &LZOxide, static_block: bool, -) -> io::Result { +) -> Result { if static_block { huff.start_static_block(output); } else { @@ -1587,7 +1605,7 @@ fn flush_block( d: &mut CompressorOxide, callback: &mut CallbackOxide, flush: TDEFLFlush, -) -> io::Result { +) -> Result { let mut saved_buffer; { let mut output = callback @@ -1635,7 +1653,7 @@ fn flush_block( // (as literals are either 8 or 9 bytes), a raw block will // never take up less space if the number of input bytes are less than 32. let expanded = (d.lz.total_bytes > 32) - && (output.inner.position() - saved_buffer.pos + 1 >= u64::from(d.lz.total_bytes)) + && (output.inner_pos - saved_buffer.pos + 1 >= (d.lz.total_bytes as usize)) && (d.dict.lookahead_pos - d.dict.code_buf_dict_pos <= d.dict.size); if use_raw_block || expanded { @@ -2339,6 +2357,8 @@ mod test { MZ_DEFAULT_WINDOW_BITS, }; use crate::inflate::decompress_to_vec; + use std::prelude::v1::*; + use std::vec; #[test] fn u16_to_slice() { diff --git a/miniz_oxide/src/deflate/mod.rs b/miniz_oxide/src/deflate/mod.rs index dbe930ce..ac8b5e56 100644 --- a/miniz_oxide/src/deflate/mod.rs +++ b/miniz_oxide/src/deflate/mod.rs @@ -1,5 +1,8 @@ //! This module contains functionality for compression. +use alloc::vec; +use alloc::vec::Vec; + mod buffer; pub mod core; pub mod stream; @@ -119,7 +122,7 @@ fn compress_to_vec_inner(input: &[u8], level: u8, window_bits: i32, strategy: i3 // The comp flags function sets the zlib flag if the window_bits parameter is > 0. let flags = create_comp_flags_from_zip_params(level.into(), window_bits, strategy); let mut compressor = CompressorOxide::new(flags); - let mut output = vec![0; std::cmp::max(input.len() / 2, 2)]; + let mut output = vec![0; ::core::cmp::max(input.len() / 2, 2)]; let mut in_pos = 0; let mut out_pos = 0; @@ -157,6 +160,7 @@ fn compress_to_vec_inner(input: &[u8], level: u8, window_bits: i32, strategy: i3 mod test { use super::{compress_to_vec, compress_to_vec_inner, CompressionStrategy}; use crate::inflate::decompress_to_vec; + use std::vec; /// Test deflate example. /// diff --git a/miniz_oxide/src/deflate/stream.rs b/miniz_oxide/src/deflate/stream.rs index 55ef316c..c5ebedb2 100644 --- a/miniz_oxide/src/deflate/stream.rs +++ b/miniz_oxide/src/deflate/stream.rs @@ -3,7 +3,7 @@ //! As of now this is mainly inteded for use to build a higher-level wrapper. //! //! There is no DeflateState as the needed state is contained in the compressor struct itself. -use std::convert::{AsMut, AsRef}; +use core::convert::{AsMut, AsRef}; use crate::deflate::core::{compress, CompressorOxide, TDEFLFlush, TDEFLStatus}; use crate::{MZError, MZFlush, MZStatus, StreamResult}; @@ -100,6 +100,9 @@ mod test { use crate::deflate::CompressorOxide; use crate::inflate::decompress_to_vec_zlib; use crate::{MZFlush, MZStatus}; + use std::prelude::v1::*; + use std::vec; + #[test] fn test_state() { let data = b"Hello zlib!"; diff --git a/miniz_oxide/src/inflate/core.rs b/miniz_oxide/src/inflate/core.rs index 4da31b6f..56df026a 100644 --- a/miniz_oxide/src/inflate/core.rs +++ b/miniz_oxide/src/inflate/core.rs @@ -3,8 +3,8 @@ use super::*; use crate::shared::{update_adler32, HUFFMAN_LENGTH_ORDER}; -use std::convert::TryInto; -use std::{cmp, slice}; +use ::core::convert::TryInto; +use ::core::{cmp, slice}; use self::output_buffer::OutputBuffer; @@ -1020,39 +1020,24 @@ fn decompress_fast( pub fn decompress( r: &mut DecompressorOxide, in_buf: &[u8], - out_cur: &mut Cursor<&mut [u8]>, - flags: u32, -) -> (TINFLStatus, usize, usize) { - let res = decompress_inner(r, in_buf, out_cur, flags); - let new_pos = out_cur.position() + res.2 as u64; - out_cur.set_position(new_pos); - res -} - -#[inline] -fn decompress_inner( - r: &mut DecompressorOxide, - in_buf: &[u8], - out_cur: &mut Cursor<&mut [u8]>, + out: &mut [u8], + out_pos: usize, flags: u32, ) -> (TINFLStatus, usize, usize) { - let out_buf_start_pos = out_cur.position() as usize; let out_buf_size_mask = if flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF != 0 { usize::max_value() } else { // In the case of zero len, any attempt to write would produce HasMoreOutput, // so to gracefully process the case of there really being no output, // set the mask to all zeros. - out_cur.get_ref().len().saturating_sub(1) + out.len().saturating_sub(1) }; // Ensure the output buffer's size is a power of 2, unless the output buffer // is large enough to hold the entire output file (in which case it doesn't // matter). // Also make sure that the output buffer position is not past the end of the output buffer. - if (out_buf_size_mask.wrapping_add(1) & out_buf_size_mask) != 0 - || out_cur.position() > out_cur.get_ref().len() as u64 - { + if (out_buf_size_mask.wrapping_add(1) & out_buf_size_mask) != 0 || out_pos > out.len() { return (TINFLStatus::BadParam, 0, 0); } @@ -1060,7 +1045,7 @@ fn decompress_inner( let mut state = r.state; - let mut out_buf = OutputBuffer::from_slice_and_pos(out_cur.get_mut(), out_buf_start_pos); + let mut out_buf = OutputBuffer::from_slice_and_pos(out, out_pos); // Make a local copy of the important variables here so we can work with them on the stack. let mut l = LocalVars { @@ -1634,10 +1619,7 @@ fn decompress_inner( let need_adler = flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32) != 0; if need_adler && status as i32 >= 0 { let out_buf_pos = out_buf.position(); - r.check_adler32 = update_adler32( - r.check_adler32, - &out_buf.get_ref()[out_buf_start_pos..out_buf_pos], - ); + r.check_adler32 = update_adler32(r.check_adler32, &out_buf.get_ref()[out_pos..out_buf_pos]); // disabled so that random input from fuzzer would not be rejected early, // before it has a chance to reach interesting parts of code @@ -1655,7 +1637,7 @@ fn decompress_inner( ( status, in_buf.len() - in_iter.len() - in_undo, - out_buf.position() - out_buf_start_pos, + out_buf.position() - out_pos, ) } @@ -1671,8 +1653,7 @@ mod test { output_buffer: &mut [u8], flags: u32, ) -> (TINFLStatus, &'i [u8], usize) { - let (status, in_pos, out_pos) = - decompress(r, input_buffer, &mut Cursor::new(output_buffer), flags); + let (status, in_pos, out_pos) = decompress(r, input_buffer, output_buffer, 0, flags); (status, &input_buffer[in_pos..], out_pos) } @@ -1772,14 +1753,14 @@ mod test { fn check_result(input: &[u8], expected_status: TINFLStatus, expected_state: State, zlib: bool) { let mut r = DecompressorOxide::default(); let mut output_buf = vec![0; 1024 * 32]; - let mut out_cursor = Cursor::new(output_buf.as_mut_slice()); let flags = if zlib { inflate_flags::TINFL_FLAG_PARSE_ZLIB_HEADER } else { 0 } | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | TINFL_FLAG_HAS_MORE_INPUT; - let (d_status, _in_bytes, _out_bytes) = decompress(&mut r, input, &mut out_cursor, flags); + let (d_status, _in_bytes, _out_bytes) = + decompress(&mut r, input, &mut output_buf, 0, flags); assert_eq!(expected_status, d_status); assert_eq!(expected_state, r.state); } @@ -1870,10 +1851,9 @@ mod test { | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF; let mut r = DecompressorOxide::new(); let mut output_buf = vec![]; - let mut out_cursor = Cursor::new(output_buf.as_mut_slice()); // Check that we handle an empty buffer properly and not panicking. // https://github.com/Frommi/miniz_oxide/issues/23 - let res = decompress(&mut r, &encoded, &mut out_cursor, flags); + let res = decompress(&mut r, &encoded, &mut output_buf, 0, flags); assert_eq!(res, (TINFLStatus::HasMoreOutput, 4, 0)); } @@ -1885,10 +1865,9 @@ mod test { let flags = TINFL_FLAG_COMPUTE_ADLER32; let mut r = DecompressorOxide::new(); let mut output_buf = vec![]; - let mut out_cursor = Cursor::new(output_buf.as_mut_slice()); // Check that we handle an empty buffer properly and not panicking. // https://github.com/Frommi/miniz_oxide/issues/23 - let res = decompress(&mut r, &encoded, &mut out_cursor, flags); + let res = decompress(&mut r, &encoded, &mut output_buf, 0, flags); assert_eq!(res, (TINFLStatus::HasMoreOutput, 2, 0)); } } diff --git a/miniz_oxide/src/inflate/mod.rs b/miniz_oxide/src/inflate/mod.rs index 6a32a5a9..57570166 100644 --- a/miniz_oxide/src/inflate/mod.rs +++ b/miniz_oxide/src/inflate/mod.rs @@ -1,7 +1,9 @@ //! This module contains functionality for decompression. -use std::io::Cursor; -use std::usize; +use ::core::usize; +use alloc::boxed::Box; +use alloc::vec; +use alloc::vec::Vec; pub mod core; mod output_buffer; @@ -79,13 +81,10 @@ fn decompress_to_vec_inner(input: &[u8], flags: u32) -> Result, TINFLSta let mut in_pos = 0; let mut out_pos = 0; loop { - let (status, in_consumed, out_consumed) = { - // Wrap the whole output slice so we know we have enough of the - // decompressed data for matches. - let mut c = Cursor::new(ret.as_mut_slice()); - c.set_position(out_pos as u64); - decompress(&mut decomp, &input[in_pos..], &mut c, flags) - }; + // Wrap the whole output slice so we know we have enough of the + // decompressed data for matches. + let (status, in_consumed, out_consumed) = + decompress(&mut decomp, &input[in_pos..], &mut ret, out_pos, flags); in_pos += in_consumed; out_pos += out_consumed; diff --git a/miniz_oxide/src/inflate/stream.rs b/miniz_oxide/src/inflate/stream.rs index 42b8a742..39c602f3 100644 --- a/miniz_oxide/src/inflate/stream.rs +++ b/miniz_oxide/src/inflate/stream.rs @@ -1,8 +1,8 @@ //! Extra streaming decompression functionality. //! //! As of now this is mainly inteded for use to build a higher-level wrapper. -use std::io::Cursor; -use std::{cmp, mem}; +use alloc::boxed::Box; +use core::{cmp, mem}; use crate::inflate::core::{decompress, inflate_flags, DecompressorOxide, TINFL_LZ_DICT_SIZE}; use crate::inflate::TINFLStatus; @@ -152,12 +152,7 @@ pub fn inflate( if (flush == MZFlush::Finish) && first_call { decomp_flags |= inflate_flags::TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF; - let status = decompress( - &mut state.decomp, - next_in, - &mut Cursor::new(next_out), - decomp_flags, - ); + let status = decompress(&mut state.decomp, next_in, next_out, 0, decomp_flags); let in_bytes = status.1; let out_bytes = status.2; let status = status.0; @@ -230,11 +225,13 @@ fn inflate_loop( ) -> MZResult { let orig_in_len = next_in.len(); loop { - let status = { - let mut cursor = Cursor::new(&mut state.dict[..]); - cursor.set_position(state.dict_ofs as u64); - decompress(&mut state.decomp, *next_in, &mut cursor, decomp_flags) - }; + let status = decompress( + &mut state.decomp, + *next_in, + &mut state.dict, + state.dict_ofs, + decomp_flags, + ); let in_bytes = status.1; let out_bytes = status.2; @@ -301,6 +298,8 @@ fn push_dict_out(state: &mut InflateState, next_out: &mut &mut [u8]) -> usize { mod test { use super::{inflate, InflateState}; use crate::{DataFormat, MZFlush, MZStatus}; + use std::vec; + #[test] fn test_state() { let encoded = [ diff --git a/miniz_oxide/src/lib.rs b/miniz_oxide/src/lib.rs index c2abb54b..4ae3d76c 100644 --- a/miniz_oxide/src/lib.rs +++ b/miniz_oxide/src/lib.rs @@ -21,9 +21,14 @@ //! //! ``` +#![allow(warnings)] #![forbid(unsafe_code)] +#![no_std] -extern crate adler32; +extern crate alloc; + +#[cfg(test)] +extern crate std; pub mod deflate; pub mod inflate; @@ -145,13 +150,13 @@ impl StreamResult { } } -impl std::convert::From for MZResult { +impl core::convert::From for MZResult { fn from(res: StreamResult) -> Self { res.status } } -impl std::convert::From<&StreamResult> for MZResult { +impl core::convert::From<&StreamResult> for MZResult { fn from(res: &StreamResult) -> Self { res.status } diff --git a/miniz_oxide/tests/test.rs b/miniz_oxide/tests/test.rs index 5eaa9b68..56b12387 100644 --- a/miniz_oxide/tests/test.rs +++ b/miniz_oxide/tests/test.rs @@ -96,7 +96,6 @@ fn zlib_header_level() { #[test] fn need_more_input_has_more_output_at_same_time() { use miniz_oxide::inflate::core; - use std::io::Cursor; let input = get_test_file_data("tests/test_data/numbers.deflate"); let data = get_test_file_data("tests/test_data/numbers.txt"); @@ -106,11 +105,10 @@ fn need_more_input_has_more_output_at_same_time() { decomp.init(); let mut output = [0; core::TINFL_LZ_DICT_SIZE]; - let mut output_cursor = Cursor::new(&mut output[..]); let flags = core::inflate_flags::TINFL_FLAG_HAS_MORE_INPUT; let (status, in_consumed, out_consumed) = - core::decompress(&mut decomp, input, &mut output_cursor, flags); + core::decompress(&mut decomp, input, &mut output, 0, flags); let input_empty = in_consumed == input.len(); let output_full = out_consumed == output.len(); diff --git a/src/tinfl.rs b/src/tinfl.rs index d107a332..996e04dc 100644 --- a/src/tinfl.rs +++ b/src/tinfl.rs @@ -5,7 +5,6 @@ use miniz_oxide::inflate::core::DecompressorOxide; pub use miniz_oxide::inflate::core::DecompressorOxide as tinfl_decompressor; pub use miniz_oxide::inflate::core::{decompress, inflate_flags}; use miniz_oxide::inflate::TINFLStatus; -use std::io::Cursor; use std::{ptr, slice, usize}; pub const TINFL_DECOMPRESS_MEM_TO_MEM_FAILED: size_t = usize::MAX; @@ -22,12 +21,11 @@ unmangle!( ) -> i32 { let next_pos = out_buf_next as usize - out_buf_start as usize; let out_size = *out_buf_size + next_pos; - let mut out_cursor = Cursor::new(slice::from_raw_parts_mut(out_buf_start, out_size)); - out_cursor.set_position(next_pos as u64); let (status, in_consumed, out_consumed) = decompress( r.as_mut().expect("bad decompressor pointer"), slice::from_raw_parts(in_buf, *in_buf_size), - &mut out_cursor, + slice::from_raw_parts_mut(out_buf_start, out_size), + next_pos, flags, ); @@ -49,7 +47,8 @@ unmangle!( let (status, _, out_consumed) = decompress( &mut decomp, slice::from_raw_parts(p_src_buf as *const u8, src_buf_len), - &mut Cursor::new(slice::from_raw_parts_mut(p_out_buf as *mut u8, out_buf_len)), + slice::from_raw_parts_mut(p_out_buf as *mut u8, out_buf_len), + 0, (flags & !inflate_flags::TINFL_FLAG_HAS_MORE_INPUT) | inflate_flags::TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF, ); @@ -89,18 +88,14 @@ unmangle!( // How far into the source buffer we have read. let mut src_buf_ofs = 0; loop { - let mut out_cur = Cursor::new(slice::from_raw_parts_mut( - p_buf as *mut u8, - out_buf_capacity, - )); - out_cur.set_position(*p_out_len as u64); let (status, in_consumed, out_consumed) = decompress( &mut decomp, slice::from_raw_parts( p_src_buf.offset(src_buf_ofs as isize) as *const u8, src_buf_len - src_buf_ofs, ), - &mut out_cur, + slice::from_raw_parts_mut(p_buf as *mut u8, out_buf_capacity), + *p_out_len, (flags & !inflate_flags::TINFL_FLAG_HAS_MORE_INPUT) | inflate_flags::TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF, ); From e9bf64d68dacad5747982d89ec9e947c9740f36b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 15 Jun 2020 10:46:21 -0700 Subject: [PATCH 2/2] Update with annotations to build in libstd --- miniz_oxide/Cargo.toml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/miniz_oxide/Cargo.toml b/miniz_oxide/Cargo.toml index 0b03c3b2..70733f72 100644 --- a/miniz_oxide/Cargo.toml +++ b/miniz_oxide/Cargo.toml @@ -17,4 +17,15 @@ exclude = ["benches/*", "tests/*"] name = "miniz_oxide" [dependencies] -adler32 = { version = "1.0.4", default-features = false } +adler32 = { version = "1.1.0", default-features = false } + +# Internal feature, only used when building as part of libstd, not part of the +# stable interface of this crate. +core = { version = '1.0.0', optional = true, package = 'rustc-std-workspace-core' } +alloc = { version = '1.0.0', optional = true, package = 'rustc-std-workspace-alloc' } +compiler_builtins = { version = '0.1.2', optional = true } + +[features] +# Internal feature, only used when building as part of libstd, not part of the +# stable interface of this crate. +rustc-dep-of-std = ['core', 'alloc', 'compiler_builtins', 'adler32/rustc-dep-of-std']