Skip to content

ctypes's c_uint64 is effectively an alias to uint32 due to misuse of struct.calcsize() #108356

@Nodraak

Description

@Nodraak

Bug report

Checklist

  • I am confident this is a bug in CPython, not a bug in a third-party project
  • I have searched the CPython issue tracker,
    and am confident this bug has not been reported before

CPython versions tested on:

3.10

Operating systems tested on:

Linux

Output from running 'python -VV' on the command line:

Python 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0]

A clear and concise description of the bug:

Hi all,

ctypes's c_uint64 is effectively an alias to uint32 due to misuse of struct.calcsize() in ctypes's code.

Here is a minimal, reproducible example:

import ctypes, struct

bs = bytearray.fromhex("000000000006a440")  # "435264" as big endian 64 bits unsigned integer

val1 = struct.unpack_from("!Q", bs)
print("unpack_from Q (hardcoded): %s" % (val1))

val2 = struct.unpack_from("!" + ctypes.c_uint64._type_, bs)
print("unpack_from %s (ctypes.c_uint64): %s" % (ctypes.c_uint64._type_, val2))

The above will prints:

unpack_from Q (hardcoded): 435264  // unpack_from() is fine
unpack_from L (ctypes.c_uint64): (0,)  // but not ctypes.c_uint64._type_...

While I would expect:

unpack_from Q (hardcoded): 435264
unpack_from Q (ctypes.c_uint64): 435264  // Correct unpack

Symptom: ctypes.c_uint64._type_ is "L", but should be "Q"

Suggested fix: in /usr/lib/python3.10/ctypes/__init__.py:206, replace if _calcsize("l") == _calcsize("q"): by if _calcsize("=l") == _calcsize("=q"):

Rationale: without "=", the size including padding is returned: 32 bits is aligned
on 64 bits. That's wrong, we want the real size, without padding.


Version:

  • Python: Python 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0] on linux
  • uname: Linux LAPTOP-ADRIEN 5.19.0-43-generic #44~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Mon May 22 13:39:36 UTC 2 x86_64 x86_64 x86_64 GNU/Linux

Quick links:

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions