Skip to content

Commit

Permalink
gh-46376: add (failing) tests for ctypes/pointer/cast/set_contents
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
s1kpp committed Sep 6, 2023
1 parent bf414b7 commit d44a269
Show file tree
Hide file tree
Showing 4 changed files with 493 additions and 4 deletions.
30 changes: 29 additions & 1 deletion Lib/test/test_ctypes/test_arrays.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import gc
import ctypes
import sys
import unittest
import warnings
from ctypes import (Structure, Array, sizeof, addressof,
import weakref
from ctypes import (Structure, Array, sizeof, addressof, POINTER, pointer,
create_string_buffer, create_unicode_buffer,
c_char, c_wchar, c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint,
c_long, c_ulonglong, c_float, c_double, c_longdouble)
Expand Down Expand Up @@ -249,6 +251,32 @@ def test_deprecation(self):
with self.assertWarns(DeprecationWarning):
CharArray = ctypes.ARRAY(c_char, 3)

def test_ptr_reuse(self):
w = weakref.WeakValueDictionary()
arr = 3 * POINTER(c_short)

vals = arr(
pointer(w.setdefault(10, c_short(10))),
pointer(w.setdefault(11, c_short(11))),
None,
)
gc.collect()

self.assertEqual(vals[0].contents.value, 10)
self.assertEqual(vals[1].contents.value, 11)

vals[2] = vals[0]

self.assertEqual(vals[2].contents.value, 10)

vals[2][0] = w.setdefault(12, c_short(12))
vals[2].contents = w.setdefault(13, c_short(13))

gc.collect()

self.assertEqual(vals[2].contents.value, 13)
self.assertEqual(vals[0].contents.value, 12)


if __name__ == '__main__':
unittest.main()
Loading

0 comments on commit d44a269

Please sign in to comment.