Skip to content

Commit db3ce79

Browse files
bpo-32745: Fix a regression in the handling of ctypes' c_wchar_p type (GH-8721) (#25811)
Embedded nulls would cause a ValueError to be raised. Thanks go to Eryk Sun for their analysis. Co-authored-by: Łukasz Langa <[email protected]> (cherry picked from commit 73766b0) Co-authored-by: Zackery Spytz <[email protected]>
1 parent 78e5588 commit db3ce79

File tree

3 files changed

+13
-1
lines changed

3 files changed

+13
-1
lines changed

Lib/ctypes/test/test_unicode.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ def test_buffers(self):
2626
self.assertEqual(buf[::2], 'a\xe4\xfc')
2727
self.assertEqual(buf[6:5:-1], "")
2828

29+
def test_embedded_null(self):
30+
class TestStruct(ctypes.Structure):
31+
_fields_ = [("unicode", ctypes.c_wchar_p)]
32+
t = TestStruct()
33+
# This would raise a ValueError:
34+
t.unicode = "foo\0bar\0\0"
35+
36+
2937
func = ctypes.CDLL(_ctypes_test.__file__)._testfunc_p_p
3038

3139
class StringTestCase(UnicodeTestCase):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix a regression in the handling of ctypes' :data:`ctypes.c_wchar_p` type:
2+
embedded null characters would cause a :exc:`ValueError` to be raised. Patch
3+
by Zackery Spytz.

Modules/_ctypes/cfield.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1360,6 +1360,7 @@ Z_set(void *ptr, PyObject *value, Py_ssize_t size)
13601360
{
13611361
PyObject *keep;
13621362
wchar_t *buffer;
1363+
Py_ssize_t bsize;
13631364

13641365
if (value == Py_None) {
13651366
*(wchar_t **)ptr = NULL;
@@ -1383,7 +1384,7 @@ Z_set(void *ptr, PyObject *value, Py_ssize_t size)
13831384

13841385
/* We must create a wchar_t* buffer from the unicode object,
13851386
and keep it alive */
1386-
buffer = PyUnicode_AsWideCharString(value, NULL);
1387+
buffer = PyUnicode_AsWideCharString(value, &bsize);
13871388
if (!buffer)
13881389
return NULL;
13891390
keep = PyCapsule_New(buffer, CTYPES_CFIELD_CAPSULE_NAME_PYMEM, pymem_destructor);

0 commit comments

Comments
 (0)