From c4a7c371342edf0d307cea728f56d3302f0ab38c Mon Sep 17 00:00:00 2001 From: akallabeth Date: Thu, 15 Jan 2026 12:04:36 +0100 Subject: [PATCH 1/6] [gdi,gfx] properly clamp SurfaceToSurface --- libfreerdp/gdi/gfx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libfreerdp/gdi/gfx.c b/libfreerdp/gdi/gfx.c index 56e6ff9ed..96ce10070 100644 --- a/libfreerdp/gdi/gfx.c +++ b/libfreerdp/gdi/gfx.c @@ -1335,8 +1335,6 @@ static UINT gdi_SurfaceToSurface(RdpgfxClientContext* context, { UINT status = ERROR_INTERNAL_ERROR; BOOL sameSurface = 0; - UINT32 nWidth = 0; - UINT32 nHeight = 0; const RECTANGLE_16* rectSrc = NULL; RECTANGLE_16 invalidRect; gdiGfxSurface* surfaceSrc = NULL; @@ -1362,8 +1360,8 @@ static UINT gdi_SurfaceToSurface(RdpgfxClientContext* context, if (!is_rect_valid(rectSrc, surfaceSrc->width, surfaceSrc->height)) goto fail; - nWidth = rectSrc->right - rectSrc->left; - nHeight = rectSrc->bottom - rectSrc->top; + const UINT32 nWidth = rectSrc->right - rectSrc->left; + const UINT32 nHeight = rectSrc->bottom - rectSrc->top; for (UINT16 index = 0; index < surfaceToSurface->destPtsCount; index++) { @@ -1374,8 +1372,10 @@ static UINT gdi_SurfaceToSurface(RdpgfxClientContext* context, if (!is_rect_valid(&rect, surfaceDst->width, surfaceDst->height)) goto fail; + const UINT32 rwidth = rect.right - rect.left; + const UINT32 rheight = rect.bottom - rect.top; if (!freerdp_image_copy(surfaceDst->data, surfaceDst->format, surfaceDst->scanline, - destPt->x, destPt->y, nWidth, nHeight, surfaceSrc->data, + destPt->x, destPt->y, rwidth, rheight, surfaceSrc->data, surfaceSrc->format, surfaceSrc->scanline, rectSrc->left, rectSrc->top, NULL, FREERDP_FLIP_NONE)) goto fail; From c4391827d7facfc874ca7f61a92afb82232a5748 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Thu, 15 Jan 2026 12:11:57 +0100 Subject: [PATCH 2/6] [codec,clear] fix clear_resize_buffer checks --- libfreerdp/codec/clear.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libfreerdp/codec/clear.c b/libfreerdp/codec/clear.c index ad5752909..aa36baa9b 100644 --- a/libfreerdp/codec/clear.c +++ b/libfreerdp/codec/clear.c @@ -58,7 +58,7 @@ struct S_CLEAR_CONTEXT NSC_CONTEXT* nsc; UINT32 seqNumber; BYTE* TempBuffer; - UINT32 TempSize; + size_t TempSize; UINT32 nTempStep; UINT32 TempFormat; UINT32 format; @@ -328,16 +328,17 @@ static BOOL clear_decompress_subcode_rlex(wStream* WINPR_RESTRICT s, UINT32 bitm static BOOL clear_resize_buffer(CLEAR_CONTEXT* WINPR_RESTRICT clear, UINT32 width, UINT32 height) { - UINT32 size = 0; - if (!clear) return FALSE; - size = ((width + 16) * (height + 16) * FreeRDPGetBytesPerPixel(clear->format)); + const UINT64 size = 1ull * (width + 16ull) * (height + 16ull); + const size_t bpp = FreeRDPGetBytesPerPixel(clear->format); + if (size > UINT32_MAX / bpp) + return FALSE; - if (size > clear->TempSize) + if (size > clear->TempSize / bpp) { - BYTE* tmp = (BYTE*)winpr_aligned_recalloc(clear->TempBuffer, size, sizeof(BYTE), 32); + BYTE* tmp = (BYTE*)winpr_aligned_recalloc(clear->TempBuffer, size, bpp, 32); if (!tmp) { @@ -346,7 +347,7 @@ static BOOL clear_resize_buffer(CLEAR_CONTEXT* WINPR_RESTRICT clear, UINT32 widt return FALSE; } - clear->TempSize = size; + clear->TempSize = size * bpp; clear->TempBuffer = tmp; } From 25102b432fb37916a1a553d7ef8fd940c6e52c3f Mon Sep 17 00:00:00 2001 From: akallabeth Date: Thu, 15 Jan 2026 12:17:33 +0100 Subject: [PATCH 3/6] [codec,clear] fix missing length checks --- libfreerdp/codec/clear.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libfreerdp/codec/clear.c b/libfreerdp/codec/clear.c index aa36baa9b..4a67a8ed6 100644 --- a/libfreerdp/codec/clear.c +++ b/libfreerdp/codec/clear.c @@ -1139,8 +1139,10 @@ INT32 clear_decompress(CLEAR_CONTEXT* WINPR_RESTRICT clear, const BYTE* WINPR_RE if (glyphData) { - if (!freerdp_image_copy_no_overlap(glyphData, clear->format, 0, 0, 0, nWidth, nHeight, - pDstData, DstFormat, nDstStep, nXDst, nYDst, palette, + const uint32_t w = MIN(nWidth, nDstWidth); + const uint32_t h = MIN(nHeight, nDstHeight); + if (!freerdp_image_copy_no_overlap(glyphData, clear->format, 0, 0, 0, w, h, pDstData, + DstFormat, nDstStep, nXDst, nYDst, palette, FREERDP_KEEP_DST_ALPHA)) goto fail; } From f8688b57f6cfad9a0b05475a6afbde355ffab720 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Thu, 15 Jan 2026 12:19:53 +0100 Subject: [PATCH 4/6] [codec,clear] fix off by one length check --- libfreerdp/codec/clear.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libfreerdp/codec/clear.c b/libfreerdp/codec/clear.c index 4a67a8ed6..0efa89f8d 100644 --- a/libfreerdp/codec/clear.c +++ b/libfreerdp/codec/clear.c @@ -876,12 +876,12 @@ static BOOL clear_decompress_bands_data(CLEAR_CONTEXT* WINPR_RESTRICT clear, if (count > nHeight) count = nHeight; - if (nXDstRel + i > nDstWidth) + if (nXDstRel + i >= nDstWidth) return FALSE; for (UINT32 y = 0; y < count; y++) { - if (nYDstRel + y > nDstHeight) + if (nYDstRel + y >= nDstHeight) return FALSE; BYTE* pDstPixel8 = From 1bab198a2edd0d0e6e1627d21a433151ea190500 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Thu, 15 Jan 2026 12:02:02 +0100 Subject: [PATCH 5/6] [codec,planar] fix decoder length checks --- libfreerdp/codec/planar.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libfreerdp/codec/planar.c b/libfreerdp/codec/planar.c index 1a06e36ed..94a640a55 100644 --- a/libfreerdp/codec/planar.c +++ b/libfreerdp/codec/planar.c @@ -727,6 +727,11 @@ BOOL freerdp_bitmap_decompress_planar(BITMAP_PLANAR_CONTEXT* WINPR_RESTRICT plan WINPR_ASSERT(planar); WINPR_ASSERT(prims); + if (planar->maxWidth < nSrcWidth) + return FALSE; + if (planar->maxHeight < nSrcHeight) + return FALSE; + if (nDstStep <= 0) nDstStep = nDstWidth * FreeRDPGetBytesPerPixel(DstFormat); From 9964f8669d445c8adc36fb95c9987c680fff7a03 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Thu, 15 Jan 2026 12:45:08 +0100 Subject: [PATCH 6/6] [client,sdl] modernize code --- client/SDL/SDL3/sdl_monitor.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/client/SDL/SDL3/sdl_monitor.cpp b/client/SDL/SDL3/sdl_monitor.cpp index e3de2e597..5e1bb3a4d 100644 --- a/client/SDL/SDL3/sdl_monitor.cpp +++ b/client/SDL/SDL3/sdl_monitor.cpp @@ -98,15 +98,11 @@ static BOOL sdl_apply_mon_max_size(SdlContext* sdl, UINT32* pMaxWidth, UINT32* p { auto monitor = static_cast( freerdp_settings_get_pointer_array(settings, FreeRDP_MonitorDefArray, x)); - if (monitor->x < left) - left = monitor->x; - if (monitor->y < top) - top = monitor->y; - if (monitor->x + monitor->width > right) - right = monitor->x + monitor->width; - if (monitor->y + monitor->height > bottom) - bottom = monitor->y + monitor->height; + left = std::min(monitor->x, left); + top = std::min(monitor->y, top); + right = std::max(monitor->x + monitor->width, right); + bottom = std::max(monitor->y + monitor->height, bottom); } const int32_t w = right - left;