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
This commit is contained in:
2026-07-12 18:07:12 +02:00
parent cd7ae43da7
commit dde3ecd162
+14 -13
View File
@@ -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::<u8>(), 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,