From 977d0fb07051540aac83eb0c109d24061651fb06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= Date: Thu, 26 Mar 2020 18:01:27 +0100 Subject: [PATCH] Replace misaligned type casting with proper unions. Fixes #40052 --- Include/cpython/abstract.h | 8 ++++++-- Objects/call.c | 9 ++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index 9d23c8c11be577..52ed745810d3cf 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -68,6 +68,10 @@ PyVectorcall_Function(PyObject *callable) PyTypeObject *tp; Py_ssize_t offset; vectorcallfunc *ptr; + union { + char *data; + vectorcallfunc *ptr; + } vc; assert(callable != NULL); tp = Py_TYPE(callable); @@ -77,8 +81,8 @@ PyVectorcall_Function(PyObject *callable) assert(PyCallable_Check(callable)); offset = tp->tp_vectorcall_offset; assert(offset > 0); - ptr = (vectorcallfunc *)(((char *)callable) + offset); - return *ptr; + vc.data = (char *)callable + offset; + return *vc.ptr; } /* Call the callable object 'callable' with the "vectorcall" calling diff --git a/Objects/call.c b/Objects/call.c index 08614143246091..eb619b201e0270 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -206,6 +206,11 @@ PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs) { PyThreadState *tstate = _PyThreadState_GET(); + union { + char *data; + vectorcallfunc *ptr; + } vc; + /* get vectorcallfunc as in PyVectorcall_Function, but without * the Py_TPFLAGS_HAVE_VECTORCALL check */ Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset; @@ -215,7 +220,9 @@ PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs) Py_TYPE(callable)->tp_name); return NULL; } - vectorcallfunc func = *(vectorcallfunc *)(((char *)callable) + offset); + vc.data = (char *)callable + offset; + vectorcallfunc func = *vc.ptr; + if (func == NULL) { _PyErr_Format(tstate, PyExc_TypeError, "'%.200s' object does not support vectorcall",