diff --git a/winpr/libwinpr/clipboard/synthetic.c b/winpr/libwinpr/clipboard/synthetic.c index 0104f5b48..e680f0268 100644 --- a/winpr/libwinpr/clipboard/synthetic.c +++ b/winpr/libwinpr/clipboard/synthetic.c @@ -275,8 +275,8 @@ static void* clipboard_synthesize_cf_dibv5(wClipboard* clipboard, UINT32 formatI return NULL; } -static void* clipboard_prepend_bmp_header(const BITMAPINFOHEADER* pInfoHeader, const void* data, - size_t size, UINT32* pSize) +static void* clipboard_prepend_bmp_header(const WINPR_BITMAP_INFO_HEADER* pInfoHeader, + const void* data, size_t size, UINT32* pSize) { WINPR_ASSERT(pInfoHeader); WINPR_ASSERT(pSize); @@ -285,22 +285,34 @@ static void* clipboard_prepend_bmp_header(const BITMAPINFOHEADER* pInfoHeader, c if ((pInfoHeader->biBitCount < 1) || (pInfoHeader->biBitCount > 32)) return NULL; - const size_t DstSize = sizeof(BITMAPFILEHEADER) + size; - BYTE* pDstData = (BYTE*)malloc(DstSize); - - if (!pDstData) + const size_t DstSize = sizeof(WINPR_BITMAP_FILE_HEADER) + size; + wStream* s = Stream_New(NULL, DstSize); + if (!s) return NULL; - BITMAPFILEHEADER* pFileHeader = (BITMAPFILEHEADER*)pDstData; - pFileHeader->bfType = 0x4D42; - pFileHeader->bfSize = DstSize; - pFileHeader->bfReserved1 = 0; - pFileHeader->bfReserved2 = 0; - pFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); - unsigned char* pDst = &pDstData[sizeof(BITMAPFILEHEADER)]; - CopyMemory(pDst, data, size); + WINPR_BITMAP_FILE_HEADER fileHeader = { 0 }; + fileHeader.bfType[0] = 'B'; + fileHeader.bfType[1] = 'M'; + fileHeader.bfSize = DstSize; + fileHeader.bfOffBits = sizeof(WINPR_BITMAP_FILE_HEADER) + sizeof(WINPR_BITMAP_INFO_HEADER); + if (!writeBitmapFileHeader(s, &fileHeader)) + goto fail; + + 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; - 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)) return NULL; - const BITMAPINFOHEADER* pInfoHeader = (const BITMAPINFOHEADER*)data; - return clipboard_prepend_bmp_header(pInfoHeader, data, SrcSize, pSize); + wStream sbuffer = { 0 }; + 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) { diff --git a/winpr/libwinpr/utils/image.c b/winpr/libwinpr/utils/image.c index 93aa7a436..376062dd0 100644 --- a/winpr/libwinpr/utils/image.c +++ b/winpr/libwinpr/utils/image.c @@ -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, 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))) return FALSE; @@ -108,7 +108,7 @@ BOOL readBitmapFileHeader(wStream* s, WINPR_BITMAP_FILE_HEADER* bf) 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))) return FALSE; @@ -127,7 +127,7 @@ static BOOL writeBitmapInfoHeader(wStream* s, const WINPR_BITMAP_INFO_HEADER* bi 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)))) return FALSE; diff --git a/winpr/libwinpr/utils/image.h b/winpr/libwinpr/utils/image.h index e73156803..81233ae5b 100644 --- a/winpr/libwinpr/utils/image.h +++ b/winpr/libwinpr/utils/image.h @@ -26,5 +26,9 @@ #include 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 */