Skip to content

Commit d79dd92

Browse files
bpo-38748: Add ctypes test for stack corruption due to misaligned arguments (GH-26204)
1 parent 85752de commit d79dd92

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

Lib/test/test_ctypes/test_callbacks.py

+13
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import sys
12
import functools
23
import unittest
34
from test import support
@@ -150,6 +151,18 @@ def __del__(self):
150151
gc.collect()
151152
CFUNCTYPE(None)(lambda x=Nasty(): None)
152153

154+
@need_symbol('WINFUNCTYPE')
155+
def test_i38748_stackCorruption(self):
156+
callback_funcType = WINFUNCTYPE(c_long, c_long, c_longlong)
157+
@callback_funcType
158+
def callback(a, b):
159+
c = a + b
160+
print(f"a={a}, b={b}, c={c}")
161+
return c
162+
dll = cdll[_ctypes_test.__file__]
163+
# With no fix for i38748, the next line will raise OSError and cause the test to fail.
164+
self.assertEqual(dll._test_i38748_runCallback(callback, 5, 10), 15)
165+
153166

154167
@need_symbol('WINFUNCTYPE')
155168
class StdcallCallbacks(Callbacks):

Modules/_ctypes/_ctypes_test.c

+13
Original file line numberDiff line numberDiff line change
@@ -1034,6 +1034,19 @@ EXPORT (HRESULT) KeepObject(IUnknown *punk)
10341034

10351035
#endif
10361036

1037+
#ifdef MS_WIN32
1038+
1039+
// i38748: c stub for testing stack corruption
1040+
// When executing a Python callback with a long and a long long
1041+
1042+
typedef long(__stdcall *_test_i38748_funcType)(long, long long);
1043+
1044+
EXPORT(long) _test_i38748_runCallback(_test_i38748_funcType callback, int a, int b) {
1045+
return callback(a, b);
1046+
}
1047+
1048+
#endif
1049+
10371050
static struct PyModuleDef_Slot _ctypes_test_slots[] = {
10381051
{0, NULL}
10391052
};

0 commit comments

Comments
 (0)