From 0746639629cc0eb1eb61e880c626c8db393665cf Mon Sep 17 00:00:00 2001
From: Armin Novak <armin.novak@thincast.com>
Date: Sun, 15 Feb 2026 19:19:07 +0100
Subject: [PATCH] [codec,clear] fix missing destination boundary checks

---
 libfreerdp/codec/clear.c | 51 +++++++++++++++++++++++++---------------
 1 file changed, 32 insertions(+), 19 deletions(-)

diff --git a/libfreerdp/codec/clear.c b/libfreerdp/codec/clear.c
index 18bc74e68cf4..25724fed41f9 100644
--- a/libfreerdp/codec/clear.c
+++ b/libfreerdp/codec/clear.c
@@ -455,40 +455,41 @@ static BOOL clear_decompress_subcodecs_data(CLEAR_CONTEXT* WINPR_RESTRICT clear,
                                             UINT32 nDstWidth, UINT32 nDstHeight,
                                             const gdiPalette* WINPR_RESTRICT palette)
 {
-	UINT16 xStart = 0;
-	UINT16 yStart = 0;
-	UINT16 width = 0;
-	UINT16 height = 0;
-	UINT32 bitmapDataByteCount = 0;
-	BYTE subcodecId = 0;
 	UINT32 suboffset = 0;
 
 	if (!Stream_CheckAndLogRequiredLength(TAG, s, subcodecByteCount))
 		return FALSE;
 
-	suboffset = 0;
-
 	while (suboffset < subcodecByteCount)
 	{
-		UINT32 nXDstRel = 0;
-		UINT32 nYDstRel = 0;
-
 		if (!Stream_CheckAndLogRequiredLength(TAG, s, 13))
 			return FALSE;
 
-		Stream_Read_UINT16(s, xStart);
-		Stream_Read_UINT16(s, yStart);
-		Stream_Read_UINT16(s, width);
-		Stream_Read_UINT16(s, height);
-		Stream_Read_UINT32(s, bitmapDataByteCount);
-		Stream_Read_UINT8(s, subcodecId);
+		const UINT16 xStart = Stream_Get_UINT16(s);
+		const UINT16 yStart = Stream_Get_UINT16(s);
+		const UINT16 width = Stream_Get_UINT16(s);
+		const UINT16 height = Stream_Get_UINT16(s);
+		const UINT32 bitmapDataByteCount = Stream_Get_UINT32(s);
+		const UINT8 subcodecId = Stream_Get_UINT8(s);
 		suboffset += 13;
 
 		if (!Stream_CheckAndLogRequiredLength(TAG, s, bitmapDataByteCount))
 			return FALSE;
 
-		nXDstRel = nXDst + xStart;
-		nYDstRel = nYDst + yStart;
+		const UINT32 nXDstRel = nXDst + xStart;
+		const UINT32 nYDstRel = nYDst + yStart;
+		if (1ull * nXDstRel + width > nWidth)
+		{
+			WLog_ERR(TAG, "nXDstRel %" PRIu16 " + width %" PRIu16 " > nWidth %" PRIu32 "", xStart,
+			         width, nWidth);
+			return FALSE;
+		}
+		if (1ull * nYDstRel + height > nHeight)
+		{
+			WLog_ERR(TAG, "nYDstRel %" PRIu16 " + height %" PRIu16 " > nHeight %" PRIu32 "", yStart,
+			         height, nHeight);
+			return FALSE;
+		}
 
 		if (1ull * xStart + width > nWidth)
 		{
@@ -1045,6 +1046,18 @@ INT32 clear_decompress(CLEAR_CONTEXT* WINPR_RESTRICT clear, const BYTE* WINPR_RE
 	if ((nWidth > 0xFFFF) || (nHeight > 0xFFFF))
 		return -1004;
 
+	if (nXDst > nDstWidth)
+	{
+		WLog_WARN(TAG, "nXDst %" PRIu32 " > nDstWidth %" PRIu32, nXDst, nDstWidth);
+		return -1005;
+	}
+
+	if (nYDst > nDstHeight)
+	{
+		WLog_WARN(TAG, "nYDst %" PRIu32 " > nDstHeight %" PRIu32, nYDst, nDstHeight);
+		return -1006;
+	}
+
 	s = Stream_StaticConstInit(&sbuffer, pSrcData, SrcSize);
 
 	if (!s)


From 7d8fdce2d0ef337cb86cb37fc0c436c905e04d77 Mon Sep 17 00:00:00 2001
From: Armin Novak <armin.novak@thincast.com>
Date: Mon, 16 Feb 2026 19:56:55 +0100
Subject: [PATCH] [codec,clear] fix destination checks

check against the correct nDstWidth/nDstHeight
---
 libfreerdp/codec/clear.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libfreerdp/codec/clear.c b/libfreerdp/codec/clear.c
index 25724fed41f9..0158bacfb0b6 100644
--- a/libfreerdp/codec/clear.c
+++ b/libfreerdp/codec/clear.c
@@ -478,16 +478,16 @@ static BOOL clear_decompress_subcodecs_data(CLEAR_CONTEXT* WINPR_RESTRICT clear,
 
 		const UINT32 nXDstRel = nXDst + xStart;
 		const UINT32 nYDstRel = nYDst + yStart;
-		if (1ull * nXDstRel + width > nWidth)
+		if (1ull * nXDstRel + width > nDstWidth)
 		{
-			WLog_ERR(TAG, "nXDstRel %" PRIu16 " + width %" PRIu16 " > nWidth %" PRIu32 "", xStart,
-			         width, nWidth);
+			WLog_ERR(TAG, "nXDstRel %" PRIu32 " + width %" PRIu16 " > nDstWidth %" PRIu32 "",
+			         nXDstRel, width, nDstWidth);
 			return FALSE;
 		}
-		if (1ull * nYDstRel + height > nHeight)
+		if (1ull * nYDstRel + height > nDstHeight)
 		{
-			WLog_ERR(TAG, "nYDstRel %" PRIu16 " + height %" PRIu16 " > nHeight %" PRIu32 "", yStart,
-			         height, nHeight);
+			WLog_ERR(TAG, "nYDstRel %" PRIu32 " + height %" PRIu16 " > nDstHeight %" PRIu32 "",
+			         nYDstRel, height, nDstHeight);
 			return FALSE;
 		}
 
