refactor(cdict): move static initializer error policy to Rust
Keep the private static-CDict initializer in C, but return its native size_t status through the callback boundary. Rust now owns the public success-or-NULL mapping, preserving the original workspace validation, callback order, and private layout ownership while making initializer failures explicit and unit-testable. Test Plan: ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings; cargo +nightly fmt --manifest-path rust/Cargo.toml --all -- --check; GCC and Clang syntax-only checks; make -j1 -C tests test (all 41 shell tests, fuzzer, zstd tester, and zstream tester passed).
This commit is contained in:
@@ -463,7 +463,7 @@ typedef void (*ZSTD_rust_initStaticCDictMoveWorkspace_f)(
|
||||
void* context, void* cdict);
|
||||
typedef void (*ZSTD_rust_initStaticCDictInitialize_f)(
|
||||
void* context, void* cdict, int useRowMatchFinder);
|
||||
typedef void* (*ZSTD_rust_initStaticCDictInit_f)(
|
||||
typedef size_t (*ZSTD_rust_initStaticCDictInit_f)(
|
||||
void* context, void* cdict);
|
||||
typedef struct {
|
||||
void* callbackContext;
|
||||
@@ -7306,16 +7306,14 @@ static void ZSTD_rust_initStaticCDict_initialize(
|
||||
dictionary->compressionLevel = ZSTD_NO_CLEVEL;
|
||||
}
|
||||
|
||||
static void* ZSTD_rust_initStaticCDict_init(void* opaque, void* cdict)
|
||||
static size_t ZSTD_rust_initStaticCDict_init(void* opaque, void* cdict)
|
||||
{
|
||||
ZSTD_rust_initStaticCDictContext const* const context =
|
||||
(const ZSTD_rust_initStaticCDictContext*)opaque;
|
||||
if (ZSTD_isError( ZSTD_initCDict_internal(
|
||||
return ZSTD_initCDict_internal(
|
||||
(ZSTD_CDict*)cdict, context->dict, context->dictSize,
|
||||
context->dictLoadMethod, context->dictContentType,
|
||||
context->params) ))
|
||||
return NULL;
|
||||
return cdict;
|
||||
context->params);
|
||||
}
|
||||
|
||||
const ZSTD_CDict* ZSTD_initStaticCDict(
|
||||
|
||||
@@ -1091,7 +1091,7 @@ type InitStaticCDictCreateWorkspaceFn = unsafe extern "C" fn(*mut c_void);
|
||||
type InitStaticCDictReserveObjectFn = unsafe extern "C" fn(*mut c_void) -> *mut c_void;
|
||||
type InitStaticCDictMoveWorkspaceFn = unsafe extern "C" fn(*mut c_void, *mut c_void);
|
||||
type InitStaticCDictInitializeFn = unsafe extern "C" fn(*mut c_void, *mut c_void, c_int);
|
||||
type InitStaticCDictFn = unsafe extern "C" fn(*mut c_void, *mut c_void) -> *mut c_void;
|
||||
type InitStaticCDictFn = unsafe extern "C" fn(*mut c_void, *mut c_void) -> usize;
|
||||
|
||||
/// Explicit projection for the public `ZSTD_initStaticCDict` wrapper.
|
||||
///
|
||||
@@ -1130,7 +1130,16 @@ const _: () = {
|
||||
assert!(size_of::<ZSTD_rust_initStaticCDictState>() == size_of::<[usize; 12]>());
|
||||
};
|
||||
|
||||
#[inline]
|
||||
fn static_cdict_init_succeeded(result: usize) -> bool {
|
||||
!ERR_isError(result)
|
||||
}
|
||||
|
||||
/// Validate static CDict workspace ownership before entering the C leaf.
|
||||
///
|
||||
/// The C initializer returns the private `ZSTD_initCDict_internal()` result;
|
||||
/// Rust owns the public pointer-or-NULL mapping so the C callback remains a
|
||||
/// layout/configuration operation only.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ZSTD_rust_initStaticCDict(
|
||||
state: *const ZSTD_rust_initStaticCDictState,
|
||||
@@ -1170,10 +1179,15 @@ pub unsafe extern "C" fn ZSTD_rust_initStaticCDict(
|
||||
if cdict.is_null() {
|
||||
return ptr::null_mut();
|
||||
}
|
||||
unsafe {
|
||||
let init_result = unsafe {
|
||||
(state.move_workspace)(state.callback_context, cdict);
|
||||
(state.initialize)(state.callback_context, cdict, use_row_match_finder);
|
||||
(state.init)(state.callback_context, cdict)
|
||||
};
|
||||
if static_cdict_init_succeeded(init_result) {
|
||||
cdict
|
||||
} else {
|
||||
ptr::null_mut()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5205,7 +5219,7 @@ mod tests {
|
||||
init_cdict: *mut c_void,
|
||||
use_row_match_finder: c_int,
|
||||
initialized: bool,
|
||||
result: *mut c_void,
|
||||
init_result: usize,
|
||||
}
|
||||
|
||||
unsafe extern "C" fn init_static_cdict_test_create_workspace(context: *mut c_void) {
|
||||
@@ -5245,11 +5259,11 @@ mod tests {
|
||||
unsafe extern "C" fn init_static_cdict_test_init(
|
||||
context: *mut c_void,
|
||||
cdict: *mut c_void,
|
||||
) -> *mut c_void {
|
||||
) -> usize {
|
||||
let probe = unsafe { &mut *context.cast::<InitStaticCDictProbe>() };
|
||||
probe.events.push("init");
|
||||
probe.init_cdict = cdict;
|
||||
probe.result
|
||||
probe.init_result
|
||||
}
|
||||
|
||||
fn init_static_cdict_test_state(
|
||||
@@ -5308,12 +5322,18 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn static_cdict_initializer_maps_error_status_to_null() {
|
||||
assert!(static_cdict_init_succeeded(0));
|
||||
assert!(static_cdict_init_succeeded(1));
|
||||
assert!(!static_cdict_init_succeeded(ERROR(
|
||||
ZstdErrorCode::MemoryAllocation
|
||||
)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn init_static_cdict_rejects_an_unaligned_workspace_before_callback() {
|
||||
let mut probe = InitStaticCDictProbe {
|
||||
result: ptr::dangling_mut(),
|
||||
..Default::default()
|
||||
};
|
||||
let mut probe = InitStaticCDictProbe::default();
|
||||
let mut workspace = [0usize; 2];
|
||||
let unaligned_workspace = workspace.as_mut_ptr().cast::<u8>().wrapping_add(1).cast();
|
||||
let c_params = init_static_cdict_test_cparams();
|
||||
@@ -5335,10 +5355,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn init_static_cdict_rejects_insufficient_workspace_before_callback() {
|
||||
let mut probe = InitStaticCDictProbe {
|
||||
result: ptr::dangling_mut(),
|
||||
..Default::default()
|
||||
};
|
||||
let mut probe = InitStaticCDictProbe::default();
|
||||
let mut workspace = [0usize; 1];
|
||||
let c_params = init_static_cdict_test_cparams();
|
||||
let state = init_static_cdict_test_state(
|
||||
@@ -5362,7 +5379,6 @@ mod tests {
|
||||
let cdict = ptr::dangling_mut::<c_void>();
|
||||
let mut probe = InitStaticCDictProbe {
|
||||
reserved_cdict: cdict,
|
||||
result: ptr::dangling_mut(),
|
||||
..Default::default()
|
||||
};
|
||||
let c_params = init_static_cdict_test_cparams();
|
||||
@@ -5379,7 +5395,7 @@ mod tests {
|
||||
|
||||
let result = unsafe { ZSTD_rust_initStaticCDict(&state) };
|
||||
|
||||
assert_eq!(result, probe.result);
|
||||
assert_eq!(result, cdict);
|
||||
assert_eq!(
|
||||
probe.events,
|
||||
[
|
||||
@@ -5428,7 +5444,7 @@ mod tests {
|
||||
let cdict = ptr::dangling_mut::<c_void>();
|
||||
let mut probe = InitStaticCDictProbe {
|
||||
reserved_cdict: cdict,
|
||||
result: ptr::null_mut(),
|
||||
init_result: ERROR(ZstdErrorCode::MemoryAllocation),
|
||||
..Default::default()
|
||||
};
|
||||
let c_params = init_static_cdict_test_cparams();
|
||||
@@ -5462,10 +5478,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn init_static_cdict_rejects_a_null_workspace() {
|
||||
let mut probe = InitStaticCDictProbe {
|
||||
result: ptr::dangling_mut(),
|
||||
..Default::default()
|
||||
};
|
||||
let mut probe = InitStaticCDictProbe::default();
|
||||
let c_params = init_static_cdict_test_cparams();
|
||||
let state = init_static_cdict_test_state(
|
||||
&mut probe,
|
||||
|
||||
Reference in New Issue
Block a user