Merge pull request #10559 from akallabeth/clip-endian

[winpr,clipboard] use endian safe bitmap read/write
This commit is contained in:
akallabeth 2024-09-04 22:24:55 +02:00 committed by GitHub
commit c670eda6eb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 42 additions and 20 deletions

View File

@ -275,8 +275,8 @@ static void* clipboard_synthesize_cf_dibv5(wClipboard* clipboard, UINT32 formatI
return NULL; return NULL;
} }
static void* clipboard_prepend_bmp_header(const BITMAPINFOHEADER* pInfoHeader, const void* data, static void* clipboard_prepend_bmp_header(const WINPR_BITMAP_INFO_HEADER* pInfoHeader,
size_t size, UINT32* pSize) const void* data, size_t size, UINT32* pSize)
{ {
WINPR_ASSERT(pInfoHeader); WINPR_ASSERT(pInfoHeader);
WINPR_ASSERT(pSize); WINPR_ASSERT(pSize);
@ -285,22 +285,34 @@ static void* clipboard_prepend_bmp_header(const BITMAPINFOHEADER* pInfoHeader, c
if ((pInfoHeader->biBitCount < 1) || (pInfoHeader->biBitCount > 32)) if ((pInfoHeader->biBitCount < 1) || (pInfoHeader->biBitCount > 32))
return NULL; return NULL;
const size_t DstSize = sizeof(BITMAPFILEHEADER) + size; const size_t DstSize = sizeof(WINPR_BITMAP_FILE_HEADER) + size;
BYTE* pDstData = (BYTE*)malloc(DstSize); wStream* s = Stream_New(NULL, DstSize);
if (!s)
if (!pDstData)
return NULL; return NULL;
BITMAPFILEHEADER* pFileHeader = (BITMAPFILEHEADER*)pDstData; WINPR_BITMAP_FILE_HEADER fileHeader = { 0 };
pFileHeader->bfType = 0x4D42; fileHeader.bfType[0] = 'B';
pFileHeader->bfSize = DstSize; fileHeader.bfType[1] = 'M';
pFileHeader->bfReserved1 = 0; fileHeader.bfSize = DstSize;
pFileHeader->bfReserved2 = 0; fileHeader.bfOffBits = sizeof(WINPR_BITMAP_FILE_HEADER) + sizeof(WINPR_BITMAP_INFO_HEADER);
pFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); if (!writeBitmapFileHeader(s, &fileHeader))
unsigned char* pDst = &pDstData[sizeof(BITMAPFILEHEADER)]; goto fail;
CopyMemory(pDst, data, size);
if (!Stream_EnsureRemainingCapacity(s, size))
goto fail;
Stream_Write(s, data, size);
const size_t len = Stream_GetPosition(s);
if (len != DstSize)
goto fail;
*pSize = DstSize; *pSize = DstSize;
return pDstData;
BYTE* dst = Stream_Buffer(s);
Stream_Free(s, FALSE);
return dst;
fail:
Stream_Free(s, TRUE);
return NULL;
} }
/** /**
@ -319,8 +331,14 @@ static void* clipboard_synthesize_image_bmp(wClipboard* clipboard, UINT32 format
if (SrcSize < sizeof(BITMAPINFOHEADER)) if (SrcSize < sizeof(BITMAPINFOHEADER))
return NULL; return NULL;
const BITMAPINFOHEADER* pInfoHeader = (const BITMAPINFOHEADER*)data; wStream sbuffer = { 0 };
return clipboard_prepend_bmp_header(pInfoHeader, data, SrcSize, pSize); size_t offset = 0;
WINPR_BITMAP_INFO_HEADER header = { 0 };
wStream* s = Stream_StaticConstInit(&sbuffer, data, SrcSize);
if (!readBitmapInfoHeader(s, &header, &offset))
return NULL;
return clipboard_prepend_bmp_header(&header, data, SrcSize, pSize);
} }
else if (formatId == CF_DIBV5) else if (formatId == CF_DIBV5)
{ {

View File

@ -60,7 +60,7 @@ static SSIZE_T winpr_convert_from_png(const BYTE* comp_data, size_t comp_data_by
static SSIZE_T winpr_convert_from_webp(const BYTE* comp_data, size_t comp_data_bytes, UINT32* width, static SSIZE_T winpr_convert_from_webp(const BYTE* comp_data, size_t comp_data_bytes, UINT32* width,
UINT32* height, UINT32* bpp, BYTE** ppdecomp_data); UINT32* height, UINT32* bpp, BYTE** ppdecomp_data);
static BOOL writeBitmapFileHeader(wStream* s, const WINPR_BITMAP_FILE_HEADER* bf) BOOL writeBitmapFileHeader(wStream* s, const WINPR_BITMAP_FILE_HEADER* bf)
{ {
if (!Stream_EnsureRemainingCapacity(s, sizeof(WINPR_BITMAP_FILE_HEADER))) if (!Stream_EnsureRemainingCapacity(s, sizeof(WINPR_BITMAP_FILE_HEADER)))
return FALSE; return FALSE;
@ -108,7 +108,7 @@ BOOL readBitmapFileHeader(wStream* s, WINPR_BITMAP_FILE_HEADER* bf)
bf->bfSize - sizeof(WINPR_BITMAP_FILE_HEADER)); bf->bfSize - sizeof(WINPR_BITMAP_FILE_HEADER));
} }
static BOOL writeBitmapInfoHeader(wStream* s, const WINPR_BITMAP_INFO_HEADER* bi) BOOL writeBitmapInfoHeader(wStream* s, const WINPR_BITMAP_INFO_HEADER* bi)
{ {
if (!Stream_EnsureRemainingCapacity(s, sizeof(WINPR_BITMAP_INFO_HEADER))) if (!Stream_EnsureRemainingCapacity(s, sizeof(WINPR_BITMAP_INFO_HEADER)))
return FALSE; return FALSE;
@ -127,7 +127,7 @@ static BOOL writeBitmapInfoHeader(wStream* s, const WINPR_BITMAP_INFO_HEADER* bi
return TRUE; return TRUE;
} }
static BOOL readBitmapInfoHeader(wStream* s, WINPR_BITMAP_INFO_HEADER* bi, size_t* poffset) BOOL readBitmapInfoHeader(wStream* s, WINPR_BITMAP_INFO_HEADER* bi, size_t* poffset)
{ {
if (!s || !bi || (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(WINPR_BITMAP_INFO_HEADER)))) if (!s || !bi || (!Stream_CheckAndLogRequiredLength(TAG, s, sizeof(WINPR_BITMAP_INFO_HEADER))))
return FALSE; return FALSE;

View File

@ -26,5 +26,9 @@
#include <winpr/image.h> #include <winpr/image.h>
BOOL readBitmapFileHeader(wStream* s, WINPR_BITMAP_FILE_HEADER* bf); BOOL readBitmapFileHeader(wStream* s, WINPR_BITMAP_FILE_HEADER* bf);
BOOL writeBitmapFileHeader(wStream* s, const WINPR_BITMAP_FILE_HEADER* bf);
BOOL readBitmapInfoHeader(wStream* s, WINPR_BITMAP_INFO_HEADER* bi, size_t* poffset);
BOOL writeBitmapInfoHeader(wStream* s, const WINPR_BITMAP_INFO_HEADER* bi);
#endif /* LIBWINPR_UTILS_IMAGE_H */ #endif /* LIBWINPR_UTILS_IMAGE_H */