From b13e74a8abcd8f9b8b494ad7e5eebafe4258b1fe Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Fri, 2 Oct 2026 12:22:30 +1000 Subject: [PATCH 1/2] Improve freeing objects on errors in PyImaging_GrabScreenWin32() --- src/display.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/display.c b/src/display.c index 195142d465e..158a68dea0a 100644 --- a/src/display.c +++ b/src/display.c @@ -311,12 +311,12 @@ PyObject * PyImaging_GrabScreenWin32(PyObject *self, PyObject *args) { int x = 0, y = 0, width = -1, height; int includeLayeredWindows = 0, screens = 0; - HBITMAP bitmap; + HBITMAP bitmap = NULL; BITMAPCOREHEADER core; HDC screen, screen_copy; HWND wnd; DWORD rop; - PyObject *buffer; + PyObject *buffer = NULL; HANDLE dpiAwareness = NULL; HMODULE user32; Func_GetWindowDpiAwarenessContext GetWindowDpiAwarenessContext_function; @@ -382,15 +382,18 @@ PyImaging_GrabScreenWin32(PyObject *self, PyObject *args) { FreeLibrary(user32); if (width == -1) { + PyErr_SetString(PyExc_OSError, "screen grab failed"); goto error; } bitmap = CreateCompatibleBitmap(screen, width, height); if (!bitmap) { + PyErr_SetString(PyExc_OSError, "screen grab failed"); goto error; } if (!SelectObject(screen_copy, bitmap)) { + PyErr_SetString(PyExc_OSError, "screen grab failed"); goto error; } @@ -401,6 +404,7 @@ PyImaging_GrabScreenWin32(PyObject *self, PyObject *args) { rop |= CAPTUREBLT; } if (!BitBlt(screen_copy, 0, 0, width, height, screen, x, y, rop)) { + PyErr_SetString(PyExc_OSError, "screen grab failed"); goto error; } @@ -408,7 +412,7 @@ PyImaging_GrabScreenWin32(PyObject *self, PyObject *args) { buffer = PyBytes_FromStringAndSize(NULL, height * ((width * 3 + 3) & -4)); if (!buffer) { - return NULL; + goto error; } core.bcSize = sizeof(core); @@ -425,6 +429,7 @@ PyImaging_GrabScreenWin32(PyObject *self, PyObject *args) { (BITMAPINFO *)&core, DIB_RGB_COLORS )) { + PyErr_SetString(PyExc_OSError, "screen grab failed"); goto error; } @@ -439,9 +444,11 @@ PyImaging_GrabScreenWin32(PyObject *self, PyObject *args) { return Py_BuildValue("(ii)(ii)N", x, y, width, height, buffer); error: - PyErr_SetString(PyExc_OSError, "screen grab failed"); - + if (bitmap != NULL) { + DeleteObject(bitmap); + } DeleteDC(screen_copy); + Py_XDECREF(buffer); if (screens == -1) { ReleaseDC(wnd, screen); } else { From 2e4e7d8db22aafe2f81d1469b1f06ea4e5f3a2d1 Mon Sep 17 00:00:00 2001 From: Andrew Murray <3112309+radarhere@users.noreply.github.com> Date: Fri, 2 Oct 2026 17:53:34 +1000 Subject: [PATCH 2/2] Rearranged code Co-authored-by: Aarni Koskela --- src/display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/display.c b/src/display.c index 158a68dea0a..56e76b68b47 100644 --- a/src/display.c +++ b/src/display.c @@ -444,11 +444,11 @@ PyImaging_GrabScreenWin32(PyObject *self, PyObject *args) { return Py_BuildValue("(ii)(ii)N", x, y, width, height, buffer); error: + Py_XDECREF(buffer); if (bitmap != NULL) { DeleteObject(bitmap); } DeleteDC(screen_copy); - Py_XDECREF(buffer); if (screens == -1) { ReleaseDC(wnd, screen); } else {