Skip to content

Commit d44a269

Browse files
committed
gh-46376: add (failing) tests for ctypes/pointer/cast/set_contents
Previous attempt to fix gh-46376 was incomplete and overall it didn't succeed, and was reverted in 3.11. However, we have discovered some dangerous issues with ctypes, that aren't fixed or documented anywhere. This commit adds tests (@expectedfailure) so at least developers are aware of situations where memory might be corrupted, leaked or when changing a pointer value might have no effect. Hopefully, we should be able to remove @expectedfailure in the future, with new shiny ctypes implementation or at least a bugfix.
1 parent bf414b7 commit d44a269

File tree

4 files changed

+493
-4
lines changed

4 files changed

+493
-4
lines changed

Lib/test/test_ctypes/test_arrays.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import gc
12
import ctypes
23
import sys
34
import unittest
45
import warnings
5-
from ctypes import (Structure, Array, sizeof, addressof,
6+
import weakref
7+
from ctypes import (Structure, Array, sizeof, addressof, POINTER, pointer,
68
create_string_buffer, create_unicode_buffer,
79
c_char, c_wchar, c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint,
810
c_long, c_ulonglong, c_float, c_double, c_longdouble)
@@ -249,6 +251,32 @@ def test_deprecation(self):
249251
with self.assertWarns(DeprecationWarning):
250252
CharArray = ctypes.ARRAY(c_char, 3)
251253

254+
def test_ptr_reuse(self):
255+
w = weakref.WeakValueDictionary()
256+
arr = 3 * POINTER(c_short)
257+
258+
vals = arr(
259+
pointer(w.setdefault(10, c_short(10))),
260+
pointer(w.setdefault(11, c_short(11))),
261+
None,
262+
)
263+
gc.collect()
264+
265+
self.assertEqual(vals[0].contents.value, 10)
266+
self.assertEqual(vals[1].contents.value, 11)
267+
268+
vals[2] = vals[0]
269+
270+
self.assertEqual(vals[2].contents.value, 10)
271+
272+
vals[2][0] = w.setdefault(12, c_short(12))
273+
vals[2].contents = w.setdefault(13, c_short(13))
274+
275+
gc.collect()
276+
277+
self.assertEqual(vals[2].contents.value, 13)
278+
self.assertEqual(vals[0].contents.value, 12)
279+
252280

253281
if __name__ == '__main__':
254282
unittest.main()

0 commit comments

Comments
 (0)