Skip to content

Commit cd91426

Browse files
Add test for stack corruption in issue 38748.
1 parent 1cbaa50 commit cd91426

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

Lib/ctypes/test/test_callbacks.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,18 @@ def __del__(self):
146146
gc.collect()
147147
CFUNCTYPE(None)(lambda x=Nasty(): None)
148148

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

150162
@need_symbol('WINFUNCTYPE')
151163
class StdcallCallbacks(Callbacks):
@@ -319,6 +331,5 @@ def func():
319331
"of ctypes callback function")
320332
self.assertIs(cm.unraisable.object, func)
321333

322-
323334
if __name__ == '__main__':
324335
unittest.main()

Modules/_ctypes/_ctypes_test.c

Lines changed: 13 additions & 0 deletions
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)