Struct fields with size > 65535 bytes throw TypeError #126937
Labels
3.14
new features, bugs and security fixes
stdlib
Python modules in the Lib dir
topic-ctypes
type-bug
An unexpected behavior, bug, or error
Bug report
Bug description:
PyCField_new_impl()
processes these fields with size > 65535 bytes as bitfields, due to relying on theNUM_BITS()
function. It throws aTypeError
because such fields aren't a valid bitfield type.Minimal Example
Root Cause
When ctypes/_layout.py creates fields for a type, if the field type is a bitfield, it passes the size in bits to
CField()
'sbit_size
parameter. Otherwise, it passesNone
. That parameter gets passed asPyCField_new_impl()
'sbit_size_obj
parameter. However, that parameter goes unused. Instead, when checking if the field is a bitfield, we useNUM_BITS()
, passing insize
(in bytes), which effectively does an int division by 65536, and check if the result >0
. So, for fields with size > 65535 bytes, they will be treated as bitfields, and rejected as they're not one of the bitfield-compatible types.Tested versions
No Bug
Python 3.12.1 (main, Jul 26 2024, 14:03:47) [Clang 19.0.0git (https:/github.com/llvm/llvm-project 0a8cd1ed1f4f35905df318015b on emscripten
Python 3.11.5 (tags/v3.11.5:cce6ba9, Aug 24 2023, 14:38:34) [MSC v.1936 64 bit (AMD64)] on win32
Bug
Python 3.14.0a1 (tags/v3.14.0a1:8cdaca8, Oct 15 2024, 20:08:21) [MSC v.1941 64 bit (AMD64)] on win32
Commentary
Found this bug while using the latest 3.14 python build and attempting to import the Scapy library. A
TypeError
is thrown on import. They use a struct with a large field to hold tables they expect to receive from a Windows API call.If it's considered expected behavior to limit the size of a field to 64KB, then that would contradict the size test earlier in
PyCField_new_impl()
, which throws aValueError
only if the size is bigger than whatPy_ssize_t
can hold.As long as it's possible to define one of these types without having to actually instantiate, we should add a test that defines a max-size field.
I don't understand the naming of
NUM_BITS()
. See below for reference. In context, it's tightly integrated in bitfield get/set behavior, in a way that's too convoluted for me to follow. And it's used sporadically throughout Modules/_ctypes/cfield.c, so I'd hesitate to touch other usages. But this bug represents one misusage, so are there others?CPython versions tested on:
3.14, CPython main branch
Operating systems tested on:
Windows
Linked PRs
The text was updated successfully, but these errors were encountered: