gh-132470: Prevent crash in ctypes.CField when byte_size is incorrect#132475
gh-132470: Prevent crash in ctypes.CField when byte_size is incorrect#132475sobolevn merged 6 commits intopython:mainfrom
byte_size is incorrect#132475Conversation
…e size (pythongh-132470) When creating a ctypes.CField with an incorrect byte_size (e.g., using byte_size=2 for ctypes.c_byte), the code would previously abort due to the failed assertion byte_size == info->size. This commit replaces the assertion with a proper error handling mechanism that raises a ValueError when byte_size does not match the expected type size. This prevents the crash and provides a more informative error message to the us
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
I not found place where to write regression test for it. |
sobolevn
left a comment
There was a problem hiding this comment.
Please, add a test case somewhere to test_ctypes and a NEWS entry.
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
|
@sobolevn @ZeroIntensity |
Lib/test/leakers/test_ctypes.py
Outdated
| gc.collect() | ||
|
|
||
|
|
||
| def test_invalid_byte_size_raises(self): |
There was a problem hiding this comment.
I'm not sure Lib/test/leakers is the right place for this test. This should probably go with the ctypes-proper tests in Lib/test/test_ctypes. Lib/test/test_ctypes/test_struct_fields.py might be a good fit.
There was a problem hiding this comment.
yep, moved, thanks.
byte_size is incorrect
| @@ -0,0 +1,4 @@ | |||
| Creating a `ctypes.CField` with a `byte_size` that does not match the actual | |||
There was a problem hiding this comment.
No need for a NEWS entry. The structure is currently opaque and only exposed as a read-only structure. Users shouldn't be able to call the constructor directly.
| @@ -0,0 +1,4 @@ | |||
| Creating a `ctypes.CField` with a `byte_size` that does not match the actual | |||
There was a problem hiding this comment.
Remove this NEWs entry as well.
Adds a test to ensure that creating a ctypes.CField with a byte_size that doesn't match the underlying C type size (e.g., 2 bytes for c_byte) correctly raises a ValueError. This test verifies the fix for pythongh-132470 and prevents future regressions where such mismatches could cause an abort.
| with self.assertRaises(ValueError) as cm: | ||
| CField( | ||
| name="a", | ||
| type=c_byte, | ||
| byte_size=2, # Wrong size: c_byte is only 1 byte | ||
| byte_offset=2, | ||
| index=1, | ||
| _internal_use=True | ||
| ) | ||
|
|
||
| self.assertIn("does not match type size", str(cm.exception)) |
There was a problem hiding this comment.
I suggest using assertRaisesRegex instead here.
| CField( | ||
| name="a", | ||
| type=c_byte, | ||
| byte_size=2, # Wrong size: c_byte is only 1 byte |
There was a problem hiding this comment.
| byte_size=2, # Wrong size: c_byte is only 1 byte | |
| byte_size=2, # Wrong size: c_byte is only 1 byte |
There was a problem hiding this comment.
Hmm, did the commit get lost somewhere? It looks like this is still one space instead of two.
|
@dura0ok it's best to avoid force pushing once you've received feedback, since that makes it harder for reviewers to see what changed. All commits are squashed on merge anyway |
Misc/NEWS.d/next/C_API/2025-04-13-20-52-39.gh-issue-132470.UqBQjN.rst
Outdated
Show resolved
Hide resolved
Co-authored-by: sobolevn <mail@sobolevn.me>
ZeroIntensity
left a comment
There was a problem hiding this comment.
LGTM as well, but the formatting change that Bénédikt suggested seemingly got un-fixed.
That, and I didn't realize we had skip news on this. I'm going to remove that because I'd argue this is public enough for a news entry, but someone is free to bicker with me on that.
| CField( | ||
| name="a", | ||
| type=c_byte, | ||
| byte_size=2, # Wrong size: c_byte is only 1 byte |
There was a problem hiding this comment.
Hmm, did the commit get lost somewhere? It looks like this is still one space instead of two.
|
@ZeroIntensity problem with space fixed. |
sobolevn
left a comment
There was a problem hiding this comment.
Thanks! I will backport this to 3.13 as well.
|
Sorry, @dura0ok and @sobolevn, I could not cleanly backport this to |
|
@dura0ok can you please work on a manual backport? |
|
@sobolevn yes, sure. In which pr? |
|
Thanks for getting this in everyone! Python 3.13 does not allow creating @ZeroIntensity: A friendly bicker, just so you know my opinion: This should not have a NEWS entry, since the CField constructor is not public. If you call it (with |
|
FWIW, I do sometimes see changelog entries for changes to the private API if people were relying on it. I don't know if that applied here. |
When creating a ctypes.CField with an incorrect byte_size (e.g., using byte_size=2 for ctypes.c_byte), the code would previously abort due to the failed assertion byte_size == info->size.
This commit replaces the assertion with a proper error handling mechanism that raises a ValueError when byte_size does not match the expected type size. This prevents the crash and provides a more informative error message to the us
ctypes.CFieldwith wrongbyte_sizeaborts #132470