Skip to content

Commit e6957dc

Browse files
committed
fix(capi): delegate PyBuffer_SizeFromFormat to struct.calcsize
Assisted-by: Antigravity:Gemini-3.7-Flash
1 parent 6e2c4b8 commit e6957dc

1 file changed

Lines changed: 9 additions & 28 deletions

File tree

‎crates/capi/src/buffer.rs‎

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -331,36 +331,14 @@ pub unsafe extern "C" fn PyBuffer_FillInfo(
331331

332332
#[unsafe(no_mangle)]
333333
pub unsafe extern "C" fn PyBuffer_SizeFromFormat(format: *const c_char) -> isize {
334-
if format.is_null() {
335-
return -1;
336-
}
337334
with_vm(|vm| {
338335
let fmt = unsafe { format.try_as_str(vm) }?;
339-
// Basic format string size parsing following struct module rules
340-
let mut size: isize = 0;
341-
let mut count: isize = 0;
342-
for ch in fmt.chars() {
343-
match ch {
344-
'@' | '=' | '<' | '>' | '!' | ' ' => continue,
345-
'0'..='9' => {
346-
let digit = (ch as u8 - b'0') as isize;
347-
count = count * 10 + digit;
348-
}
349-
_ => {
350-
let item_count = if count == 0 { 1 } else { count };
351-
count = 0;
352-
let elem_size = match ch {
353-
'x' | 'c' | 'b' | 'B' | '?' => 1,
354-
'h' | 'H' | 'e' => 2,
355-
'i' | 'I' | 'l' | 'L' | 'f' => 4,
356-
'q' | 'Q' | 'd' => 8,
357-
'P' => core::mem::size_of::<*mut c_void>() as isize,
358-
_ => return Err(vm.new_value_error(format!("unknown format code: {ch}"))),
359-
};
360-
size += item_count * elem_size;
361-
}
362-
}
363-
}
336+
let struct_mod = vm.import("struct", 0)?;
337+
let calcsize = struct_mod.get_attr("calcsize", vm)?;
338+
let res = calcsize.call((fmt,), vm)?;
339+
let size: isize = res.try_index(vm)?.as_bigint().try_into().map_err(|_| {
340+
vm.new_overflow_error("struct.calcsize result too large for isize".to_owned())
341+
})?;
364342
Ok(size)
365343
})
366344
}
@@ -423,6 +401,9 @@ mod tests {
423401

424402
let size_double = unsafe { PyBuffer_SizeFromFormat(c"d".as_ptr()) };
425403
assert_eq!(size_double, 8);
404+
405+
let null_size = unsafe { PyBuffer_SizeFromFormat(core::ptr::null()) };
406+
assert_eq!(null_size, -1);
426407
});
427408
}
428409

0 commit comments

Comments
 (0)