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);
|
void* context, void* cdict);
|
||||||
typedef void (*ZSTD_rust_initStaticCDictInitialize_f)(
|
typedef void (*ZSTD_rust_initStaticCDictInitialize_f)(
|
||||||
void* context, void* cdict, int useRowMatchFinder);
|
void* context, void* cdict, int useRowMatchFinder);
|
||||||
typedef void* (*ZSTD_rust_initStaticCDictInit_f)(
|
typedef size_t (*ZSTD_rust_initStaticCDictInit_f)(
|
||||||
void* context, void* cdict);
|
void* context, void* cdict);
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void* callbackContext;
|
void* callbackContext;
|
||||||
@@ -7306,16 +7306,14 @@ static void ZSTD_rust_initStaticCDict_initialize(
|
|||||||
dictionary->compressionLevel = ZSTD_NO_CLEVEL;
|
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 =
|
ZSTD_rust_initStaticCDictContext const* const context =
|
||||||
(const ZSTD_rust_initStaticCDictContext*)opaque;
|
(const ZSTD_rust_initStaticCDictContext*)opaque;
|
||||||
if (ZSTD_isError( ZSTD_initCDict_internal(
|
return ZSTD_initCDict_internal(
|
||||||
(ZSTD_CDict*)cdict, context->dict, context->dictSize,
|
(ZSTD_CDict*)cdict, context->dict, context->dictSize,
|
||||||
context->dictLoadMethod, context->dictContentType,
|
context->dictLoadMethod, context->dictContentType,
|
||||||
context->params) ))
|
context->params);
|
||||||
return NULL;
|
|
||||||
return cdict;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ZSTD_CDict* ZSTD_initStaticCDict(
|
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 InitStaticCDictReserveObjectFn = unsafe extern "C" fn(*mut c_void) -> *mut c_void;
|
||||||
type InitStaticCDictMoveWorkspaceFn = 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 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.
|
/// Explicit projection for the public `ZSTD_initStaticCDict` wrapper.
|
||||||
///
|
///
|
||||||
@@ -1130,7 +1130,16 @@ const _: () = {
|
|||||||
assert!(size_of::<ZSTD_rust_initStaticCDictState>() == size_of::<[usize; 12]>());
|
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.
|
/// 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]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn ZSTD_rust_initStaticCDict(
|
pub unsafe extern "C" fn ZSTD_rust_initStaticCDict(
|
||||||
state: *const ZSTD_rust_initStaticCDictState,
|
state: *const ZSTD_rust_initStaticCDictState,
|
||||||
@@ -1170,10 +1179,15 @@ pub unsafe extern "C" fn ZSTD_rust_initStaticCDict(
|
|||||||
if cdict.is_null() {
|
if cdict.is_null() {
|
||||||
return ptr::null_mut();
|
return ptr::null_mut();
|
||||||
}
|
}
|
||||||
unsafe {
|
let init_result = unsafe {
|
||||||
(state.move_workspace)(state.callback_context, cdict);
|
(state.move_workspace)(state.callback_context, cdict);
|
||||||
(state.initialize)(state.callback_context, cdict, use_row_match_finder);
|
(state.initialize)(state.callback_context, cdict, use_row_match_finder);
|
||||||
(state.init)(state.callback_context, cdict)
|
(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,
|
init_cdict: *mut c_void,
|
||||||
use_row_match_finder: c_int,
|
use_row_match_finder: c_int,
|
||||||
initialized: bool,
|
initialized: bool,
|
||||||
result: *mut c_void,
|
init_result: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn init_static_cdict_test_create_workspace(context: *mut c_void) {
|
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(
|
unsafe extern "C" fn init_static_cdict_test_init(
|
||||||
context: *mut c_void,
|
context: *mut c_void,
|
||||||
cdict: *mut c_void,
|
cdict: *mut c_void,
|
||||||
) -> *mut c_void {
|
) -> usize {
|
||||||
let probe = unsafe { &mut *context.cast::<InitStaticCDictProbe>() };
|
let probe = unsafe { &mut *context.cast::<InitStaticCDictProbe>() };
|
||||||
probe.events.push("init");
|
probe.events.push("init");
|
||||||
probe.init_cdict = cdict;
|
probe.init_cdict = cdict;
|
||||||
probe.result
|
probe.init_result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_static_cdict_test_state(
|
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]
|
#[test]
|
||||||
fn init_static_cdict_rejects_an_unaligned_workspace_before_callback() {
|
fn init_static_cdict_rejects_an_unaligned_workspace_before_callback() {
|
||||||
let mut probe = InitStaticCDictProbe {
|
let mut probe = InitStaticCDictProbe::default();
|
||||||
result: ptr::dangling_mut(),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
let mut workspace = [0usize; 2];
|
let mut workspace = [0usize; 2];
|
||||||
let unaligned_workspace = workspace.as_mut_ptr().cast::<u8>().wrapping_add(1).cast();
|
let unaligned_workspace = workspace.as_mut_ptr().cast::<u8>().wrapping_add(1).cast();
|
||||||
let c_params = init_static_cdict_test_cparams();
|
let c_params = init_static_cdict_test_cparams();
|
||||||
@@ -5335,10 +5355,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn init_static_cdict_rejects_insufficient_workspace_before_callback() {
|
fn init_static_cdict_rejects_insufficient_workspace_before_callback() {
|
||||||
let mut probe = InitStaticCDictProbe {
|
let mut probe = InitStaticCDictProbe::default();
|
||||||
result: ptr::dangling_mut(),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
let mut workspace = [0usize; 1];
|
let mut workspace = [0usize; 1];
|
||||||
let c_params = init_static_cdict_test_cparams();
|
let c_params = init_static_cdict_test_cparams();
|
||||||
let state = init_static_cdict_test_state(
|
let state = init_static_cdict_test_state(
|
||||||
@@ -5362,7 +5379,6 @@ mod tests {
|
|||||||
let cdict = ptr::dangling_mut::<c_void>();
|
let cdict = ptr::dangling_mut::<c_void>();
|
||||||
let mut probe = InitStaticCDictProbe {
|
let mut probe = InitStaticCDictProbe {
|
||||||
reserved_cdict: cdict,
|
reserved_cdict: cdict,
|
||||||
result: ptr::dangling_mut(),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let c_params = init_static_cdict_test_cparams();
|
let c_params = init_static_cdict_test_cparams();
|
||||||
@@ -5379,7 +5395,7 @@ mod tests {
|
|||||||
|
|
||||||
let result = unsafe { ZSTD_rust_initStaticCDict(&state) };
|
let result = unsafe { ZSTD_rust_initStaticCDict(&state) };
|
||||||
|
|
||||||
assert_eq!(result, probe.result);
|
assert_eq!(result, cdict);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
probe.events,
|
probe.events,
|
||||||
[
|
[
|
||||||
@@ -5428,7 +5444,7 @@ mod tests {
|
|||||||
let cdict = ptr::dangling_mut::<c_void>();
|
let cdict = ptr::dangling_mut::<c_void>();
|
||||||
let mut probe = InitStaticCDictProbe {
|
let mut probe = InitStaticCDictProbe {
|
||||||
reserved_cdict: cdict,
|
reserved_cdict: cdict,
|
||||||
result: ptr::null_mut(),
|
init_result: ERROR(ZstdErrorCode::MemoryAllocation),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let c_params = init_static_cdict_test_cparams();
|
let c_params = init_static_cdict_test_cparams();
|
||||||
@@ -5462,10 +5478,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn init_static_cdict_rejects_a_null_workspace() {
|
fn init_static_cdict_rejects_a_null_workspace() {
|
||||||
let mut probe = InitStaticCDictProbe {
|
let mut probe = InitStaticCDictProbe::default();
|
||||||
result: ptr::dangling_mut(),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
let c_params = init_static_cdict_test_cparams();
|
let c_params = init_static_cdict_test_cparams();
|
||||||
let state = init_static_cdict_test_state(
|
let state = init_static_cdict_test_state(
|
||||||
&mut probe,
|
&mut probe,
|
||||||
|
|||||||
Reference in New Issue
Block a user