diff --git a/libbz2-rs-sys/src/bzlib.rs b/libbz2-rs-sys/src/bzlib.rs index 73ceef4d3..3bb44e617 100644 --- a/libbz2-rs-sys/src/bzlib.rs +++ b/libbz2-rs-sys/src/bzlib.rs @@ -522,25 +522,26 @@ impl Ftab { } } +#[repr(C)] pub(crate) struct DState { pub strm_addr: usize, // Only for a consistency check pub state: decompress::State, - pub state_out_ch: u8, pub state_out_len: u32, + pub state_out_ch: u8, pub blockRandomised: bool, + pub blockSize100k: u8, + pub k0: u8, pub rNToGo: i32, pub rTPos: i32, pub bsBuff: u32, pub bsLive: i32, - pub blockSize100k: i32, pub smallDecompress: DecompressMode, pub currBlockNo: i32, pub verbosity: i32, pub origPtr: i32, pub tPos: u32, - pub k0: u8, - pub unzftab: [i32; 256], pub nblock_used: i32, + pub unzftab: [i32; 256], pub cftab: [i32; 257], pub cftabCopy: [i32; 257], pub tt: DSlice, @@ -575,7 +576,7 @@ pub(crate) struct SaveArea { pub EOB: u16, pub groupNo: i32, pub nblock: u32, - pub es: i32, + pub es: u32, pub zvec: i32, pub nextSym: u16, pub nSelectors: u16, @@ -1236,6 +1237,8 @@ macro_rules! BZ_RAND_UPD_MASK { }; } +pub(crate) use BZ_RAND_UPD_MASK; + macro_rules! BZ_GET_FAST { ($s:expr, $cccc:expr) => { /* c_tPos is unsigned, hence test < 0 is pointless. */ @@ -1339,13 +1342,13 @@ fn un_rle_obuf_to_output_fast(strm: &mut BzStream, s: &mut DState) -> bo let mut c_tPos: u32 = s.tPos; let mut cs_next_out: *mut c_char = strm.next_out; let mut cs_avail_out: c_uint = strm.avail_out; - let ro_blockSize100k: i32 = s.blockSize100k; + let ro_blockSize100k: u8 = s.blockSize100k; /* end restore */ let avail_out_INIT: u32 = cs_avail_out; let s_save_nblockPP: i32 = s.save.nblock as i32 + 1; - let tt = &s.tt.as_slice()[..100000usize.wrapping_mul(ro_blockSize100k as usize)]; + let tt = &s.tt.as_slice()[..100000usize.wrapping_mul(usize::from(ro_blockSize100k))]; macro_rules! BZ_GET_FAST_C { ($c_tPos:expr) => { diff --git a/libbz2-rs-sys/src/decompress.rs b/libbz2-rs-sys/src/decompress.rs index fd23da02c..1a9d01bb2 100644 --- a/libbz2-rs-sys/src/decompress.rs +++ b/libbz2-rs-sys/src/decompress.rs @@ -5,9 +5,8 @@ use core::ffi::c_int; use crate::allocator::Allocator; use crate::bzlib::{ index_into_f, BzStream, DSlice, DState, DecompressMode, ReturnCode, SaveArea, BZ_MAX_SELECTORS, - BZ_RUNA, BZ_RUNB, + BZ_RAND_UPD_MASK, BZ_RUNA, BZ_RUNB, }; -use crate::randtable::BZ2_RNUMS; use crate::{debug_log, huffman}; /*-- Constants for the fast MTF decoder. --*/ @@ -306,24 +305,24 @@ pub(crate) fn decompress( if current_block == BZ_X_MAGIC_4 { s.state = State::BZ_X_MAGIC_4; - s.blockSize100k = GET_BYTE!(strm, s) as i32; + s.blockSize100k = GET_BYTE!(strm, s); - if !(b'1' as i32..=b'9' as i32).contains(&s.blockSize100k) { + if !(b'1'..=b'9').contains(&s.blockSize100k) { error!(BZ_DATA_ERROR_MAGIC); } - s.blockSize100k -= b'0' as i32; + s.blockSize100k -= b'0'; match s.smallDecompress { DecompressMode::Small => { // SAFETY: we assume allocation is safe - let ll16_len = s.blockSize100k as usize * 100000; + let ll16_len = usize::from(s.blockSize100k) * 100000; let Some(ll16) = DSlice::alloc(allocator, ll16_len) else { error!(BZ_MEM_ERROR); }; // SAFETY: we assume allocation is safe - let ll4_len = (1 + s.blockSize100k as usize * 100000) >> 1; + let ll4_len = (1 + usize::from(s.blockSize100k) * 100000) >> 1; let Some(ll4) = DSlice::alloc(allocator, ll4_len) else { error!(BZ_MEM_ERROR); }; @@ -333,7 +332,7 @@ pub(crate) fn decompress( } DecompressMode::Fast => { // SAFETY: we assume allocation is safe - let tt_len = s.blockSize100k as usize * 100000; + let tt_len = usize::from(s.blockSize100k) * 100000; let Some(tt) = DSlice::alloc(allocator, tt_len) else { error!(BZ_MEM_ERROR); }; @@ -592,7 +591,7 @@ pub(crate) fn decompress( uc = GET_BYTE!(strm, s); s.origPtr = s.origPtr << 8 | i32::from(uc); - if !(0..10 + 100000 * s.blockSize100k).contains(&s.origPtr) { + if !(0..10 + 100000 * i32::from(s.blockSize100k)).contains(&s.origPtr) { error!(BZ_DATA_ERROR); } @@ -782,31 +781,22 @@ pub(crate) fn decompress( if nextSym == BZ_RUNA || nextSym == BZ_RUNB { current_block = Block46; } else { - es += 1; - uc = s.seqToUnseq[s.mtfa[s.mtfbase[0_usize] as usize] as usize]; - s.unzftab[uc as usize] += es; + let uc = s.seqToUnseq[s.mtfa[s.mtfbase[0_usize] as usize] as usize]; + s.unzftab[usize::from(uc)] += es as i32; match s.smallDecompress { DecompressMode::Small => { - while es > 0 { - if nblock >= 100000 * nblockMAX100k as u32 { - error!(BZ_DATA_ERROR); - } else { - ll16[nblock as usize] = uc as u16; - nblock += 1; - es -= 1; - } - } + match ll16.get_mut(nblock as usize..(nblock + es) as usize) { + Some(slice) => slice.fill(u16::from(uc)), + None => error!(BZ_DATA_ERROR), + }; + nblock += es; } DecompressMode::Fast => { - while es > 0 { - if nblock >= 100000 * nblockMAX100k as u32 { - error!(BZ_DATA_ERROR); - } else { - tt[nblock as usize] = uc as u32; - nblock += 1; - es -= 1; - } - } + match tt.get_mut(nblock as usize..(nblock + es) as usize) { + Some(slice) => slice.fill(u32::from(uc)), + None => error!(BZ_DATA_ERROR), + }; + nblock += es; } } current_block = Block40; @@ -839,10 +829,10 @@ pub(crate) fn decompress( if nextSym == EOB { current_block = Block41; } else if nextSym == BZ_RUNA || nextSym == BZ_RUNB { - es = -1; + es = 0; logN = 0; current_block = Block46; - } else if nblock >= 100000 * nblockMAX100k as u32 { + } else if nblock >= 100000 * u32::from(nblockMAX100k) { error!(BZ_DATA_ERROR); } else { let uc = usize::from(initialize_mtfa(&mut s.mtfa, &mut s.mtfbase, nextSym)); @@ -938,45 +928,24 @@ pub(crate) fn decompress( s.tPos = s.origPtr as u32; s.nblock_used = 0; + + s.k0 = index_into_f(s.tPos as i32, &s.cftab); + s.tPos = match ll16.get(s.tPos as usize) { + None => error!(BZ_DATA_ERROR), + Some(&low_bits) => { + let high_bits = ll4[(s.tPos >> 1) as usize] + >> (s.tPos << 2 & 0x4) + & 0xf; + u32::from(low_bits) | u32::from(high_bits) << 16 + } + }; + s.nblock_used += 1; + if s.blockRandomised { s.rNToGo = 0; s.rTPos = 0; - if s.tPos >= 100000_u32.wrapping_mul(s.blockSize100k as u32) - { - // NOTE: this originates in the BZ_GET_FAST macro, and the - // `return true` is probably uninitentional?! - return ReturnCode::BZ_RUN_OK; - } - s.k0 = index_into_f(s.tPos as i32, &s.cftab); - s.tPos = ll16[s.tPos as usize] as u32 - | (ll4[(s.tPos >> 1) as usize] as u32 - >> (s.tPos << 2 & 0x4) - & 0xf) - << 16; - s.nblock_used += 1; - if s.rNToGo == 0 { - s.rNToGo = BZ2_RNUMS[s.rTPos as usize]; - s.rTPos += 1; - if s.rTPos == 512 { - s.rTPos = 0; - } - } - s.rNToGo -= 1; - s.k0 ^= if s.rNToGo == 1 { 1 } else { 0 }; - } else { - if s.tPos >= 100000_u32.wrapping_mul(s.blockSize100k as u32) - { - // NOTE: this originates in the BZ_GET_FAST macro, and the - // `return true` is probably uninitentional?! - return ReturnCode::BZ_RUN_OK; - } - s.k0 = index_into_f(s.tPos as i32, &s.cftab); - s.tPos = ll16[s.tPos as usize] as u32 - | (ll4[(s.tPos >> 1) as usize] as u32 - >> (s.tPos << 2 & 0x4) - & 0xf) - << 16; - s.nblock_used += 1; + BZ_RAND_UPD_MASK!(s); + s.k0 ^= u8::from(s.rNToGo == 1) } } DecompressMode::Fast => { @@ -987,39 +956,20 @@ pub(crate) fn decompress( } s.tPos = tt[s.origPtr as usize] >> 8; s.nblock_used = 0; + + s.tPos = match tt.get(s.tPos as usize) { + Some(&tPos) => tPos, + None => error!(BZ_DATA_ERROR), + }; + s.k0 = (s.tPos & 0xff) as u8; + s.tPos >>= 8; + s.nblock_used += 1; + if s.blockRandomised { s.rNToGo = 0; s.rTPos = 0; - if s.tPos >= 100000_u32.wrapping_mul(s.blockSize100k as u32) - { - // NOTE: this originates in the BZ_GET_FAST macro, and the - // `return true` is probably uninitentional?! - return ReturnCode::BZ_RUN_OK; - } - s.tPos = tt[s.tPos as usize]; - s.k0 = (s.tPos & 0xff) as u8; - s.tPos >>= 8; - s.nblock_used += 1; - if s.rNToGo == 0 { - s.rNToGo = BZ2_RNUMS[s.rTPos as usize]; - s.rTPos += 1; - if s.rTPos == 512 { - s.rTPos = 0; - } - } - s.rNToGo -= 1; - s.k0 ^= if s.rNToGo == 1 { 1 } else { 0 }; - } else { - if s.tPos >= 100000_u32.wrapping_mul(s.blockSize100k as u32) - { - // NOTE: this originates in the BZ_GET_FAST macro, and the - // `return true` is probably uninitentional?! - return ReturnCode::BZ_RUN_OK; - } - s.tPos = tt[s.tPos as usize]; - s.k0 = (s.tPos & 0xff) as u8; - s.tPos >>= 8; - s.nblock_used += 1; + BZ_RAND_UPD_MASK!(s); + s.k0 ^= u8::from(s.rNToGo == 1) } } } @@ -1188,7 +1138,7 @@ pub(crate) fn decompress( /*--- Now the MTF values ---*/ EOB = s.nInUse + 1; - nblockMAX100k = s.blockSize100k as u8; + nblockMAX100k = s.blockSize100k; s.unzftab.fill(0); /*-- MTF init --*/