From 3bc1eeb4f63ceec9a696af194e4c1ea0e67ff60c Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Fri, 16 Jan 2026 12:00:15 +0100
Subject: [PATCH] [codec,color] add freerdp_glyph_convert_ex

The function freerdp_glyph_convert does not check input buffer length,
deprecate it and provide a replacement that does properly check.
---
 include/freerdp/codec/color.h | 23 +++++++++++++++++++++--
 libfreerdp/codec/color.c      | 21 ++++++++++++++++++++-
 2 files changed, 41 insertions(+), 3 deletions(-)

Index: FreeRDP-3.10.3/include/freerdp/codec/color.h
===================================================================
--- FreeRDP-3.10.3.orig/include/freerdp/codec/color.h
+++ FreeRDP-3.10.3/include/freerdp/codec/color.h
@@ -279,6 +279,7 @@ typedef struct gdi_palette gdiPalette;
 		return (FreeRDPGetBitsPerPixel(format) + 7) / 8;
 	}
 
+#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
 	/***
 	 *
 	 * @param width    width to copy in pixels
@@ -288,9 +289,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);
 
 	/***
 	 *
Index: FreeRDP-3.10.3/libfreerdp/codec/color.c
===================================================================
--- FreeRDP-3.10.3.orig/libfreerdp/codec/color.c
+++ FreeRDP-3.10.3/libfreerdp/codec/color.c
@@ -43,14 +43,33 @@
 
 #define TAG FREERDP_TAG("color")
 
+#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)
