diff --git a/libbz2-rs-sys/src/bzlib.rs b/libbz2-rs-sys/src/bzlib.rs index f6d8694a5..d5949a9fa 100644 --- a/libbz2-rs-sys/src/bzlib.rs +++ b/libbz2-rs-sys/src/bzlib.rs @@ -546,7 +546,7 @@ pub(crate) struct DState { pub storedCombinedCRC: u32, pub calculatedBlockCRC: u32, pub calculatedCombinedCRC: u32, - pub nInUse: i32, + pub nInUse: u16, pub inUse: [bool; 256], pub inUse16: [bool; 16], pub seqToUnseq: [u8; 256], @@ -563,25 +563,26 @@ pub(crate) struct DState { } #[derive(Default)] +#[repr(C)] pub(crate) struct SaveArea { pub i: i32, pub j: i32, pub t: i32, - pub alphaSize: i32, - pub nGroups: i32, - pub nSelectors: i32, - pub EOB: i32, + pub alphaSize: u16, + pub EOB: u16, pub groupNo: i32, - pub groupPos: i32, + pub groupPos: u8, pub nextSym: i32, - pub nblockMAX: i32, - pub nblock: i32, + pub nblock: u32, pub es: i32, - pub N: i32, - pub curr: i32, - pub zn: i32, pub zvec: i32, - pub zj: i32, + pub nSelectors: u16, + pub zn: u8, + pub nGroups: u8, + pub curr: u8, + pub nblockMAX100k: u8, + pub logN: u8, // the log_2 of N + pub zj: bool, pub gMinlen: u8, pub gSel: u8, pub gLimit: u8, @@ -1267,12 +1268,12 @@ fn un_rle_obuf_to_output_fast(strm: &mut BzStream, s: &mut DState) -> bo } /* can a new run be started? */ - if s.nblock_used == s.save.nblock + 1 { + if s.nblock_used == s.save.nblock as i32 + 1 { return false; } /* Only caused by corrupt data stream? */ - if s.nblock_used > s.save.nblock + 1 { + if s.nblock_used > s.save.nblock as i32 + 1 { return true; } @@ -1283,7 +1284,7 @@ fn un_rle_obuf_to_output_fast(strm: &mut BzStream, s: &mut DState) -> bo BZ_RAND_UPD_MASK!(s); k1 ^= BZ_RAND_MASK!(s); s.nblock_used += 1; - if s.nblock_used == s.save.nblock + 1 { + if s.nblock_used == s.save.nblock as i32 + 1 { continue; }; if k1 != s.k0 { @@ -1296,7 +1297,7 @@ fn un_rle_obuf_to_output_fast(strm: &mut BzStream, s: &mut DState) -> bo BZ_RAND_UPD_MASK!(s); k1 ^= BZ_RAND_MASK!(s); s.nblock_used += 1; - if s.nblock_used == s.save.nblock + 1 { + if s.nblock_used == s.save.nblock as i32 + 1 { continue; }; if k1 != s.k0 { @@ -1309,7 +1310,7 @@ fn un_rle_obuf_to_output_fast(strm: &mut BzStream, s: &mut DState) -> bo BZ_RAND_UPD_MASK!(s); k1 ^= BZ_RAND_MASK!(s); s.nblock_used += 1; - if s.nblock_used == s.save.nblock + 1 { + if s.nblock_used == s.save.nblock as i32 + 1 { continue; }; if k1 != s.k0 { @@ -1341,7 +1342,7 @@ fn un_rle_obuf_to_output_fast(strm: &mut BzStream, s: &mut DState) -> bo /* end restore */ let avail_out_INIT: u32 = cs_avail_out; - let s_save_nblockPP: i32 = s.save.nblock + 1; + let s_save_nblockPP: i32 = s.save.nblock as i32 + 1; let tt = &s.tt.as_slice()[..100000usize.wrapping_mul(ro_blockSize100k as usize)]; @@ -1540,12 +1541,12 @@ fn un_rle_obuf_to_output_small(strm: &mut BzStream, s: &mut DState) -> b } /* can a new run be started? */ - if s.nblock_used == s.save.nblock + 1 { + if s.nblock_used == s.save.nblock as i32 + 1 { return false; } /* Only caused by corrupt data stream? */ - if s.nblock_used > s.save.nblock + 1 { + if s.nblock_used > s.save.nblock as i32 + 1 { return true; } @@ -1556,7 +1557,7 @@ fn un_rle_obuf_to_output_small(strm: &mut BzStream, s: &mut DState) -> b BZ_RAND_UPD_MASK!(s); k1 ^= BZ_RAND_MASK!(s); s.nblock_used += 1; - if s.nblock_used == s.save.nblock + 1 { + if s.nblock_used == s.save.nblock as i32 + 1 { continue; }; if k1 != s.k0 { @@ -1569,7 +1570,7 @@ fn un_rle_obuf_to_output_small(strm: &mut BzStream, s: &mut DState) -> b BZ_RAND_UPD_MASK!(s); k1 ^= BZ_RAND_MASK!(s); s.nblock_used += 1; - if s.nblock_used == s.save.nblock + 1 { + if s.nblock_used == s.save.nblock as i32 + 1 { continue; } if k1 != s.k0 { @@ -1582,7 +1583,7 @@ fn un_rle_obuf_to_output_small(strm: &mut BzStream, s: &mut DState) -> b BZ_RAND_UPD_MASK!(s); k1 ^= BZ_RAND_MASK!(s); s.nblock_used += 1; - if s.nblock_used == s.save.nblock + 1 { + if s.nblock_used == s.save.nblock as i32 + 1 { continue; } if k1 != s.k0 { @@ -1616,10 +1617,10 @@ fn un_rle_obuf_to_output_small(strm: &mut BzStream, s: &mut DState) -> b BZ_UPDATE_CRC!(s.calculatedBlockCRC, s.state_out_ch); s.state_out_len -= 1; } - if s.nblock_used == s.save.nblock + 1 { + if s.nblock_used == s.save.nblock as i32 + 1 { return false; } - if s.nblock_used > s.save.nblock + 1 { + if s.nblock_used > s.save.nblock as i32 + 1 { return true; } @@ -1627,7 +1628,7 @@ fn un_rle_obuf_to_output_small(strm: &mut BzStream, s: &mut DState) -> b s.state_out_ch = s.k0; BZ_GET_SMALL!(s, k1); s.nblock_used += 1; - if s.nblock_used == s.save.nblock + 1 { + if s.nblock_used == s.save.nblock as i32 + 1 { continue; } if k1 != s.k0 { @@ -1638,7 +1639,7 @@ fn un_rle_obuf_to_output_small(strm: &mut BzStream, s: &mut DState) -> b s.state_out_len = 2; BZ_GET_SMALL!(s, k1); s.nblock_used += 1; - if s.nblock_used == s.save.nblock + 1 { + if s.nblock_used == s.save.nblock as i32 + 1 { continue; } if k1 != s.k0 { @@ -1649,7 +1650,7 @@ fn un_rle_obuf_to_output_small(strm: &mut BzStream, s: &mut DState) -> b s.state_out_len = 3; BZ_GET_SMALL!(s, k1); s.nblock_used += 1; - if s.nblock_used == s.save.nblock + 1 { + if s.nblock_used == s.save.nblock as i32 + 1 { continue; } if k1 != s.k0 { @@ -1730,7 +1731,7 @@ pub(crate) fn BZ2_bzDecompressHelp(strm: &mut BzStream) -> ReturnCode { return ReturnCode::BZ_DATA_ERROR; } - if s.nblock_used == s.save.nblock + 1 && s.state_out_len == 0 { + if s.nblock_used == s.save.nblock as i32 + 1 && s.state_out_len == 0 { s.calculatedBlockCRC = !s.calculatedBlockCRC; if s.verbosity >= 3 { debug_log!( diff --git a/libbz2-rs-sys/src/decompress.rs b/libbz2-rs-sys/src/decompress.rs index 79842226f..1e0898552 100644 --- a/libbz2-rs-sys/src/decompress.rs +++ b/libbz2-rs-sys/src/decompress.rs @@ -3,7 +3,10 @@ use core::ffi::{c_int, c_uint}; use crate::allocator::Allocator; -use crate::bzlib::{index_into_f, BzStream, DSlice, DState, DecompressMode, ReturnCode, SaveArea}; +use crate::bzlib::{ + index_into_f, BzStream, DSlice, DState, DecompressMode, ReturnCode, SaveArea, BZ_MAX_SELECTORS, + BZ_RUNA, BZ_RUNB, +}; use crate::randtable::BZ2_RNUMS; use crate::{debug_log, huffman}; @@ -134,28 +137,6 @@ fn make_maps_d(s: &mut DState) { } } -trait GetBitsConvert { - fn convert(x: u32) -> Self; -} - -impl GetBitsConvert for bool { - fn convert(x: u32) -> Self { - x != 0 - } -} - -impl GetBitsConvert for u8 { - fn convert(x: u32) -> Self { - x as u8 - } -} - -impl GetBitsConvert for i32 { - fn convert(x: u32) -> Self { - x as i32 - } -} - pub(crate) fn decompress( strm: &mut BzStream, s: &mut DState, @@ -181,10 +162,10 @@ pub(crate) fn decompress( mut groupNo, mut groupPos, mut nextSym, - mut nblockMAX, + mut nblockMAX100k, mut nblock, mut es, - mut N, + mut logN, mut curr, mut zn, mut zvec, @@ -197,26 +178,25 @@ pub(crate) fn decompress( } = s.save; let ret_val: ReturnCode = 'save_state_and_return: { - macro_rules! GET_UCHAR { - ($strm:expr, $s:expr, $uuu:expr) => { - GET_BITS!($strm, $s, $uuu, 8); + macro_rules! GET_BYTE { + ($strm:expr, $s:expr) => { + (GET_BITS!($strm, $s, 8) & 0xFF) as u8 }; } macro_rules! GET_BIT { - ($strm:expr, $s:expr, $uuu:expr) => { - GET_BITS!($strm, $s, $uuu, 1); + ($strm:expr, $s:expr) => { + GET_BITS!($strm, $s, 1) != 0 }; } macro_rules! GET_BITS { - ($strm:expr, $s:expr, $vvv:expr, $nnn:expr) => { + ($strm:expr, $s:expr, $nnn:expr) => { loop { if $s.bsLive >= $nnn { let v: u32 = ($s.bsBuff >> ($s.bsLive - $nnn)) & ((1 << $nnn) - 1); $s.bsLive -= $nnn; - $vvv = GetBitsConvert::convert(v); - break; + break v; } if let Some(next_byte) = strm.read_byte() { @@ -233,7 +213,7 @@ pub(crate) fn decompress( ($s:expr) => { if groupPos == 0 { groupNo += 1; - if groupNo >= nSelectors { + if groupNo >= nSelectors as i32 { error!(BZ_DATA_ERROR); } else { groupPos = 50; @@ -258,7 +238,7 @@ pub(crate) fn decompress( State::BZ_X_MAGIC_1 => { s.state = State::BZ_X_MAGIC_1; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); if uc != b'B' { error!(BZ_DATA_ERROR_MAGIC); @@ -311,7 +291,7 @@ pub(crate) fn decompress( if current_block == BZ_X_MAGIC_2 { s.state = State::BZ_X_MAGIC_2; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); if uc != b'Z' { error!(BZ_DATA_ERROR_MAGIC); @@ -322,7 +302,7 @@ pub(crate) fn decompress( if current_block == BZ_X_MAGIC_3 { s.state = State::BZ_X_MAGIC_3; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); if uc != b'h' { error!(BZ_DATA_ERROR_MAGIC); @@ -333,7 +313,7 @@ pub(crate) fn decompress( if current_block == BZ_X_MAGIC_4 { s.state = State::BZ_X_MAGIC_4; - GET_BITS!(strm, s, s.blockSize100k, 8); + s.blockSize100k = GET_BITS!(strm, s, 8) as i32; if !(b'1' as i32..=b'9' as i32).contains(&s.blockSize100k) { error!(BZ_DATA_ERROR_MAGIC); @@ -374,7 +354,7 @@ pub(crate) fn decompress( if current_block == BZ_X_BLKHDR_1 { s.state = State::BZ_X_BLKHDR_1; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); if uc == 0x17 { // skips to `State::BZ_X_ENDHDR_2` @@ -389,7 +369,7 @@ pub(crate) fn decompress( BZ_X_ENDHDR_2 => { s.state = State::BZ_X_ENDHDR_2; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); if uc != 0x72 { error!(BZ_DATA_ERROR); @@ -400,7 +380,7 @@ pub(crate) fn decompress( BZ_X_BLKHDR_2 => { s.state = State::BZ_X_BLKHDR_2; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); if uc != 0x41 { error!(BZ_DATA_ERROR); @@ -413,7 +393,7 @@ pub(crate) fn decompress( BZ_X_ENDHDR_3 => { s.state = State::BZ_X_ENDHDR_3; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); if uc != 0x45 { error!(BZ_DATA_ERROR); @@ -424,7 +404,7 @@ pub(crate) fn decompress( BZ_X_BLKHDR_3 => { s.state = State::BZ_X_BLKHDR_3; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); if uc != 0x59 { error!(BZ_DATA_ERROR); @@ -438,7 +418,7 @@ pub(crate) fn decompress( BZ_X_ENDHDR_4 => { s.state = State::BZ_X_ENDHDR_4; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); if uc != 0x38 { error!(BZ_DATA_ERROR); @@ -449,7 +429,7 @@ pub(crate) fn decompress( BZ_X_BLKHDR_4 => { s.state = State::BZ_X_BLKHDR_4; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); if uc != 0x26 { error!(BZ_DATA_ERROR); @@ -463,7 +443,7 @@ pub(crate) fn decompress( BZ_X_ENDHDR_5 => { s.state = State::BZ_X_ENDHDR_5; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); if uc != 0x50 { error!(BZ_DATA_ERROR); @@ -474,7 +454,7 @@ pub(crate) fn decompress( BZ_X_BLKHDR_5 => { s.state = State::BZ_X_BLKHDR_5; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); if uc != 0x53 { error!(BZ_DATA_ERROR); @@ -488,7 +468,7 @@ pub(crate) fn decompress( BZ_X_ENDHDR_6 => { s.state = State::BZ_X_ENDHDR_6; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); if uc != 0x90 { error!(BZ_DATA_ERROR); @@ -500,7 +480,7 @@ pub(crate) fn decompress( BZ_X_BLKHDR_6 => { s.state = State::BZ_X_BLKHDR_6; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); if uc != 0x59 { error!(BZ_DATA_ERROR); @@ -519,7 +499,7 @@ pub(crate) fn decompress( BZ_X_CCRC_1 => { s.state = State::BZ_X_CCRC_1; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); s.storedCombinedCRC = s.storedCombinedCRC << 8 | uc as u32; current_block = BZ_X_CCRC_2; @@ -527,7 +507,7 @@ pub(crate) fn decompress( BZ_X_BCRC_1 => { s.state = State::BZ_X_BCRC_1; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); s.storedBlockCRC = s.storedBlockCRC << 8 | uc as u32; current_block = BZ_X_BCRC_2; @@ -538,7 +518,7 @@ pub(crate) fn decompress( BZ_X_CCRC_2 => { s.state = State::BZ_X_CCRC_2; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); s.storedCombinedCRC = s.storedCombinedCRC << 8 | uc as u32; current_block = BZ_X_CCRC_3; @@ -546,7 +526,7 @@ pub(crate) fn decompress( BZ_X_BCRC_2 => { s.state = State::BZ_X_BCRC_2; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); s.storedBlockCRC = s.storedBlockCRC << 8 | uc as u32; current_block = BZ_X_BCRC_3; @@ -557,7 +537,7 @@ pub(crate) fn decompress( BZ_X_CCRC_3 => { s.state = State::BZ_X_CCRC_3; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); s.storedCombinedCRC = s.storedCombinedCRC << 8 | uc as u32; current_block = BZ_X_CCRC_4; @@ -565,7 +545,7 @@ pub(crate) fn decompress( BZ_X_BCRC_3 => { s.state = State::BZ_X_BCRC_3; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); s.storedBlockCRC = s.storedBlockCRC << 8 | uc as u32; current_block = BZ_X_BCRC_4; @@ -576,7 +556,7 @@ pub(crate) fn decompress( BZ_X_BCRC_4 => { s.state = State::BZ_X_BCRC_4; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); s.storedBlockCRC = s.storedBlockCRC << 8 | uc as u32; current_block = BZ_X_RANDBIT; @@ -584,7 +564,7 @@ pub(crate) fn decompress( BZ_X_CCRC_4 => { s.state = State::BZ_X_CCRC_4; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); s.storedCombinedCRC = s.storedCombinedCRC << 8 | uc as u32; s.state = State::BZ_X_IDLE; @@ -595,7 +575,7 @@ pub(crate) fn decompress( if current_block == BZ_X_RANDBIT { s.state = State::BZ_X_RANDBIT; - GET_BITS!(strm, s, s.blockRandomised, 1); + s.blockRandomised = GET_BITS!(strm, s, 1) != 0; s.origPtr = 0; current_block = BZ_X_ORIGPTR_1; @@ -603,7 +583,7 @@ pub(crate) fn decompress( if current_block == BZ_X_ORIGPTR_1 { s.state = State::BZ_X_ORIGPTR_1; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); s.origPtr = s.origPtr << 8 | uc as i32; current_block = BZ_X_ORIGPTR_2; @@ -611,7 +591,7 @@ pub(crate) fn decompress( if current_block == BZ_X_ORIGPTR_2 { s.state = State::BZ_X_ORIGPTR_2; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); s.origPtr = s.origPtr << 8 | uc as i32; current_block = BZ_X_ORIGPTR_3; @@ -619,7 +599,7 @@ pub(crate) fn decompress( if current_block == BZ_X_ORIGPTR_3 { s.state = State::BZ_X_ORIGPTR_3; - GET_UCHAR!(strm, s, uc); + uc = GET_BYTE!(strm, s); s.origPtr = s.origPtr << 8 | uc as i32; if !(0..10 + 100000 * s.blockSize100k).contains(&s.origPtr) { @@ -640,7 +620,7 @@ pub(crate) fn decompress( BZ_X_MAPPING_1 => { s.state = State::BZ_X_MAPPING_1; - GET_BIT!(strm, s, uc); + uc = GET_BIT!(strm, s) as u8; s.inUse16[i as usize] = uc == 1; i += 1; @@ -659,7 +639,7 @@ pub(crate) fn decompress( BZ_X_MAPPING_2 => { s.state = State::BZ_X_MAPPING_2; - GET_BIT!(strm, s, uc); + uc = GET_BIT!(strm, s) as u8; if uc == 1 { s.inUse[(i * 16 + j) as usize] = true; @@ -670,7 +650,7 @@ pub(crate) fn decompress( BZ_X_SELECTOR_1 => { s.state = State::BZ_X_SELECTOR_1; - GET_BITS!(strm, s, nGroups, 3); + nGroups = GET_BITS!(strm, s, 3) as u8; if (2..=6).contains(&nGroups) { current_block = BZ_X_SELECTOR_2; @@ -681,7 +661,7 @@ pub(crate) fn decompress( BZ_X_SELECTOR_2 => { s.state = State::BZ_X_SELECTOR_2; - GET_BITS!(strm, s, nSelectors, 15); + nSelectors = GET_BITS!(strm, s, 15) as u16; if nSelectors < 1 { error!(BZ_DATA_ERROR); @@ -693,13 +673,13 @@ pub(crate) fn decompress( BZ_X_SELECTOR_3 => { s.state = State::BZ_X_SELECTOR_3; - GET_BIT!(strm, s, uc); + uc = GET_BIT!(strm, s) as u8; if uc == 0 { current_block = Block1; } else { j += 1; - if j >= nGroups { + if j >= nGroups as i32 { error!(BZ_DATA_ERROR); } else { current_block = Block25; @@ -709,7 +689,7 @@ pub(crate) fn decompress( BZ_X_CODING_1 => { s.state = State::BZ_X_CODING_1; - GET_BITS!(strm, s, curr, 5); + curr = GET_BITS!(strm, s, 5) as u8; i = 0; current_block = Block26; @@ -717,7 +697,7 @@ pub(crate) fn decompress( BZ_X_CODING_2 => { s.state = State::BZ_X_CODING_2; - GET_BIT!(strm, s, uc); + uc = GET_BIT!(strm, s) as u8; if uc != 0 { current_block = BZ_X_CODING_3; @@ -728,12 +708,11 @@ pub(crate) fn decompress( BZ_X_CODING_3 => { s.state = State::BZ_X_CODING_3; - GET_BIT!(strm, s, uc); + uc = GET_BIT!(strm, s) as u8; - if uc == 0 { - curr += 1; - } else { - curr -= 1; + match uc { + 0 => curr += 1, + _ => curr -= 1, } current_block = Block45; @@ -741,46 +720,46 @@ pub(crate) fn decompress( BZ_X_MTF_1 => { s.state = State::BZ_X_MTF_1; - GET_BITS!(strm, s, zvec, zn); + zvec = GET_BITS!(strm, s, zn as i32) as i32; current_block = Block56; } BZ_X_MTF_2 => { s.state = State::BZ_X_MTF_2; - GET_BIT!(strm, s, zj); + zj = GET_BIT!(strm, s); - zvec = zvec << 1 | zj; + zvec = zvec << 1 | zj as i32; current_block = Block56; } BZ_X_MTF_3 => { s.state = State::BZ_X_MTF_3; - GET_BITS!(strm, s, zvec, zn); + zvec = GET_BITS!(strm, s, zn as i32) as i32; current_block = Block52; } BZ_X_MTF_4 => { s.state = State::BZ_X_MTF_4; - GET_BIT!(strm, s, zj); + zj = GET_BIT!(strm, s); - zvec = zvec << 1 | zj; + zvec = zvec << 1 | zj as i32; current_block = Block52; } BZ_X_MTF_5 => { s.state = State::BZ_X_MTF_5; - GET_BITS!(strm, s, zvec, zn); + zvec = GET_BITS!(strm, s, zn as i32) as i32; current_block = Block24; } _ => { s.state = State::BZ_X_MTF_6; - GET_BIT!(strm, s, zj); + zj = GET_BIT!(strm, s); - zvec = zvec << 1 | zj; + zvec = zvec << 1 | zj as i32; current_block = Block24; } } @@ -811,7 +790,7 @@ pub(crate) fn decompress( } else { nextSym = s.perm[gPerm as usize] [(zvec - s.base[gBase as usize][zn as usize]) as usize]; - if nextSym == 0 || nextSym == 1 { + if nextSym == BZ_RUNA as i32 || nextSym == BZ_RUNB as i32 { current_block = Block46; } else { es += 1; @@ -820,7 +799,7 @@ pub(crate) fn decompress( match s.smallDecompress { DecompressMode::Small => { while es > 0 { - if nblock >= nblockMAX { + if nblock >= 100000 * nblockMAX100k as u32 { error!(BZ_DATA_ERROR); } else { ll16[nblock as usize] = uc as u16; @@ -831,7 +810,7 @@ pub(crate) fn decompress( } DecompressMode::Fast => { while es > 0 { - if nblock >= nblockMAX { + if nblock >= 100000 * nblockMAX100k as u32 { error!(BZ_DATA_ERROR); } else { tt[nblock as usize] = uc as u32; @@ -870,13 +849,13 @@ pub(crate) fn decompress( _ => {} } if current_block == Block40 { - if nextSym == EOB { + if nextSym == EOB as i32 { current_block = Block41; } else { if nextSym == 0 || nextSym == 1 { es = -1; - N = 1; - } else if nblock >= nblockMAX { + logN = 0; + } else if nblock >= 100000 * nblockMAX100k as u32 { error!(BZ_DATA_ERROR); } else { let mut ii_0: i32; @@ -949,7 +928,7 @@ pub(crate) fn decompress( } nblock += 1; update_group_pos!(s); - zn = gMinlen as i32; + zn = gMinlen; current_block = BZ_X_MTF_5; continue; } @@ -958,10 +937,10 @@ pub(crate) fn decompress( match current_block { Block46 => {} _ => { - if s.origPtr < 0 || s.origPtr >= nblock { + if s.origPtr < 0 || s.origPtr >= nblock as i32 { error!(BZ_DATA_ERROR); } else { - if s.unzftab.iter().any(|e| !(0..=nblock).contains(e)) { + if s.unzftab.iter().any(|e| !(0..=nblock as i32).contains(e)) { error!(BZ_DATA_ERROR); } s.cftab[0] = 0; @@ -969,7 +948,7 @@ pub(crate) fn decompress( for i in 1..s.cftab.len() { s.cftab[i] += s.cftab[i - 1]; } - if s.cftab.iter().any(|e| !(0..=nblock).contains(e)) { + if s.cftab.iter().any(|e| !(0..=nblock as i32).contains(e)) { error!(BZ_DATA_ERROR); } // FIXME: use https://doc.rust-lang.org/std/primitive.slice.html#method.is_sorted @@ -992,7 +971,7 @@ pub(crate) fn decompress( i += 1; } i = 0; - while i < nblock { + while i < nblock as i32 { uc = ll16[i as usize] as u8; ll16[i as usize] = (s.cftabCopy[uc as usize] & 0xffff) as u16; @@ -1082,7 +1061,7 @@ pub(crate) fn decompress( } DecompressMode::Fast => { i = 0; - while i < nblock { + while i < nblock as i32 { uc = (tt[i as usize] & 0xff) as u8; tt[s.cftab[uc as usize] as usize] |= (i << 8) as c_uint; s.cftab[uc as usize] += 1; @@ -1133,17 +1112,26 @@ pub(crate) fn decompress( } } if current_block == Block46 { - if N >= 2 * 1024 * 1024 { + // Check that N doesn't get too big, so that es doesn't + // go negative. The maximum value that can be + // RUNA/RUNB encoded is equal to the block size (post + // the initial RLE), viz, 900k, so bounding N at 2 + // million should guard against overflow without + // rejecting any legitimate inputs. + const LOG_2MB: u8 = 21; // 2 * 1024 * 1024 + + if logN >= LOG_2MB { error!(BZ_DATA_ERROR); } else { - if nextSym == 0 { - es += N; - } else if nextSym == 1 { - es += (1 + 1) * N; - } - N *= 2; + let mul = match nextSym as u16 { + BZ_RUNA => 1, + BZ_RUNB => 2, + _ => 0, + }; + es += mul * (1 << logN); + logN += 1; update_group_pos!(s); - zn = gMinlen as i32; + zn = gMinlen; current_block = BZ_X_MTF_3; continue; } @@ -1157,24 +1145,25 @@ pub(crate) fn decompress( } } Block39 => { - if i < nSelectors { + if i < nSelectors as i32 { j = 0; current_block = Block25; continue; } else { - if nSelectors > 2 + 900000 / 50 { - nSelectors = 2 + 900000 / 50; - } + // make sure that the constant fits in a u16 + const _: () = assert!((BZ_MAX_SELECTORS >> 16) == 0); + nSelectors = Ord::min(nSelectors, BZ_MAX_SELECTORS as u16); + let mut pos: [u8; 6] = [0; 6]; let mut tmp: u8; let mut v_22: u8; v_22 = 0_u8; - while (v_22 as c_int) < nGroups { + while v_22 < nGroups { pos[v_22 as usize] = v_22; v_22 = v_22.wrapping_add(1); } i = 0; - while i < nSelectors { + while i < nSelectors as i32 { v_22 = s.selectorMtf[i as usize]; tmp = pos[v_22 as usize]; while v_22 > 0 { @@ -1215,13 +1204,13 @@ pub(crate) fn decompress( } } Block51 => { - s.len[t as usize][i as usize] = curr as u8; + s.len[t as usize][i as usize] = curr; i += 1; current_block = Block26; continue; } Block26 => { - if i < alphaSize { + if i < alphaSize as i32 { current_block = Block45; continue; } @@ -1265,7 +1254,7 @@ pub(crate) fn decompress( error!(BZ_DATA_ERROR); } _ => { - if t < nGroups { + if t < nGroups as i32 { current_block = BZ_X_CODING_1; continue; } @@ -1295,7 +1284,7 @@ pub(crate) fn decompress( /*--- Now the MTF values ---*/ EOB = s.nInUse + 1; - nblockMAX = 100000 * s.blockSize100k; + nblockMAX100k = s.blockSize100k as u8; groupNo = -1; groupPos = 0; s.unzftab.fill(0); @@ -1315,7 +1304,7 @@ pub(crate) fn decompress( nblock = 0; update_group_pos!(s); - zn = gMinlen as i32; + zn = gMinlen; current_block = BZ_X_MTF_1; } } @@ -1333,10 +1322,10 @@ pub(crate) fn decompress( groupNo, groupPos, nextSym, - nblockMAX, + nblockMAX100k, nblock, es, - N, + logN, curr, zn, zvec,