From fb5bd5806a9cbd5267c9e71dd7bb1139d186a466 Mon Sep 17 00:00:00 2001 From: Michiel Date: Tue, 15 Sep 2026 09:27:38 +0200 Subject: [PATCH 1/4] Implement `ZSTD_cParameter::get_bounds` as Result --- lib/compress/zstd_compress.rs | 193 +++++++++++++++++----------------- 1 file changed, 98 insertions(+), 95 deletions(-) diff --git a/lib/compress/zstd_compress.rs b/lib/compress/zstd_compress.rs index ee35ff13..2046ae8c 100644 --- a/lib/compress/zstd_compress.rs +++ b/lib/compress/zstd_compress.rs @@ -361,6 +361,87 @@ pub struct ZSTD_cpuid_t { pub f7c: u32, } +impl ZSTD_cParameter { + /// Get the upper and lower bound + const fn get_bounds(&self) -> Result<(core::ffi::c_int, core::ffi::c_int), Error> { + match *self { + Self::ZSTD_c_compressionLevel => Ok((ZSTD_minCLevel(), ZSTD_maxCLevel())), + Self::ZSTD_c_windowLog => Ok((ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX)), + Self::ZSTD_c_hashLog => Ok((ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX)), + Self::ZSTD_c_chainLog => Ok((ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX)), + Self::ZSTD_c_searchLog => Ok((ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX)), + Self::ZSTD_c_minMatch => Ok((ZSTD_MINMATCH_MIN, ZSTD_MINMATCH_MAX)), + Self::ZSTD_c_targetLength => Ok((ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX)), + Self::ZSTD_c_strategy => Ok((ZSTD_STRATEGY_MIN, ZSTD_STRATEGY_MAX)), + Self::ZSTD_c_contentSizeFlag => Ok((0, 1)), + Self::ZSTD_c_checksumFlag => Ok((0, 1)), + Self::ZSTD_c_dictIDFlag => Ok((0, 1)), + Self::ZSTD_c_nbWorkers => Ok((0, ZSTDMT_NBWORKERS_MAX)), + Self::ZSTD_c_jobSize => Ok((0, ZSTDMT_JOBSIZE_MAX)), + Self::ZSTD_c_overlapLog => Ok((ZSTD_OVERLAPLOG_MIN, ZSTD_OVERLAPLOG_MAX)), + Self::ZSTD_c_enableDedicatedDictSearch => Ok((0, 1)), + Self::ZSTD_c_enableLongDistanceMatching => Ok(( + ParamSwitch::Auto as core::ffi::c_int, + ParamSwitch::Disable as core::ffi::c_int, + )), + Self::ZSTD_c_ldmHashLog => Ok((ZSTD_LDM_HASHLOG_MIN, ZSTD_LDM_HASHLOG_MAX)), + Self::ZSTD_c_ldmMinMatch => Ok((ZSTD_LDM_MINMATCH_MIN, ZSTD_LDM_MINMATCH_MAX)), + Self::ZSTD_c_ldmBucketSizeLog => { + Ok((ZSTD_LDM_BUCKETSIZELOG_MIN, ZSTD_LDM_BUCKETSIZELOG_MAX)) + } + Self::ZSTD_c_ldmHashRateLog => Ok((ZSTD_LDM_HASHRATELOG_MIN, ZSTD_LDM_HASHRATELOG_MAX)), + Self::ZSTD_c_rsyncable => Ok((0, 1)), + Self::ZSTD_c_forceMaxWindow => Ok((0, 1)), + Self::ZSTD_c_format => Ok(( + Format::ZSTD_f_zstd1 as core::ffi::c_int, + Format::ZSTD_f_zstd1_magicless as core::ffi::c_int, + )), + Self::ZSTD_c_forceAttachDict => Ok(( + ZSTD_dictAttachPref_e::ZSTD_dictDefaultAttach.0 as core::ffi::c_int, + ZSTD_dictAttachPref_e::ZSTD_dictForceLoad.0 as core::ffi::c_int, + )), + Self::ZSTD_c_literalCompressionMode => Ok(( + ParamSwitch::Auto as core::ffi::c_int, + ParamSwitch::Disable as core::ffi::c_int, + )), + Self::ZSTD_c_targetCBlockSize => { + Ok((ZSTD_TARGETCBLOCKSIZE_MIN, ZSTD_TARGETCBLOCKSIZE_MAX)) + } + Self::ZSTD_c_srcSizeHint => Ok((ZSTD_SRCSIZEHINT_MIN, ZSTD_SRCSIZEHINT_MAX)), + Self::ZSTD_c_stableInBuffer | Self::ZSTD_c_stableOutBuffer => Ok(( + ZSTD_bm_buffered as core::ffi::c_int, + ZSTD_bm_stable as core::ffi::c_int, + )), + Self::ZSTD_c_blockDelimiters => Ok(( + ZSTD_sf_noBlockDelimiters as core::ffi::c_int, + ZSTD_sf_explicitBlockDelimiters as core::ffi::c_int, + )), + Self::ZSTD_c_validateSequences => Ok((0, 1)), + Self::ZSTD_c_splitAfterSequences => Ok(( + ParamSwitch::Auto as core::ffi::c_int, + ParamSwitch::Disable as core::ffi::c_int, + )), + Self::ZSTD_c_blockSplitterLevel => Ok((0, ZSTD_BLOCKSPLITTER_LEVEL_MAX)), + Self::ZSTD_c_useRowMatchFinder => Ok(( + ParamSwitch::Auto as core::ffi::c_int, + ParamSwitch::Disable as core::ffi::c_int, + )), + Self::ZSTD_c_deterministicRefPrefix => Ok((0, 1)), + Self::ZSTD_c_prefetchCDictTables => Ok(( + ParamSwitch::Auto as core::ffi::c_int, + ParamSwitch::Disable as core::ffi::c_int, + )), + Self::ZSTD_c_enableSeqProducerFallback => Ok((0, 1)), + Self::ZSTD_c_maxBlockSize => Ok((ZSTD_BLOCKSIZE_MAX_MIN, ZSTD_BLOCKSIZE_MAX)), + Self::ZSTD_c_repcodeResolution => Ok(( + ParamSwitch::Auto as core::ffi::c_int, + ParamSwitch::Disable as core::ffi::c_int, + )), + _ => Err(Error::parameter_unsupported), + } + } +} + #[derive(Copy, Clone)] #[repr(C)] pub struct ZSTD_bounds { @@ -369,20 +450,19 @@ pub struct ZSTD_bounds { pub upperBound: core::ffi::c_int, } -impl ZSTD_bounds { - pub fn new(lowerBound: core::ffi::c_int, upperBound: core::ffi::c_int) -> Self { - ZSTD_bounds { - error: 0, - lowerBound, - upperBound, - } - } - - pub fn error(error: size_t) -> Self { - ZSTD_bounds { - error, - lowerBound: 0, - upperBound: 0, +impl From for ZSTD_bounds { + fn from(param: ZSTD_cParameter) -> Self { + match param.get_bounds() { + Ok((lowerBound, upperBound)) => ZSTD_bounds { + error: 0, + lowerBound, + upperBound, + }, + Err(err) => ZSTD_bounds { + error: err.to_error_code(), + lowerBound: 0, + upperBound: 0, + }, } } } @@ -416,17 +496,10 @@ pub const ZSTD_MAX_NB_BLOCK_SPLITS: usize = 196; /// `true` if value is within cParam bounds #[inline] fn ZSTD_cParam_withinBounds(cParam: ZSTD_cParameter, value: core::ffi::c_int) -> bool { - let bounds = ZSTD_cParam_getBounds(cParam); - if ERR_isError(bounds.error) { - return false; - } - if value < bounds.lowerBound { - return false; - } - if value > bounds.upperBound { + let Ok((lowerBound, upperBound)) = cParam.get_bounds() else { return false; - } - true + }; + value >= lowerBound && value <= upperBound } #[inline] @@ -1455,77 +1528,7 @@ fn ZSTD_CCtxParams_setZstdParams(cctxParams: &mut ZSTD_CCtx_params, params: &ZST #[cfg_attr(feature = "export-symbols", export_name = crate::prefix!(ZSTD_cParam_getBounds))] pub extern "C" fn ZSTD_cParam_getBounds(param: ZSTD_cParameter) -> ZSTD_bounds { - match param.0 { - 100 => ZSTD_bounds::new(ZSTD_minCLevel(), ZSTD_maxCLevel()), - 101 => ZSTD_bounds::new(ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX), - 102 => ZSTD_bounds::new(ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX), - 103 => ZSTD_bounds::new(ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX), - 104 => ZSTD_bounds::new(ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX), - 105 => ZSTD_bounds::new(ZSTD_MINMATCH_MIN, ZSTD_MINMATCH_MAX), - 106 => ZSTD_bounds::new(ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX), - 107 => ZSTD_bounds::new(ZSTD_STRATEGY_MIN, ZSTD_STRATEGY_MAX), - 200 => ZSTD_bounds::new(0, 1), - 201 => ZSTD_bounds::new(0, 1), - 202 => ZSTD_bounds::new(0, 1), - 400 => ZSTD_bounds::new(0, ZSTDMT_NBWORKERS_MAX), - 401 => ZSTD_bounds::new(0, ZSTDMT_JOBSIZE_MAX), - 402 => ZSTD_bounds::new(ZSTD_OVERLAPLOG_MIN, ZSTD_OVERLAPLOG_MAX), - 1005 => ZSTD_bounds::new(0, 1), - 160 => ZSTD_bounds::new( - ParamSwitch::Auto as core::ffi::c_int, - ParamSwitch::Disable as core::ffi::c_int, - ), - 161 => ZSTD_bounds::new(ZSTD_LDM_HASHLOG_MIN, ZSTD_LDM_HASHLOG_MAX), - 162 => ZSTD_bounds::new(ZSTD_LDM_MINMATCH_MIN, ZSTD_LDM_MINMATCH_MAX), - 163 => ZSTD_bounds::new(ZSTD_LDM_BUCKETSIZELOG_MIN, ZSTD_LDM_BUCKETSIZELOG_MAX), - 164 => ZSTD_bounds::new(ZSTD_LDM_HASHRATELOG_MIN, ZSTD_LDM_HASHRATELOG_MAX), - 500 => ZSTD_bounds::new(0, 1), - 1000 => ZSTD_bounds::new(0, 1), - 10 => ZSTD_bounds::new( - Format::ZSTD_f_zstd1 as core::ffi::c_int, - Format::ZSTD_f_zstd1_magicless as core::ffi::c_int, - ), - 1001 => ZSTD_bounds::new( - ZSTD_dictAttachPref_e::ZSTD_dictDefaultAttach.0 as core::ffi::c_int, - ZSTD_dictAttachPref_e::ZSTD_dictForceLoad.0 as core::ffi::c_int, - ), - 1002 => ZSTD_bounds::new( - ParamSwitch::Auto as core::ffi::c_int, - ParamSwitch::Disable as core::ffi::c_int, - ), - 130 => ZSTD_bounds::new(ZSTD_TARGETCBLOCKSIZE_MIN, ZSTD_TARGETCBLOCKSIZE_MAX), - 1004 => ZSTD_bounds::new(ZSTD_SRCSIZEHINT_MIN, ZSTD_SRCSIZEHINT_MAX), - 1006 | 1007 => ZSTD_bounds::new( - ZSTD_bm_buffered as core::ffi::c_int, - ZSTD_bm_stable as core::ffi::c_int, - ), - 1008 => ZSTD_bounds::new( - ZSTD_sf_noBlockDelimiters as core::ffi::c_int, - ZSTD_sf_explicitBlockDelimiters as core::ffi::c_int, - ), - 1009 => ZSTD_bounds::new(0, 1), - 1010 => ZSTD_bounds::new( - ParamSwitch::Auto as core::ffi::c_int, - ParamSwitch::Disable as core::ffi::c_int, - ), - 1017 => ZSTD_bounds::new(0, ZSTD_BLOCKSPLITTER_LEVEL_MAX), - 1011 => ZSTD_bounds::new( - ParamSwitch::Auto as core::ffi::c_int, - ParamSwitch::Disable as core::ffi::c_int, - ), - 1012 => ZSTD_bounds::new(0, 1), - 1013 => ZSTD_bounds::new( - ParamSwitch::Auto as core::ffi::c_int, - ParamSwitch::Disable as core::ffi::c_int, - ), - 1014 => ZSTD_bounds::new(0, 1), - 1015 => ZSTD_bounds::new(ZSTD_BLOCKSIZE_MAX_MIN, ZSTD_BLOCKSIZE_MAX), - 1016 => ZSTD_bounds::new( - ParamSwitch::Auto as core::ffi::c_int, - ParamSwitch::Disable as core::ffi::c_int, - ), - _ => ZSTD_bounds::error(Error::parameter_unsupported.to_error_code()), - } + ZSTD_bounds::from(param) } /// Clamps the value into the bounded range. From 32692167b43e545db435b46f24685b1becc3277d Mon Sep 17 00:00:00 2001 From: Michiel Date: Tue, 15 Sep 2026 10:21:49 +0200 Subject: [PATCH 2/4] Implement `ZSTD_cParam_clampBounds` on `ZSTD_cParameter` --- lib/compress/zstd_compress.rs | 118 ++++++++++++++-------------------- 1 file changed, 47 insertions(+), 71 deletions(-) diff --git a/lib/compress/zstd_compress.rs b/lib/compress/zstd_compress.rs index 2046ae8c..3dc4d3f3 100644 --- a/lib/compress/zstd_compress.rs +++ b/lib/compress/zstd_compress.rs @@ -440,6 +440,22 @@ impl ZSTD_cParameter { _ => Err(Error::parameter_unsupported), } } + + /// Clamps the value into the bounded range of the cParam + #[inline] + fn clamp_bounds(&self, value: &mut core::ffi::c_int) -> Result<(), Error> { + let (lowerBound, upperBound) = self.get_bounds()?; + *value = (*value).clamp(lowerBound, upperBound); + Ok(()) + } + + /// Same as [`Self::clamp_bounds`], but for unsigned valued + #[inline] + fn clamp_bounds_unsigned(&self, value: &mut core::ffi::c_uint) -> Result<(), Error> { + let (lowerBound, upperBound) = self.get_bounds()?; + *value = (*value as core::ffi::c_int).clamp(lowerBound, upperBound) as core::ffi::c_uint; + Ok(()) + } } #[derive(Copy, Clone)] @@ -1531,18 +1547,6 @@ pub extern "C" fn ZSTD_cParam_getBounds(param: ZSTD_cParameter) -> ZSTD_bounds { ZSTD_bounds::from(param) } -/// Clamps the value into the bounded range. -fn ZSTD_cParam_clampBounds(cParam: ZSTD_cParameter, value: &mut core::ffi::c_int) -> size_t { - let bounds = ZSTD_cParam_getBounds(cParam); - if ERR_isError(bounds.error) { - return bounds.error; - } - - *value = (*value).clamp(bounds.lowerBound, bounds.upperBound); - - 0 -} - fn ZSTD_isUpdateAuthorized(param: ZSTD_cParameter) -> bool { match param { ZSTD_cParameter::ZSTD_c_compressionLevel @@ -1643,9 +1647,8 @@ pub unsafe extern "C" fn ZSTD_CCtxParams_setParameter( (*CCtxParams).format as size_t } 100 => { - let err_code = ZSTD_cParam_clampBounds(param, &mut value); - if ERR_isError(err_code) { - return err_code; + if let Err(err) = param.clamp_bounds(&mut value) { + return err.to_error_code(); } if value == 0 { (*CCtxParams).compressionLevel = ZSTD_CLEVEL_DEFAULT; @@ -1737,9 +1740,8 @@ pub unsafe extern "C" fn ZSTD_CCtxParams_setParameter( (*CCtxParams).literalCompressionMode as size_t } 400 => { - let err_code_0 = ZSTD_cParam_clampBounds(param, &mut value); - if ERR_isError(err_code_0) { - return err_code_0; + if let Err(err) = param.clamp_bounds(&mut value) { + return err.to_error_code(); } (*CCtxParams).nbWorkers = value; (*CCtxParams).nbWorkers as size_t @@ -1748,27 +1750,22 @@ pub unsafe extern "C" fn ZSTD_CCtxParams_setParameter( if value != 0 && value < ZSTDMT_JOBSIZE_MIN { value = ZSTDMT_JOBSIZE_MIN; } - let err_code_1 = ZSTD_cParam_clampBounds(param, &mut value); - if ERR_isError(err_code_1) { - return err_code_1; + if let Err(err) = param.clamp_bounds(&mut value) { + return err.to_error_code(); } (*CCtxParams).jobSize = value as size_t; (*CCtxParams).jobSize } 402 => { - let err_code_2 = - ZSTD_cParam_clampBounds(ZSTD_cParameter::ZSTD_c_overlapLog, &mut value); - if ERR_isError(err_code_2) { - return err_code_2; + if let Err(err) = param.clamp_bounds(&mut value) { + return err.to_error_code(); } (*CCtxParams).overlapLog = value; (*CCtxParams).overlapLog as size_t } 500 => { - let err_code_3 = - ZSTD_cParam_clampBounds(ZSTD_cParameter::ZSTD_c_overlapLog, &mut value); - if ERR_isError(err_code_3) { - return err_code_3; + if let Err(err) = param.clamp_bounds(&mut value) { + return err.to_error_code(); } (*CCtxParams).rsyncable = value; (*CCtxParams).rsyncable as size_t @@ -2452,48 +2449,27 @@ pub extern "C" fn ZSTD_checkCParams(cParams: ZSTD_compressionParameters) -> size /// Make CParam values within valid range. fn ZSTD_clampCParams(mut cParams: ZSTD_compressionParameters) -> ZSTD_compressionParameters { - let bounds = ZSTD_cParam_getBounds(ZSTD_cParameter::ZSTD_c_windowLog); - if (cParams.windowLog as core::ffi::c_int) < bounds.lowerBound { - cParams.windowLog = bounds.lowerBound as core::ffi::c_uint; - } else if cParams.windowLog as core::ffi::c_int > bounds.upperBound { - cParams.windowLog = bounds.upperBound as core::ffi::c_uint; - } - let bounds_0 = ZSTD_cParam_getBounds(ZSTD_cParameter::ZSTD_c_chainLog); - if (cParams.chainLog as core::ffi::c_int) < bounds_0.lowerBound { - cParams.chainLog = bounds_0.lowerBound as core::ffi::c_uint; - } else if cParams.chainLog as core::ffi::c_int > bounds_0.upperBound { - cParams.chainLog = bounds_0.upperBound as core::ffi::c_uint; - } - let bounds_1 = ZSTD_cParam_getBounds(ZSTD_cParameter::ZSTD_c_hashLog); - if (cParams.hashLog as core::ffi::c_int) < bounds_1.lowerBound { - cParams.hashLog = bounds_1.lowerBound as core::ffi::c_uint; - } else if cParams.hashLog as core::ffi::c_int > bounds_1.upperBound { - cParams.hashLog = bounds_1.upperBound as core::ffi::c_uint; - } - let bounds_2 = ZSTD_cParam_getBounds(ZSTD_cParameter::ZSTD_c_searchLog); - if (cParams.searchLog as core::ffi::c_int) < bounds_2.lowerBound { - cParams.searchLog = bounds_2.lowerBound as core::ffi::c_uint; - } else if cParams.searchLog as core::ffi::c_int > bounds_2.upperBound { - cParams.searchLog = bounds_2.upperBound as core::ffi::c_uint; - } - let bounds_3 = ZSTD_cParam_getBounds(ZSTD_cParameter::ZSTD_c_minMatch); - if (cParams.minMatch as core::ffi::c_int) < bounds_3.lowerBound { - cParams.minMatch = bounds_3.lowerBound as core::ffi::c_uint; - } else if cParams.minMatch as core::ffi::c_int > bounds_3.upperBound { - cParams.minMatch = bounds_3.upperBound as core::ffi::c_uint; - } - let bounds_4 = ZSTD_cParam_getBounds(ZSTD_cParameter::ZSTD_c_targetLength); - if (cParams.targetLength as core::ffi::c_int) < bounds_4.lowerBound { - cParams.targetLength = bounds_4.lowerBound as core::ffi::c_uint; - } else if cParams.targetLength as core::ffi::c_int > bounds_4.upperBound { - cParams.targetLength = bounds_4.upperBound as core::ffi::c_uint; - } - let bounds_5 = ZSTD_cParam_getBounds(ZSTD_cParameter::ZSTD_c_strategy); - if (cParams.strategy as core::ffi::c_int) < bounds_5.lowerBound { - cParams.strategy = bounds_5.lowerBound as ZSTD_strategy; - } else if cParams.strategy as core::ffi::c_int > bounds_5.upperBound { - cParams.strategy = bounds_5.upperBound as ZSTD_strategy; - } + ZSTD_cParameter::ZSTD_c_windowLog + .clamp_bounds_unsigned(&mut cParams.windowLog) + .unwrap(); + ZSTD_cParameter::ZSTD_c_chainLog + .clamp_bounds_unsigned(&mut cParams.chainLog) + .unwrap(); + ZSTD_cParameter::ZSTD_c_hashLog + .clamp_bounds_unsigned(&mut cParams.hashLog) + .unwrap(); + ZSTD_cParameter::ZSTD_c_searchLog + .clamp_bounds_unsigned(&mut cParams.searchLog) + .unwrap(); + ZSTD_cParameter::ZSTD_c_minMatch + .clamp_bounds_unsigned(&mut cParams.minMatch) + .unwrap(); + ZSTD_cParameter::ZSTD_c_targetLength + .clamp_bounds_unsigned(&mut cParams.targetLength) + .unwrap(); + ZSTD_cParameter::ZSTD_c_strategy + .clamp_bounds_unsigned(&mut cParams.strategy) + .unwrap(); cParams } From 9b201adedf508b60e3ea2c1a462506d7ef0d06ea Mon Sep 17 00:00:00 2001 From: Michiel Date: Tue, 15 Sep 2026 10:55:02 +0200 Subject: [PATCH 3/4] Implement `ZSTD_cParam_withinBounds` on `ZSTD_cParameter` --- lib/compress/zstd_compress.rs | 104 ++++++++++++---------------------- 1 file changed, 36 insertions(+), 68 deletions(-) diff --git a/lib/compress/zstd_compress.rs b/lib/compress/zstd_compress.rs index 3dc4d3f3..2b3140c6 100644 --- a/lib/compress/zstd_compress.rs +++ b/lib/compress/zstd_compress.rs @@ -456,6 +456,13 @@ impl ZSTD_cParameter { *value = (*value as core::ffi::c_int).clamp(lowerBound, upperBound) as core::ffi::c_uint; Ok(()) } + + /// Returns `true` if value is within cParam bounds + #[inline] + fn within_bounds(&self, value: core::ffi::c_int) -> bool { + self.get_bounds() + .is_ok_and(|(lowerBound, upperBound)| value >= lowerBound && value <= upperBound) + } } #[derive(Copy, Clone)] @@ -507,17 +514,6 @@ pub const ZSTD_BLOCKSPLITTER_LEVEL_MAX: core::ffi::c_int = 6; pub const ZSTD_OPT_SIZE: core::ffi::c_int = ZSTD_OPT_NUM + 3; pub const ZSTD_MAX_NB_BLOCK_SPLITS: usize = 196; -/// # Returns -/// -/// `true` if value is within cParam bounds -#[inline] -fn ZSTD_cParam_withinBounds(cParam: ZSTD_cParameter, value: core::ffi::c_int) -> bool { - let Ok((lowerBound, upperBound)) = cParam.get_bounds() else { - return false; - }; - value >= lowerBound && value <= upperBound -} - #[inline] unsafe fn ZSTD_rleCompressBlock( dst: *mut core::ffi::c_void, @@ -1661,49 +1657,49 @@ pub unsafe extern "C" fn ZSTD_CCtxParams_setParameter( 0 } 101 => { - if value != 0 && !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_windowLog, value) { + if value != 0 && !ZSTD_cParameter::ZSTD_c_windowLog.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).cParams.windowLog = value as u32; (*CCtxParams).cParams.windowLog as size_t } 102 => { - if value != 0 && !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_hashLog, value) { + if value != 0 && !ZSTD_cParameter::ZSTD_c_hashLog.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).cParams.hashLog = value as u32; (*CCtxParams).cParams.hashLog as size_t } 103 => { - if value != 0 && !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_chainLog, value) { + if value != 0 && !ZSTD_cParameter::ZSTD_c_chainLog.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).cParams.chainLog = value as u32; (*CCtxParams).cParams.chainLog as size_t } 104 => { - if value != 0 && !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_searchLog, value) { + if value != 0 && !ZSTD_cParameter::ZSTD_c_searchLog.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).cParams.searchLog = value as u32; value as size_t } 105 => { - if value != 0 && !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_minMatch, value) { + if value != 0 && !ZSTD_cParameter::ZSTD_c_minMatch.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).cParams.minMatch = value as u32; (*CCtxParams).cParams.minMatch as size_t } 106 => { - if !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_targetLength, value) { + if !ZSTD_cParameter::ZSTD_c_targetLength.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).cParams.targetLength = value as u32; (*CCtxParams).cParams.targetLength as size_t } 107 => { - if value != 0 && !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_strategy, value) { + if value != 0 && !ZSTD_cParameter::ZSTD_c_strategy.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).cParams.strategy = value as ZSTD_strategy; @@ -1782,32 +1778,28 @@ pub unsafe extern "C" fn ZSTD_CCtxParams_setParameter( (*CCtxParams).ldmParams.enableLdm as size_t } 161 => { - if value != 0 && !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_ldmHashLog, value) { + if value != 0 && !ZSTD_cParameter::ZSTD_c_ldmHashLog.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).ldmParams.hashLog = value as u32; (*CCtxParams).ldmParams.hashLog as size_t } 162 => { - if value != 0 && !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_ldmMinMatch, value) { + if value != 0 && !ZSTD_cParameter::ZSTD_c_ldmMinMatch.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).ldmParams.minMatchLength = value as u32; (*CCtxParams).ldmParams.minMatchLength as size_t } 163 => { - if value != 0 - && !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_ldmBucketSizeLog, value) - { + if value != 0 && !ZSTD_cParameter::ZSTD_c_ldmBucketSizeLog.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).ldmParams.bucketSizeLog = value as u32; (*CCtxParams).ldmParams.bucketSizeLog as size_t } 164 => { - if value != 0 - && !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_ldmHashRateLog, value) - { + if value != 0 && !ZSTD_cParameter::ZSTD_c_ldmHashRateLog.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).ldmParams.hashRateLog = value as u32; @@ -1816,7 +1808,7 @@ pub unsafe extern "C" fn ZSTD_CCtxParams_setParameter( 130 => { if value != 0 { value = value.max(ZSTD_TARGETCBLOCKSIZE_MIN); - if !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_targetCBlockSize, value) { + if !ZSTD_cParameter::ZSTD_c_targetCBlockSize.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } } @@ -1824,37 +1816,35 @@ pub unsafe extern "C" fn ZSTD_CCtxParams_setParameter( (*CCtxParams).targetCBlockSize } 1004 => { - if value != 0 - && !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_experimentalParam7, value) - { + if value != 0 && !ZSTD_cParameter::ZSTD_c_srcSizeHint.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).srcSizeHint = value; (*CCtxParams).srcSizeHint as size_t } 1006 => { - if !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_experimentalParam9, value) { + if !ZSTD_cParameter::ZSTD_c_stableInBuffer.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).inBufferMode = value as ZSTD_bufferMode_e; (*CCtxParams).inBufferMode as size_t } 1007 => { - if !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_experimentalParam10, value) { + if !ZSTD_cParameter::ZSTD_c_stableOutBuffer.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).outBufferMode = value as ZSTD_bufferMode_e; (*CCtxParams).outBufferMode as size_t } 1008 => { - if !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_experimentalParam11, value) { + if !ZSTD_cParameter::ZSTD_c_blockDelimiters.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).blockDelimiters = value as ZSTD_SequenceFormat_e; (*CCtxParams).blockDelimiters as size_t } 1009 => { - if !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_experimentalParam12, value) { + if !ZSTD_cParameter::ZSTD_c_validateSequences.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).validateSequences = value; @@ -1868,7 +1858,7 @@ pub unsafe extern "C" fn ZSTD_CCtxParams_setParameter( (*CCtxParams).postBlockSplitter as size_t } 1017 => { - if !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_experimentalParam20, value) { + if !ZSTD_cParameter::ZSTD_c_blockSplitterLevel.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).preBlockSplitter_level = value; @@ -1882,7 +1872,7 @@ pub unsafe extern "C" fn ZSTD_CCtxParams_setParameter( (*CCtxParams).useRowMatchFinder as size_t } 1012 => { - if !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_experimentalParam15, value) { + if !ZSTD_cParameter::ZSTD_c_deterministicRefPrefix.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).deterministicRefPrefix = (value != 0) as core::ffi::c_int; @@ -1896,16 +1886,14 @@ pub unsafe extern "C" fn ZSTD_CCtxParams_setParameter( (*CCtxParams).prefetchCDictTables as size_t } 1014 => { - if !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_experimentalParam17, value) { + if !ZSTD_cParameter::ZSTD_c_enableSeqProducerFallback.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).enableMatchFinderFallback = value; (*CCtxParams).enableMatchFinderFallback as size_t } 1015 => { - if value != 0 - && !ZSTD_cParam_withinBounds(ZSTD_cParameter::ZSTD_c_experimentalParam18, value) - { + if value != 0 && !ZSTD_cParameter::ZSTD_c_maxBlockSize.within_bounds(value) { return Error::parameter_outOfBound.to_error_code(); } (*CCtxParams).maxBlockSize = value as size_t; @@ -2401,46 +2389,26 @@ pub unsafe extern "C" fn ZSTD_CCtx_reset( /// 0, or an error code if one value is beyond authorized range. #[cfg_attr(feature = "export-symbols", export_name = crate::prefix!(ZSTD_checkCParams))] pub extern "C" fn ZSTD_checkCParams(cParams: ZSTD_compressionParameters) -> size_t { - if !ZSTD_cParam_withinBounds( - ZSTD_cParameter::ZSTD_c_windowLog, - cParams.windowLog as core::ffi::c_int, - ) { + if !ZSTD_cParameter::ZSTD_c_windowLog.within_bounds(cParams.windowLog as core::ffi::c_int) { return Error::parameter_outOfBound.to_error_code(); } - if !ZSTD_cParam_withinBounds( - ZSTD_cParameter::ZSTD_c_chainLog, - cParams.chainLog as core::ffi::c_int, - ) { + if !ZSTD_cParameter::ZSTD_c_chainLog.within_bounds(cParams.chainLog as core::ffi::c_int) { return Error::parameter_outOfBound.to_error_code(); } - if !ZSTD_cParam_withinBounds( - ZSTD_cParameter::ZSTD_c_hashLog, - cParams.hashLog as core::ffi::c_int, - ) { + if !ZSTD_cParameter::ZSTD_c_hashLog.within_bounds(cParams.hashLog as core::ffi::c_int) { return Error::parameter_outOfBound.to_error_code(); } - if !ZSTD_cParam_withinBounds( - ZSTD_cParameter::ZSTD_c_searchLog, - cParams.searchLog as core::ffi::c_int, - ) { + if !ZSTD_cParameter::ZSTD_c_searchLog.within_bounds(cParams.searchLog as core::ffi::c_int) { return Error::parameter_outOfBound.to_error_code(); } - if !ZSTD_cParam_withinBounds( - ZSTD_cParameter::ZSTD_c_minMatch, - cParams.minMatch as core::ffi::c_int, - ) { + if !ZSTD_cParameter::ZSTD_c_minMatch.within_bounds(cParams.minMatch as core::ffi::c_int) { return Error::parameter_outOfBound.to_error_code(); } - if !ZSTD_cParam_withinBounds( - ZSTD_cParameter::ZSTD_c_targetLength, - cParams.targetLength as core::ffi::c_int, - ) { + if !ZSTD_cParameter::ZSTD_c_targetLength.within_bounds(cParams.targetLength as core::ffi::c_int) + { return Error::parameter_outOfBound.to_error_code(); } - if !ZSTD_cParam_withinBounds( - ZSTD_cParameter::ZSTD_c_strategy, - cParams.strategy as core::ffi::c_int, - ) { + if !ZSTD_cParameter::ZSTD_c_strategy.within_bounds(cParams.strategy as core::ffi::c_int) { return Error::parameter_outOfBound.to_error_code(); } From 1b6aa787e3cb5c0c3e93360ffa12b065f7788c8f Mon Sep 17 00:00:00 2001 From: Michiel Date: Tue, 15 Sep 2026 11:11:53 +0200 Subject: [PATCH 4/4] Clean up `ParamSwitch` bounds --- lib/compress/zstd_compress.rs | 30 ++++++------------------------ lib/zstd.rs | 3 +++ 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/lib/compress/zstd_compress.rs b/lib/compress/zstd_compress.rs index 2b3140c6..86f299fb 100644 --- a/lib/compress/zstd_compress.rs +++ b/lib/compress/zstd_compress.rs @@ -380,10 +380,7 @@ impl ZSTD_cParameter { Self::ZSTD_c_jobSize => Ok((0, ZSTDMT_JOBSIZE_MAX)), Self::ZSTD_c_overlapLog => Ok((ZSTD_OVERLAPLOG_MIN, ZSTD_OVERLAPLOG_MAX)), Self::ZSTD_c_enableDedicatedDictSearch => Ok((0, 1)), - Self::ZSTD_c_enableLongDistanceMatching => Ok(( - ParamSwitch::Auto as core::ffi::c_int, - ParamSwitch::Disable as core::ffi::c_int, - )), + Self::ZSTD_c_enableLongDistanceMatching => Ok(ParamSwitch::BOUNDS), Self::ZSTD_c_ldmHashLog => Ok((ZSTD_LDM_HASHLOG_MIN, ZSTD_LDM_HASHLOG_MAX)), Self::ZSTD_c_ldmMinMatch => Ok((ZSTD_LDM_MINMATCH_MIN, ZSTD_LDM_MINMATCH_MAX)), Self::ZSTD_c_ldmBucketSizeLog => { @@ -400,10 +397,7 @@ impl ZSTD_cParameter { ZSTD_dictAttachPref_e::ZSTD_dictDefaultAttach.0 as core::ffi::c_int, ZSTD_dictAttachPref_e::ZSTD_dictForceLoad.0 as core::ffi::c_int, )), - Self::ZSTD_c_literalCompressionMode => Ok(( - ParamSwitch::Auto as core::ffi::c_int, - ParamSwitch::Disable as core::ffi::c_int, - )), + Self::ZSTD_c_literalCompressionMode => Ok(ParamSwitch::BOUNDS), Self::ZSTD_c_targetCBlockSize => { Ok((ZSTD_TARGETCBLOCKSIZE_MIN, ZSTD_TARGETCBLOCKSIZE_MAX)) } @@ -417,26 +411,14 @@ impl ZSTD_cParameter { ZSTD_sf_explicitBlockDelimiters as core::ffi::c_int, )), Self::ZSTD_c_validateSequences => Ok((0, 1)), - Self::ZSTD_c_splitAfterSequences => Ok(( - ParamSwitch::Auto as core::ffi::c_int, - ParamSwitch::Disable as core::ffi::c_int, - )), + Self::ZSTD_c_splitAfterSequences => Ok(ParamSwitch::BOUNDS), Self::ZSTD_c_blockSplitterLevel => Ok((0, ZSTD_BLOCKSPLITTER_LEVEL_MAX)), - Self::ZSTD_c_useRowMatchFinder => Ok(( - ParamSwitch::Auto as core::ffi::c_int, - ParamSwitch::Disable as core::ffi::c_int, - )), + Self::ZSTD_c_useRowMatchFinder => Ok(ParamSwitch::BOUNDS), Self::ZSTD_c_deterministicRefPrefix => Ok((0, 1)), - Self::ZSTD_c_prefetchCDictTables => Ok(( - ParamSwitch::Auto as core::ffi::c_int, - ParamSwitch::Disable as core::ffi::c_int, - )), + Self::ZSTD_c_prefetchCDictTables => Ok(ParamSwitch::BOUNDS), Self::ZSTD_c_enableSeqProducerFallback => Ok((0, 1)), Self::ZSTD_c_maxBlockSize => Ok((ZSTD_BLOCKSIZE_MAX_MIN, ZSTD_BLOCKSIZE_MAX)), - Self::ZSTD_c_repcodeResolution => Ok(( - ParamSwitch::Auto as core::ffi::c_int, - ParamSwitch::Disable as core::ffi::c_int, - )), + Self::ZSTD_c_repcodeResolution => Ok(ParamSwitch::BOUNDS), _ => Err(Error::parameter_unsupported), } } diff --git a/lib/zstd.rs b/lib/zstd.rs index 194c8018..f1800ba8 100644 --- a/lib/zstd.rs +++ b/lib/zstd.rs @@ -677,6 +677,9 @@ pub enum ParamSwitch { } impl ParamSwitch { + /// The lower and upper bound of this enum + pub const BOUNDS: (core::ffi::c_int, core::ffi::c_int) = (Self::Auto as _, Self::Disable as _); + pub fn to_i32(self) -> i32 { self as i32 }