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
This commit is contained in:
parent
3c37f2ff11
commit
40f743fb37
1 changed files with 10 additions and 2 deletions
|
|
@ -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<size_t>(4) * static_cast<size_t>(w) * static_cast<size_t>(absHeight));
|
||||
|
||||
// clean up GDI
|
||||
DeleteObject(dst);
|
||||
|
|
|
|||
Loading…
Reference in a new issue