Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Lib/ctypes/test/test_unicode.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ def test_buffers(self):
self.assertEqual(buf[::2], 'a\xe4\xfc')
self.assertEqual(buf[6:5:-1], "")

def test_embedded_null(self):
class TestStruct(ctypes.Structure):
_fields_ = [("unicode", ctypes.c_wchar_p)]
t = TestStruct()
# This would raise a ValueError:
t.unicode = "foo\0bar\0\0"


func = ctypes.CDLL(_ctypes_test.__file__)._testfunc_p_p

class StringTestCase(UnicodeTestCase):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fix a regression in the handling of ctypes' :data:`ctypes.c_wchar_p` type:
embedded null characters would cause a :exc:`ValueError` to be raised. Patch
by Zackery Spytz.
3 changes: 2 additions & 1 deletion Modules/_ctypes/cfield.c
Original file line number Diff line number Diff line change
Expand Up @@ -1354,6 +1354,7 @@ Z_set(void *ptr, PyObject *value, Py_ssize_t size)
{
PyObject *keep;
wchar_t *buffer;
Py_ssize_t bsize;

if (value == Py_None) {
*(wchar_t **)ptr = NULL;
Expand All @@ -1377,7 +1378,7 @@ Z_set(void *ptr, PyObject *value, Py_ssize_t size)

/* We must create a wchar_t* buffer from the unicode object,
and keep it alive */
buffer = PyUnicode_AsWideCharString(value, NULL);
buffer = PyUnicode_AsWideCharString(value, &bsize);
if (!buffer)
return NULL;
keep = PyCapsule_New(buffer, CTYPES_CFIELD_CAPSULE_NAME_PYMEM, pymem_destructor);
Expand Down