From 6482b7a92fff3959582cef052d1967ad6bde3738 Mon Sep 17 00:00:00 2001
From: Armin Novak <armin.novak@thincast.com>
Date: Sat, 28 Feb 2026 11:38:23 +0100
Subject: [PATCH] [codec,h264] validate rectangles before use

---
 libfreerdp/codec/h264.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

Index: FreeRDP-3.10.3/libfreerdp/codec/h264.c
===================================================================
--- FreeRDP-3.10.3.orig/libfreerdp/codec/h264.c
+++ FreeRDP-3.10.3/libfreerdp/codec/h264.c
@@ -91,6 +91,37 @@ BOOL avc420_ensure_buffer(H264_CONTEXT*
 	return TRUE;
 }
 
+static BOOL isRectValid(UINT32 width, UINT32 height, const RECTANGLE_16* rect)
+{
+	WINPR_ASSERT(rect);
+	if (rect->left > width)
+		return FALSE;
+	if (rect->right > width)
+		return FALSE;
+	if (rect->left >= rect->right)
+		return FALSE;
+	if (rect->top > height)
+		return FALSE;
+	if (rect->bottom > height)
+		return FALSE;
+	if (rect->top >= rect->bottom)
+		return FALSE;
+	return TRUE;
+}
+
+static BOOL areRectsValid(UINT32 width, UINT32 height, const RECTANGLE_16* rects, UINT32 count)
+{
+	WINPR_ASSERT(rects || (count == 0));
+	for (size_t x = 0; x < count; x++)
+	{
+		const RECTANGLE_16* rect = &rects[x];
+		if (!isRectValid(width, height, rect))
+			return FALSE;
+	}
+	return TRUE;
+}
+
+
 INT32 avc420_decompress(H264_CONTEXT* h264, const BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstData,
                         DWORD DstFormat, UINT32 nDstStep, UINT32 nDstWidth, UINT32 nDstHeight,
                         const RECTANGLE_16* regionRects, UINT32 numRegionRects)
@@ -101,6 +132,9 @@ INT32 avc420_decompress(H264_CONTEXT* h2
 	if (!h264 || h264->Compressor)
 		return -1001;
 
+	if (!areRectsValid(nDstWidth, nDstHeight, regionRects, numRegionRects))
+		return -1013;
+
 	status = h264->subsystem->Decompress(h264, pSrcData, SrcSize);
 
 	if (status == 0)
@@ -551,6 +585,11 @@ INT32 avc444_decompress(H264_CONTEXT* h2
 	if (!h264 || !regionRects || !pSrcData || !pDstData || h264->Compressor)
 		return -1001;
 
+	if (!areRectsValid(nDstWidth, nDstHeight, regionRects, numRegionRects))
+		return -1013;
+	if (!areRectsValid(nDstWidth, nDstHeight, auxRegionRects, numAuxRegionRect))
+		return -1014;
+
 	switch (op)
 	{
 		case 0: /* YUV420 in stream 1
