Skip to content

gh-161390: Reject non-ctypes objects assigned to pointer contents - #161402

Open
rajorin wants to merge 2 commits into
python:mainfrom
rajorin:gh-161390-pointer-contents
Open

rajorin wants to merge 2 commits into
python:mainfrom
rajorin:gh-161390-pointer-contents

Conversation

@rajorin

@rajorin rajorin commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Assigning a non-ctypes object to ctypes pointer contents cast that object to CDataObject when isinstance() was fooled by a spoofed __class__. That crashed the interpreter.

Pointer.contents now requires a real ctypes object and raises TypeError otherwise.

#161390

@sobolevn sobolevn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be a breaking change for some valid code?

@rajorin

rajorin commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

No. The isinstance check only ran when the value was not already a ctypes object, and a true result was still cast to CDataObject so its b_ptr could be used. There is no valid object for which that cast works.

A real ctypes value never took that branch. CDataObject_Check uses the real type, and instances of c_int (including a Python subclass) are subclasses of _ctypes._CData. Assigning one still goes through the same path as before:

class MyInt(ctypes.c_int):
    pass

ptr = ctypes.pointer(ctypes.c_int(1))
ptr.contents = MyInt(7)  # still accepted

The objects that pass isinstance and fail CDataObject_Check are objects whose __class__ is not their real type. Using those as a CDataObject crashed, which is the bug in the report. They now raise TypeError.

Assigning a different real ctypes type, such as c_char to a pointer to c_int, is unchanged. That was already accepted without the isinstance check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants