mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
Merge pull request #12151 from akallabeth/glyph-fix
Glyph fix length checks
This commit is contained in:
@@ -288,6 +288,7 @@ typedef struct gdi_palette gdiPalette;
|
||||
return (FreeRDPGetBitsPerPixel(format) + 7) / 8;
|
||||
}
|
||||
|
||||
#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
|
||||
/***
|
||||
*
|
||||
* @param width width to copy in pixels
|
||||
@@ -297,9 +298,27 @@ typedef struct gdi_palette gdiPalette;
|
||||
* @return A buffer allocated with winpr_aligned_malloc(width * height, 16)
|
||||
* if successful, NULL otherwise.
|
||||
*/
|
||||
|
||||
WINPR_DEPRECATED_VAR("[since 3.21.0] use freerdp_glyph_convert_ex instead",
|
||||
WINPR_ATTR_MALLOC(winpr_aligned_free, 1)
|
||||
FREERDP_API BYTE* freerdp_glyph_convert(
|
||||
UINT32 width, UINT32 height, const BYTE* WINPR_RESTRICT data));
|
||||
#endif
|
||||
|
||||
/***
|
||||
*
|
||||
* @param width width to copy in pixels
|
||||
* @param height height to copy in pixels
|
||||
* @param data source buffer, must be (nWidth + 7) / 8 bytes long
|
||||
* @param len the length of \ref data in bytes
|
||||
*
|
||||
* @return A buffer allocated with winpr_aligned_malloc(width * height, 16)
|
||||
* if successful, NULL otherwise.
|
||||
* @since version 3.21.0
|
||||
*/
|
||||
WINPR_ATTR_MALLOC(winpr_aligned_free, 1)
|
||||
FREERDP_API BYTE* freerdp_glyph_convert(UINT32 width, UINT32 height,
|
||||
const BYTE* WINPR_RESTRICT data);
|
||||
FREERDP_API BYTE* freerdp_glyph_convert_ex(UINT32 width, UINT32 height,
|
||||
const BYTE* WINPR_RESTRICT data, size_t len);
|
||||
|
||||
/***
|
||||
*
|
||||
|
||||
@@ -1139,8 +1139,54 @@ INT32 clear_decompress(CLEAR_CONTEXT* WINPR_RESTRICT clear, const BYTE* WINPR_RE
|
||||
|
||||
if (glyphData)
|
||||
{
|
||||
const uint32_t w = MIN(nWidth, nDstWidth);
|
||||
const uint32_t h = MIN(nHeight, nDstHeight);
|
||||
uint32_t w = MIN(nWidth, nDstWidth);
|
||||
if (nXDst > nDstWidth)
|
||||
{
|
||||
WLog_WARN(TAG, "glyphData copy area x exceeds destination: x=%" PRIu32 " > %" PRIu32,
|
||||
nXDst, nDstWidth);
|
||||
w = 0;
|
||||
}
|
||||
else if (nXDst + w > nDstWidth)
|
||||
{
|
||||
WLog_WARN(TAG,
|
||||
"glyphData copy area x + width exceeds destination: x=%" PRIu32 " + %" PRIu32
|
||||
" > %" PRIu32,
|
||||
nXDst, w, nDstWidth);
|
||||
w = nDstWidth - nXDst;
|
||||
}
|
||||
|
||||
if (w != nWidth)
|
||||
{
|
||||
WLog_WARN(TAG,
|
||||
"glyphData copy area width truncated: requested=%" PRIu32
|
||||
", truncated to %" PRIu32,
|
||||
nWidth, w);
|
||||
}
|
||||
|
||||
uint32_t h = MIN(nHeight, nDstHeight);
|
||||
if (nYDst > nDstHeight)
|
||||
{
|
||||
WLog_WARN(TAG, "glyphData copy area y exceeds destination: y=%" PRIu32 " > %" PRIu32,
|
||||
nYDst, nDstHeight);
|
||||
h = 0;
|
||||
}
|
||||
else if (nYDst + h > nDstHeight)
|
||||
{
|
||||
WLog_WARN(TAG,
|
||||
"glyphData copy area y + height exceeds destination: x=%" PRIu32 " + %" PRIu32
|
||||
" > %" PRIu32,
|
||||
nYDst, h, nDstHeight);
|
||||
h = nDstHeight - nYDst;
|
||||
}
|
||||
|
||||
if (h != nHeight)
|
||||
{
|
||||
WLog_WARN(TAG,
|
||||
"glyphData copy area height truncated: requested=%" PRIu32
|
||||
", truncated to %" PRIu32,
|
||||
nHeight, h);
|
||||
}
|
||||
|
||||
if (!freerdp_image_copy_no_overlap(glyphData, clear->format, 0, 0, 0, w, h, pDstData,
|
||||
DstFormat, nDstStep, nXDst, nYDst, palette,
|
||||
FREERDP_KEEP_DST_ALPHA))
|
||||
|
||||
@@ -242,14 +242,33 @@ fail:
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
|
||||
BYTE* freerdp_glyph_convert(UINT32 width, UINT32 height, const BYTE* WINPR_RESTRICT data)
|
||||
{
|
||||
const size_t scanline = (width + 7ull) / 8ull;
|
||||
const size_t required = scanline * height;
|
||||
return freerdp_glyph_convert_ex(width, height, data, required);
|
||||
}
|
||||
#endif
|
||||
|
||||
BYTE* freerdp_glyph_convert_ex(UINT32 width, UINT32 height, const BYTE* WINPR_RESTRICT data,
|
||||
size_t len)
|
||||
{
|
||||
/*
|
||||
* converts a 1-bit-per-pixel glyph to a one-byte-per-pixel glyph:
|
||||
* this approach uses a little more memory, but provides faster
|
||||
* means of accessing individual pixels in blitting operations
|
||||
*/
|
||||
const UINT32 scanline = (width + 7) / 8;
|
||||
const size_t scanline = (width + 7ull) / 8ull;
|
||||
const size_t required = scanline * height;
|
||||
if (len < required)
|
||||
return NULL;
|
||||
|
||||
if ((len == 0) || (width == 0) || (height == 0))
|
||||
return NULL;
|
||||
|
||||
WINPR_ASSERT(data);
|
||||
|
||||
BYTE* dstData = (BYTE*)winpr_aligned_malloc(1ull * width * height, 16);
|
||||
|
||||
if (!dstData)
|
||||
|
||||
@@ -270,20 +270,17 @@ static BOOL gdi_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, BOOL p
|
||||
/* Glyph Class */
|
||||
static BOOL gdi_Glyph_New(rdpContext* context, rdpGlyph* glyph)
|
||||
{
|
||||
BYTE* data = NULL;
|
||||
gdiGlyph* gdi_glyph = NULL;
|
||||
|
||||
if (!context || !glyph)
|
||||
return FALSE;
|
||||
|
||||
gdi_glyph = (gdiGlyph*)glyph;
|
||||
gdiGlyph* gdi_glyph = (gdiGlyph*)glyph;
|
||||
gdi_glyph->hdc = gdi_GetDC();
|
||||
|
||||
if (!gdi_glyph->hdc)
|
||||
return FALSE;
|
||||
|
||||
gdi_glyph->hdc->format = PIXEL_FORMAT_MONO;
|
||||
data = freerdp_glyph_convert(glyph->cx, glyph->cy, glyph->aj);
|
||||
BYTE* data = freerdp_glyph_convert_ex(glyph->cx, glyph->cy, glyph->aj, glyph->cb);
|
||||
|
||||
if (!data)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user