Update tarfile from v3.14.3 and fix bugs by youknowone · Pull Request #7223 · RustPython/RustPython
98-102:
Use a non-empty message for MemoryError.
Error::Mem currently produces MemoryError(""), which is hard to diagnose in user reports.
Suggested fix
- Error::Mem => vm.new_memory_error(""), + Error::Mem => vm.new_memory_error("Memory allocation failed"),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@crates/stdlib/src/lzma.rs` around lines 98 - 102, In catch_lzma_error,
Error::Mem returns an empty MemoryError message which is unhelpful; update the
Error::Mem arm in the catch_lzma_error function to call vm.new_memory_error with
a descriptive non-empty string (e.g., "LZMA decompression memory exhausted" or
similar) so MemoryError carries useful context when raised.
461-481:
build_filter_spec accepts malformed property lengths.
FILTER_LZMA2/FILTER_DELTA should require exactly 1 byte, and BCJ filters should accept only 0 or 4 bytes; current logic silently accepts invalid blobs.
Suggested fix
FILTER_LZMA2 => {
- if props.is_empty() {
+ if props.len() != 1 {
return Err(new_lzma_error("Invalid or unsupported options", vm));
}
let dict_size = lzma2_dict_size_from_prop(props[0]);
dict.set_item("dict_size", vm.new_pyobj(dict_size), vm)?;
}
FILTER_DELTA => {
- if props.is_empty() {
+ if props.len() != 1 {
return Err(new_lzma_error("Invalid or unsupported options", vm));
}
let dist = props[0] as u32 + 1;
dict.set_item("dist", vm.new_pyobj(dist), vm)?;
}
FILTER_X86 | FILTER_POWERPC | FILTER_IA64 | FILTER_ARM | FILTER_ARMTHUMB
| FILTER_SPARC => {
- if props.len() == 4 {
+ if props.is_empty() {
+ // default start_offset = 0
+ } else if props.len() == 4 {
let start_offset = u32::from_le_bytes([props[0], props[1], props[2], props[3]]);
dict.set_item("start_offset", vm.new_pyobj(start_offset), vm)?;
+ } else {
+ return Err(new_lzma_error("Invalid or unsupported options", vm));
}
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@crates/stdlib/src/lzma.rs` around lines 461 - 481, The build_filter_spec
branch handling FILTER_LZMA2, FILTER_DELTA, and BCJ filters (FILTER_X86,
FILTER_POWERPC, FILTER_IA64, FILTER_ARM, FILTER_ARMTHUMB, FILTER_SPARC)
currently accepts malformed props lengths; update it so FILTER_LZMA2 and
FILTER_DELTA require props.len() == 1 (otherwise return
Err(new_lzma_error("Invalid or unsupported options", vm))) and the BCJ branches
only accept props.len() == 0 or props.len() == 4 (if 4 parse start_offset, else
if 0 do nothing; any other length return the same LZMA error). Keep the existing
dict.set_item calls but gate them behind these strict length checks in
build_filter_spec.
755-766:
FORMAT_ALONE currently ignores caller-provided filters.
When filter_specs is Some, this path still builds encoder options only from preset, silently dropping user configuration.
Suggested fix
fn init_alone(
preset: u32,
filter_specs: Option<Vec<PyObjectRef>>,
vm: &VirtualMachine,
) -> PyResult<Stream> {
- if let Some(_filter_specs) = filter_specs {
- // TODO: validate single LZMA1 filter and use its options
- let options = LzmaOptions::new_preset(preset).map_err(|_| {
- new_lzma_error(format!("Invalid compression preset: {preset}"), vm)
- })?;
- Stream::new_lzma_encoder(&options).map_err(|e| catch_lzma_error(e, vm))
- } else {
- let options = LzmaOptions::new_preset(preset).map_err(|_| {
- new_lzma_error(format!("Invalid compression preset: {preset}"), vm)
- })?;
- Stream::new_lzma_encoder(&options).map_err(|e| catch_lzma_error(e, vm))
- }
+ if filter_specs.is_some() {
+ return Err(new_lzma_error(
+ "FORMAT_ALONE with custom filters is not implemented",
+ vm,
+ ));
+ }
+ let options = LzmaOptions::new_preset(preset)
+ .map_err(|_| new_lzma_error(format!("Invalid compression preset: {preset}"), vm))?;
+ Stream::new_lzma_encoder(&options).map_err(|e| catch_lzma_error(e, vm))
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@crates/stdlib/src/lzma.rs` around lines 755 - 766, The branch currently
ignores caller-provided filters: when filter_specs is Some you still call
LzmaOptions::new_preset(preset) and drop the filters; instead, compute the LZMA
encoder options once by first deriving options depending on filter_specs
(validate that filter_specs contains a single LZMA1 filter and build LzmaOptions
from its options when Some, falling back to LzmaOptions::new_preset(preset) when
None), then call Stream::new_lzma_encoder(&options).map_err(|e|
catch_lzma_error(e, vm)) a single time; update the code around filter_specs,
LzmaOptions::new_preset and Stream::new_lzma_encoder to remove the duplicated
logic and correctly honor the caller-provided filters.
207-233:
TypeError text over-promises dict-like support.
Both helpers require PyDict via downcast_ref::<PyDict>(), but the message says “dict or dict-like object”.
Suggested fix
- let dict = spec.downcast_ref::<PyDict>().ok_or_else(|| { - vm.new_type_error("Filter specifier must be a dict or dict-like object") - })?; + let dict = spec + .downcast_ref::<PyDict>() + .ok_or_else(|| vm.new_type_error("Filter specifier must be a dict"))?;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@crates/stdlib/src/lzma.rs` around lines 207 - 233, The TypeError message in
get_dict_opt_u32 and get_dict_opt_u64 incorrectly promises "dict-like" support
while downcasting only to PyDict; update the vm.new_type_error call in both
functions to state that the filter specifier "must be a dict" (or alternatively,
implement true mapping support by accepting mapping protocol), so the error text
matches the actual check performed by the downcast_ref::<PyDict>() used in
get_dict_opt_u32 and get_dict_opt_u64.