From dde3ecd162c60e0b47aa132727014ad7d54c37a2 Mon Sep 17 00:00:00 2001 From: ddidderr Date: Sun, 12 Jul 2026 18:07:12 +0200 Subject: [PATCH] fix(dict): honor legacy dictionary capacity before copying segments Delay the legacy dictionary segment copy until the effective content size is known, preventing writes beyond the caller-provided dictionary capacity. Test Plan: - RUSTC_WRAPPER= CARGO_BUILD_RUSTC_WRAPPER= cargo test --manifest-path rust/cli/Cargo.toml - make -C tests check V=1 --- rust/src/dict_builder_zdict.rs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/rust/src/dict_builder_zdict.rs b/rust/src/dict_builder_zdict.rs index b1d52210d..56f3cd67a 100644 --- a/rust/src/dict_builder_zdict.rs +++ b/rust/src/dict_builder_zdict.rs @@ -1140,6 +1140,20 @@ unsafe fn train_from_buffer_unsafe_legacy( if content_size < ZDICT_CONTENTSIZE_MIN { return dictionary_error(ZstdErrorCode::DictionaryCreationFailed); } + let max = dict_list[0].pos as usize; + let mut current_size = 0usize; + let mut count = 1usize; + while count < max { + current_size += dict_list[count].length as usize; + if current_size > max_dict_size { + current_size -= dict_list[count].length as usize; + break; + } + count += 1; + } + dict_list[0].pos = count as u32; + content_size = current_size; + let output = unsafe { std::slice::from_raw_parts_mut(dict_buffer.cast::(), max_dict_size) }; let mut write_at = max_dict_size; for item in dict_list.iter().take(dict_list[0].pos as usize).skip(1) { @@ -1157,19 +1171,6 @@ unsafe fn train_from_buffer_unsafe_legacy( .copy_from_slice(&samples_buffer[item.pos as usize..item.pos as usize + length]); } - let max = dict_list[0].pos as usize; - let mut current_size = 0usize; - let mut count = 1usize; - while count < max { - current_size += dict_list[count].length as usize; - if current_size > max_dict_size { - current_size -= dict_list[count].length as usize; - break; - } - count += 1; - } - dict_list[0].pos = count as u32; - content_size = current_size; add_entropy_tables_advanced( dict_buffer, content_size,