feat(compress): move frame progression input policy to Rust

Move buffered-input presence, offset subtraction, and block-size validation into
Rust while keeping the private MT progression query behind its C callback. The
C entry point now projects only the consumed/produced counters, input-buffer
fields, and worker dispatch inputs. Rust preserves the null-buffer behavior and
aborts on the same impossible offset or oversized-buffer invariants as the
original C assertions.

Test Plan:
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo check --manifest-path rust/Cargo.toml --tests
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 make -j1
This commit is contained in:
2026-07-21 18:51:04 +02:00
parent 4fc1a43977
commit 42e6662a6d
2 changed files with 117 additions and 28 deletions
+21 -11
View File
@@ -757,10 +757,24 @@ ZSTD_frameProgression ZSTD_rust_frameProgression(U64 consumedSrcSize,
U64 producedCSize);
typedef ZSTD_frameProgression (*ZSTD_rust_frameProgressionMTorST_f)(
void* context);
typedef struct {
const void* inBuff;
size_t inBuffPos;
size_t inToCompress;
} ZSTD_rust_frameProgressionInputState;
typedef char ZSTD_rust_frame_progression_input_state_layout[
(offsetof(ZSTD_rust_frameProgressionInputState, inBuff) == 0
&& offsetof(ZSTD_rust_frameProgressionInputState, inBuffPos)
== sizeof(void*)
&& offsetof(ZSTD_rust_frameProgressionInputState, inToCompress)
== sizeof(void*) + sizeof(size_t)
&& sizeof(ZSTD_rust_frameProgressionInputState)
== sizeof(void*) + 2 * sizeof(size_t))
? 1 : -1];
typedef struct {
U64 consumedSrcSize;
U64 producedCSize;
size_t buffered;
ZSTD_rust_frameProgressionInputState input;
void* mtContext;
ZSTD_rust_frameProgressionMTorST_f mtFrameProgression;
int nbWorkers;
@@ -770,16 +784,16 @@ typedef char ZSTD_rust_frame_progression_mt_or_st_state_layout[
&& offsetof(ZSTD_rust_frameProgressionMTorSTState, consumedSrcSize) == 0
&& offsetof(ZSTD_rust_frameProgressionMTorSTState, producedCSize)
== sizeof(U64)
&& offsetof(ZSTD_rust_frameProgressionMTorSTState, buffered)
&& offsetof(ZSTD_rust_frameProgressionMTorSTState, input)
== 2 * sizeof(U64)
&& offsetof(ZSTD_rust_frameProgressionMTorSTState, mtContext)
== 2 * sizeof(U64) + sizeof(size_t)
== 2 * sizeof(U64) + sizeof(void*) + 2 * sizeof(size_t)
&& offsetof(ZSTD_rust_frameProgressionMTorSTState, mtFrameProgression)
== 2 * sizeof(U64) + sizeof(size_t) + sizeof(void*)
== 2 * sizeof(U64) + 2 * sizeof(void*) + 2 * sizeof(size_t)
&& offsetof(ZSTD_rust_frameProgressionMTorSTState, nbWorkers)
== 2 * sizeof(U64) + sizeof(size_t) + 2 * sizeof(void*)
== 2 * sizeof(U64) + 3 * sizeof(void*) + 2 * sizeof(size_t)
&& sizeof(ZSTD_rust_frameProgressionMTorSTState)
== (sizeof(void*) == 8 ? 48 : 32))
== (sizeof(void*) == 8 ? 64 : 40))
? 1 : -1];
ZSTD_frameProgression ZSTD_rust_frameProgressionMTorST(
const ZSTD_rust_frameProgressionMTorSTState* state);
@@ -4835,18 +4849,14 @@ static ZSTD_frameProgression ZSTD_rust_frameProgression_MT(void* context)
ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx)
{
size_t const buffered = (cctx->inBuff == NULL) ? 0 :
cctx->inBuffPos - cctx->inToCompress;
ZSTD_rust_frameProgressionMTorSTState state = {
cctx->consumedSrcSize,
cctx->producedCSize,
buffered,
{ cctx->inBuff, cctx->inBuffPos, cctx->inToCompress },
NULL,
NULL,
0
};
if (buffered) assert(cctx->inBuffPos >= cctx->inToCompress);
assert(buffered <= ZSTD_BLOCKSIZE_MAX);
#ifdef ZSTD_MULTITHREAD
state.mtContext = cctx->mtctx;
state.mtFrameProgression = ZSTD_rust_frameProgression_MT;