diff --git a/Modules/clinic/overlapped.c.h b/Modules/clinic/overlapped.c.h index 16d6013ef2f2e5..7e81fc8f97104f 100644 --- a/Modules/clinic/overlapped.c.h +++ b/Modules/clinic/overlapped.c.h @@ -466,22 +466,27 @@ PyDoc_STRVAR(_overlapped_Overlapped_ReadFileInto__doc__, static PyObject * _overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self, - HANDLE handle, PyObject *bufobj); + HANDLE handle, Py_buffer *bufobj); static PyObject * _overlapped_Overlapped_ReadFileInto(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O:ReadFileInto", + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*:ReadFileInto", &handle, &bufobj)) { goto exit; } - return_value = _overlapped_Overlapped_ReadFileInto_impl(self, handle, bufobj); + return_value = _overlapped_Overlapped_ReadFileInto_impl(self, handle, &bufobj); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -527,7 +532,7 @@ PyDoc_STRVAR(_overlapped_Overlapped_WSARecvInto__doc__, static PyObject * _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, - HANDLE handle, PyObject *bufobj, + HANDLE handle, Py_buffer *bufobj, DWORD flags); static PyObject * @@ -535,16 +540,21 @@ _overlapped_Overlapped_WSARecvInto(OverlappedObject *self, PyObject *const *args { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; DWORD flags; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"Ok:WSARecvInto", + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*k:WSARecvInto", &handle, &bufobj, &flags)) { goto exit; } - return_value = _overlapped_Overlapped_WSARecvInto_impl(self, handle, bufobj, flags); + return_value = _overlapped_Overlapped_WSARecvInto_impl(self, handle, &bufobj, flags); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -559,22 +569,27 @@ PyDoc_STRVAR(_overlapped_Overlapped_WriteFile__doc__, static PyObject * _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj); + Py_buffer *bufobj); static PyObject * _overlapped_Overlapped_WriteFile(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O:WriteFile", + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*:WriteFile", &handle, &bufobj)) { goto exit; } - return_value = _overlapped_Overlapped_WriteFile_impl(self, handle, bufobj); + return_value = _overlapped_Overlapped_WriteFile_impl(self, handle, &bufobj); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -589,23 +604,28 @@ PyDoc_STRVAR(_overlapped_Overlapped_WSASend__doc__, static PyObject * _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj, DWORD flags); + Py_buffer *bufobj, DWORD flags); static PyObject * _overlapped_Overlapped_WSASend(OverlappedObject *self, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; DWORD flags; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"Ok:WSASend", + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*k:WSASend", &handle, &bufobj, &flags)) { goto exit; } - return_value = _overlapped_Overlapped_WSASend_impl(self, handle, bufobj, flags); + return_value = _overlapped_Overlapped_WSASend_impl(self, handle, &bufobj, flags); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -852,7 +872,7 @@ PyDoc_STRVAR(_overlapped_Overlapped_WSASendTo__doc__, static PyObject * _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj, DWORD flags, + Py_buffer *bufobj, DWORD flags, PyObject *AddressObj); static PyObject * @@ -860,17 +880,22 @@ _overlapped_Overlapped_WSASendTo(OverlappedObject *self, PyObject *const *args, { PyObject *return_value = NULL; HANDLE handle; - PyObject *bufobj; + Py_buffer bufobj = {NULL, NULL}; DWORD flags; PyObject *AddressObj; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"OkO:WSASendTo", + if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*kO:WSASendTo", &handle, &bufobj, &flags, &AddressObj)) { goto exit; } - return_value = _overlapped_Overlapped_WSASendTo_impl(self, handle, bufobj, flags, AddressObj); + return_value = _overlapped_Overlapped_WSASendTo_impl(self, handle, &bufobj, flags, AddressObj); exit: + /* Cleanup for bufobj */ + if (bufobj.obj) { + PyBuffer_Release(&bufobj); + } + return return_value; } @@ -943,4 +968,4 @@ _overlapped_Overlapped_WSARecvFromInto(OverlappedObject *self, PyObject *const * return return_value; } -/*[clinic end generated code: output=5c9b17890ef29d52 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d19a061ea7398d23 input=a9049054013a1b77]*/ diff --git a/Modules/overlapped.c b/Modules/overlapped.c index ab9a2f0ce26f62..74fba8346c2e1c 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -98,7 +98,7 @@ typedef struct { // A (number of bytes read, (host, port)) tuple PyObject* result; /* Buffer passed by the user */ - Py_buffer *user_buffer; + Py_buffer user_buffer; struct sockaddr_in6 address; int address_length; } read_from_into; @@ -118,6 +118,13 @@ overlapped_get_state(PyObject *module) } +static inline void +steal_buffer(Py_buffer * dst, Py_buffer * src) +{ + memcpy(dst, src, sizeof(Py_buffer)); + memset(src, 0, sizeof(Py_buffer)); +} + /* * Map Windows error codes to subclasses of OSError */ @@ -150,7 +157,6 @@ static LPFN_ACCEPTEX Py_AcceptEx = NULL; static LPFN_CONNECTEX Py_ConnectEx = NULL; static LPFN_DISCONNECTEX Py_DisconnectEx = NULL; static LPFN_TRANSMITFILE Py_TransmitFile = NULL; -static BOOL (CALLBACK *Py_CancelIoEx)(HANDLE, LPOVERLAPPED) = NULL; #define GET_WSA_POINTER(s, x) \ (SOCKET_ERROR != WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, \ @@ -164,10 +170,19 @@ initialize_function_pointers(void) GUID GuidConnectEx = WSAID_CONNECTEX; GUID GuidDisconnectEx = WSAID_DISCONNECTEX; GUID GuidTransmitFile = WSAID_TRANSMITFILE; - HINSTANCE hKernel32; SOCKET s; DWORD dwBytes; + if (Py_AcceptEx != NULL && + Py_ConnectEx != NULL && + Py_DisconnectEx != NULL && + Py_TransmitFile != NULL) + { + // All function pointers are initialized already + // by previous module import + return 0; + } + s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s == INVALID_SOCKET) { SetFromWindowsErr(WSAGetLastError()); @@ -185,12 +200,6 @@ initialize_function_pointers(void) } closesocket(s); - - /* On WinXP we will have Py_CancelIoEx == NULL */ - Py_BEGIN_ALLOW_THREADS - hKernel32 = GetModuleHandle("KERNEL32"); - *(FARPROC *)&Py_CancelIoEx = GetProcAddress(hKernel32, "CancelIoEx"); - Py_END_ALLOW_THREADS return 0; } @@ -596,7 +605,7 @@ _overlapped_FormatMessage_impl(PyObject *module, DWORD code) * Mark operation as completed - used when reading produces ERROR_BROKEN_PIPE */ -static void +static inline void mark_as_completed(OVERLAPPED *ov) { ov->Internal = 0; @@ -678,6 +687,9 @@ Overlapped_clear(OverlappedObject *self) // We've received a message, free the result tuple. Py_CLEAR(self->read_from_into.result); } + if (self->read_from_into.user_buffer.obj) { + PyBuffer_Release(&self->read_from_into.user_buffer); + } break; } case TYPE_WRITE: @@ -704,10 +716,10 @@ Overlapped_dealloc(OverlappedObject *self) if (!HasOverlappedIoCompleted(&self->overlapped) && self->type != TYPE_NOT_STARTED) { - if (Py_CancelIoEx && Py_CancelIoEx(self->handle, &self->overlapped)) + Py_BEGIN_ALLOW_THREADS + if (CancelIoEx(self->handle, &self->overlapped)) wait = TRUE; - Py_BEGIN_ALLOW_THREADS ret = GetOverlappedResult(self->handle, &self->overlapped, &bytes, wait); Py_END_ALLOW_THREADS @@ -820,10 +832,7 @@ _overlapped_Overlapped_cancel_impl(OverlappedObject *self) if (!HasOverlappedIoCompleted(&self->overlapped)) { Py_BEGIN_ALLOW_THREADS - if (Py_CancelIoEx) - ret = Py_CancelIoEx(self->handle, &self->overlapped); - else - ret = CancelIo(self->handle); + ret = CancelIoEx(self->handle, &self->overlapped); Py_END_ALLOW_THREADS } @@ -1034,7 +1043,7 @@ _overlapped_Overlapped_ReadFile_impl(OverlappedObject *self, HANDLE handle, _overlapped.Overlapped.ReadFileInto handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer / Start overlapped receive. @@ -1042,24 +1051,21 @@ Start overlapped receive. static PyObject * _overlapped_Overlapped_ReadFileInto_impl(OverlappedObject *self, - HANDLE handle, PyObject *bufobj) -/*[clinic end generated code: output=1e9e712e742e5b2a input=16f6cc268d1d0387]*/ + HANDLE handle, Py_buffer *bufobj) +/*[clinic end generated code: output=8754744506023071 input=4f037ba09939e32d]*/ { if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_READINTO; self->handle = handle; @@ -1142,7 +1148,7 @@ _overlapped_Overlapped_WSARecv_impl(OverlappedObject *self, HANDLE handle, _overlapped.Overlapped.WSARecvInto handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer flags: DWORD / @@ -1151,25 +1157,22 @@ Start overlapped receive. static PyObject * _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, - HANDLE handle, PyObject *bufobj, + HANDLE handle, Py_buffer *bufobj, DWORD flags) -/*[clinic end generated code: output=9a438abc436fe87c input=4f87c38fc381d525]*/ +/*[clinic end generated code: output=59ae7688786cf86b input=73e7fa00db633edd]*/ { if (self->type != TYPE_NONE) { PyErr_SetString(PyExc_ValueError, "operation already attempted"); return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_READINTO; self->handle = handle; @@ -1182,7 +1185,7 @@ _overlapped_Overlapped_WSARecvInto_impl(OverlappedObject *self, _overlapped.Overlapped.WriteFile handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer / Start overlapped write. @@ -1190,8 +1193,8 @@ Start overlapped write. static PyObject * _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj) -/*[clinic end generated code: output=c376230b6120d877 input=b8d9a7608d8a1e72]*/ + Py_buffer *bufobj) +/*[clinic end generated code: output=fa5d5880a1bf04b1 input=ac54424c362abfc1]*/ { DWORD written; BOOL ret; @@ -1202,16 +1205,13 @@ _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_WRITE; self->handle = handle; @@ -1237,7 +1237,7 @@ _overlapped_Overlapped_WriteFile_impl(OverlappedObject *self, HANDLE handle, _overlapped.Overlapped.WSASend handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer flags: DWORD / @@ -1246,8 +1246,8 @@ Start overlapped send. static PyObject * _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj, DWORD flags) -/*[clinic end generated code: output=316031c7467040cc input=932e7cba6d18f708]*/ + Py_buffer *bufobj, DWORD flags) +/*[clinic end generated code: output=3baaa6e1f7fe229e input=c4167420ba2f93d8]*/ { DWORD written; WSABUF wsabuf; @@ -1259,16 +1259,13 @@ _overlapped_Overlapped_WSASend_impl(OverlappedObject *self, HANDLE handle, return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) - return NULL; - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_WRITE; self->handle = handle; @@ -1668,8 +1665,8 @@ Overlapped_traverse(OverlappedObject *self, visitproc visit, void *arg) break; case TYPE_READ_FROM_INTO: Py_VISIT(self->read_from_into.result); - if (self->read_from_into.user_buffer->obj) { - Py_VISIT(&self->read_from_into.user_buffer->obj); + if (self->read_from_into.user_buffer.obj) { + Py_VISIT(&self->read_from_into.user_buffer.obj); } break; } @@ -1728,7 +1725,7 @@ _overlapped_WSAConnect_impl(PyObject *module, HANDLE ConnectSocket, _overlapped.Overlapped.WSASendTo handle: HANDLE - buf as bufobj: object + buf as bufobj: Py_buffer flags: DWORD address_as_bytes as AddressObj: object / @@ -1738,9 +1735,9 @@ Start overlapped sendto over a connectionless (UDP) socket. static PyObject * _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, - PyObject *bufobj, DWORD flags, + Py_buffer *bufobj, DWORD flags, PyObject *AddressObj) -/*[clinic end generated code: output=fe0ff55eb60d65e1 input=f709e6ecebd9bc18]*/ +/*[clinic end generated code: output=3cdedc4cfaeb70cd input=b7c1749a62e2e374]*/ { char AddressBuf[sizeof(struct sockaddr_in6)]; SOCKADDR *Address = (SOCKADDR*)AddressBuf; @@ -1762,17 +1759,13 @@ _overlapped_Overlapped_WSASendTo_impl(OverlappedObject *self, HANDLE handle, return NULL; } - if (!PyArg_Parse(bufobj, "y*", &self->user_buffer)) { - return NULL; - } - #if SIZEOF_SIZE_T > SIZEOF_LONG - if (self->user_buffer.len > (Py_ssize_t)ULONG_MAX) { - PyBuffer_Release(&self->user_buffer); + if (bufobj->len > (Py_ssize_t)ULONG_MAX) { PyErr_SetString(PyExc_ValueError, "buffer too large"); return NULL; } #endif + steal_buffer(&self->user_buffer, bufobj); self->type = TYPE_WRITE_TO; self->handle = handle; @@ -1912,7 +1905,7 @@ _overlapped_Overlapped_WSARecvFromInto_impl(OverlappedObject *self, self->type = TYPE_READ_FROM_INTO; self->handle = handle; - self->read_from_into.user_buffer = bufobj; + steal_buffer(&self->read_from_into.user_buffer, bufobj); memset(&self->read_from_into.address, 0, sizeof(self->read_from_into.address)); self->read_from_into.address_length = sizeof(self->read_from_into.address);
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: