From 40f743fb379828dabce60dcec28a875e4864390c Mon Sep 17 00:00:00 2001 From: Mustafa Senoglu Date: Fri, 31 Jul 2026 22:47:43 +0300 Subject: [PATCH] fix: handle top-down DIB images in clipboard bitmap converter A BITMAPINFOHEADER with negative biHeight (top-down DIB) caused std::length_error crash in toIClipboard because 4 * w * h went negative and wrapped to a huge size_t in string::append. Fix: use abs(height) for buffer size and SetDIBitsToDevice, and add null check for CreateDIBSection. fixes: #9869 --- .../platform/MSWindowsClipboardBitmapConverter.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/lib/platform/MSWindowsClipboardBitmapConverter.cpp b/src/lib/platform/MSWindowsClipboardBitmapConverter.cpp index 9e4003519..29462bfaa 100644 --- a/src/lib/platform/MSWindowsClipboardBitmapConverter.cpp +++ b/src/lib/platform/MSWindowsClipboardBitmapConverter.cpp @@ -1,6 +1,7 @@ /* * Deskflow -- mouse and keyboard sharing utility * SPDX-FileCopyrightText: (C) 2012 - 2016 Synergy App Ltd + * SPDX-FileCopyrightText: (C) 2026 Deskflow Developers * SPDX-FileCopyrightText: (C) 2004 Chris Schoeneman * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception */ @@ -72,6 +73,7 @@ std::string MSWindowsClipboardBitmapConverter::toIClipboard(HANDLE data) const BITMAPINFOHEADER info; LONG w = bitmap->bmiHeader.biWidth; LONG h = bitmap->bmiHeader.biHeight; + const LONG absHeight = (h < 0) ? -h : h; info.biSize = sizeof(BITMAPINFOHEADER); info.biWidth = w; info.biHeight = h; @@ -85,6 +87,12 @@ std::string MSWindowsClipboardBitmapConverter::toIClipboard(HANDLE data) const info.biClrImportant = 0; HDC dc = GetDC(nullptr); HBITMAP dst = CreateDIBSection(dc, (BITMAPINFO *)&info, DIB_RGB_COLORS, &raw, nullptr, 0); + if (dst == nullptr || raw == nullptr) { + LOG_WARN("failed to allocate destination bitmap for clipboard image"); + ReleaseDC(nullptr, dc); + GlobalUnlock(data); + return std::string(); + } // find the start of the pixel data const char *srcBits = (const char *)bitmap + bitmap->bmiHeader.biSize; @@ -103,14 +111,14 @@ std::string MSWindowsClipboardBitmapConverter::toIClipboard(HANDLE data) const // copy source image to destination image HDC dstDC = CreateCompatibleDC(dc); HGDIOBJ oldBitmap = SelectObject(dstDC, dst); - SetDIBitsToDevice(dstDC, 0, 0, w, h, 0, 0, 0, h, srcBits, bitmap, DIB_RGB_COLORS); + SetDIBitsToDevice(dstDC, 0, 0, w, absHeight, 0, 0, 0, absHeight, srcBits, bitmap, DIB_RGB_COLORS); SelectObject(dstDC, oldBitmap); DeleteDC(dstDC); GdiFlush(); // extract data std::string image((const char *)&info, info.biSize); - image.append((const char *)raw, 4 * w * h); + image.append((const char *)raw, static_cast(4) * static_cast(w) * static_cast(absHeight)); // clean up GDI DeleteObject(dst);