feat(compress): move external sequence validation to Rust

Port the external-sequence window, offset, and minimum-match checks through a scalar C ABI leaf while retaining the C caller's control flow and diagnostics.

Test Plan: cargo test --manifest-path rust/Cargo.toml --no-default-features --features compression; cargo clippy --manifest-path rust/Cargo.toml; cargo clippy --manifest-path rust/Cargo.toml --benches; cargo clippy --manifest-path rust/Cargo.toml --tests; make -B -C lib -j2 lib; make -B -C tests -j2 test-zstream (84 deterministic, 7063 and 8665 fuzzer cases).
This commit is contained in:
2026-07-18 05:19:19 +02:00
parent 4c6a00722f
commit 1a05952013
2 changed files with 76 additions and 12 deletions
+6 -12
View File
@@ -265,6 +265,9 @@ size_t ZSTD_rust_blockSizeExplicitDelimiter(const ZSTD_Sequence* inSeqs,
size_t ZSTD_rust_determineBlockSize(int mode, size_t blockSize, size_t remaining,
const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
U32 seqIdx);
size_t ZSTD_rust_validateSequence(U32 offBase, U32 matchLength, U32 minMatch,
size_t posInSrc, U32 windowLog, size_t dictSize,
int useSequenceProducer);
typedef char ZSTD_rust_stats_seqdef_layout[(sizeof(SeqDef) == 8) ? 1 : -1];
typedef char ZSTD_rust_stats_seqstore_long_length_pos[
@@ -5339,18 +5342,9 @@ static size_t
ZSTD_validateSequence(U32 offBase, U32 matchLength, U32 minMatch,
size_t posInSrc, U32 windowLog, size_t dictSize, int useSequenceProducer)
{
U32 const windowSize = 1u << windowLog;
/* posInSrc represents the amount of data the decoder would decode up to this point.
* As long as the amount of data decoded is less than or equal to window size, offsets may be
* larger than the total length of output decoded in order to reference the dict, even larger than
* window size. After output surpasses windowSize, we're limited to windowSize offsets again.
*/
size_t const offsetBound = posInSrc > windowSize ? (size_t)windowSize : posInSrc + (size_t)dictSize;
size_t const matchLenLowerBound = (minMatch == 3 || useSequenceProducer) ? 3 : 4;
RETURN_ERROR_IF(offBase > OFFSET_TO_OFFBASE(offsetBound), externalSequences_invalid, "Offset too large!");
/* Validate maxNbSeq is large enough for the given matchLength and minMatch */
RETURN_ERROR_IF(matchLength < matchLenLowerBound, externalSequences_invalid, "Matchlength too small for the minMatch");
return 0;
return ZSTD_rust_validateSequence(offBase, matchLength, minMatch,
posInSrc, windowLog, dictSize,
useSequenceProducer);
}
/* Returns an offset code, given a sequence's raw offset, the ongoing repcode array, and whether litLength == 0 */