From d2d4f449312ddafd4a4c6c8a4f856c7f0d44a3b5 Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Mon, 26 Jan 2026 10:38:03 +0100
Subject: [PATCH] [channels,rdpecam] ensure sws context size matches

---
 channels/rdpecam/client/camera.h             |  2 +
 channels/rdpecam/client/camera_device_main.c |  7 ++-
 channels/rdpecam/client/encoding.c           | 48 ++++++++++++++++----
 channels/remdesk/server/remdesk_main.c       |  3 +-
 4 files changed, 47 insertions(+), 13 deletions(-)

diff -urp FreeRDP-3.10.3.orig/channels/rdpecam/client/camera.h FreeRDP-3.10.3/channels/rdpecam/client/camera.h
--- FreeRDP-3.10.3.orig/channels/rdpecam/client/camera.h	2024-12-17 03:06:36.000000000 -0600
+++ FreeRDP-3.10.3/channels/rdpecam/client/camera.h	2026-02-17 20:30:13.782519238 -0600
@@ -106,6 +106,8 @@ typedef struct
 #endif
 
 	/* sws_scale */
+	uint32_t swsWidth;
+	uint32_t swsHeight;
 	struct SwsContext* sws;
 
 } CameraDeviceStream;
diff -urp FreeRDP-3.10.3.orig/channels/rdpecam/client/encoding.c FreeRDP-3.10.3/channels/rdpecam/client/encoding.c
--- FreeRDP-3.10.3.orig/channels/rdpecam/client/encoding.c	2024-12-17 03:06:36.000000000 -0600
+++ FreeRDP-3.10.3/channels/rdpecam/client/encoding.c	2026-02-18 08:45:03.777015421 -0600
@@ -87,6 +87,30 @@ static enum AVPixelFormat ecamToAVPixFor
 	}
 }
 
+static void ecam_sws_free(CameraDeviceStream* stream)
+{
+	if (stream->sws)
+	{
+		sws_freeContext(stream->sws);
+		stream->sws = NULL;
+	}
+}
+
+static BOOL ecam_sws_valid(const CameraDeviceStream* stream)
+{
+	if (!stream->sws)
+		return FALSE;
+	if (stream->swsWidth != stream->currMediaType.Width)
+		return FALSE;
+	if (stream->swsHeight != stream->currMediaType.Height)
+		return FALSE;
+	if (stream->currMediaType.Width > INT32_MAX)
+		return FALSE;
+	if (stream->currMediaType.Height > INT32_MAX)
+		return FALSE;
+	return TRUE;
+}
+
 /**
  * Function description
  * initialize libswscale
@@ -97,9 +121,16 @@ static BOOL ecam_init_sws_context(Camera
 {
 	WINPR_ASSERT(stream);
 
-	if (stream->sws)
+	if (stream->currMediaType.Width > INT32_MAX)
+		return FALSE;
+	if (stream->currMediaType.Height > INT32_MAX)
+		return FALSE;
+
+	if (ecam_sws_valid(stream))
 		return TRUE;
 
+	ecam_sws_free(stream);
+
 	/* replacing deprecated JPEG formats, still produced by decoder */
 	switch (pixFormat)
 	{
@@ -127,8 +158,10 @@ static BOOL ecam_init_sws_context(Camera
 			break;
 	}
 
-	const int width = (int)stream->currMediaType.Width;
-	const int height = (int)stream->currMediaType.Height;
+	stream->swsWidth = stream->currMediaType.Width;
+	stream->swsHeight = stream->currMediaType.Height;
+	const int width = WINPR_ASSERTING_INT_CAST(int, stream->currMediaType.Width);
+	const int height = WINPR_ASSERTING_INT_CAST(int, stream->currMediaType.Height);
 
 	stream->sws = sws_getContext(width, height, pixFormat, width, height, AV_PIX_FMT_YUV420P, 0,
 	                             NULL, NULL, NULL);
@@ -158,6 +191,9 @@ static BOOL ecam_encoder_compress_h264(C
 	CAM_MEDIA_FORMAT inputFormat = streamInputFormat(stream);
 	enum AVPixelFormat pixFormat = AV_PIX_FMT_NONE;
 
+	if (!ecam_sws_valid(stream))
+		return FALSE;
+
 #if defined(WITH_INPUT_FORMAT_MJPG)
 	if (inputFormat == CAM_MEDIA_FORMAT_MJPG)
 	{
@@ -236,11 +272,7 @@ static void ecam_encoder_context_free_h2
 {
 	WINPR_ASSERT(stream);
 
-	if (stream->sws)
-	{
-		sws_freeContext(stream->sws);
-		stream->sws = NULL;
-	}
+	ecam_sws_free(stream);
 
 #if defined(WITH_INPUT_FORMAT_MJPG)
 	if (stream->avOutFrame)
diff -urp FreeRDP-3.10.3.orig/channels/remdesk/server/remdesk_main.c FreeRDP-3.10.3/channels/remdesk/server/remdesk_main.c
--- FreeRDP-3.10.3.orig/channels/remdesk/server/remdesk_main.c	2024-12-17 03:06:36.000000000 -0600
+++ FreeRDP-3.10.3/channels/remdesk/server/remdesk_main.c	2026-02-18 09:19:29.009278942 -0600
@@ -538,7 +538,8 @@ static DWORD WINAPI remdesk_server_threa
 				Stream_SealLength(s);
 				Stream_SetPosition(s, 0);
 
-				if ((error = remdesk_server_receive_pdu(context, s)))
+				error = remdesk_server_receive_pdu(context, s);
+				if (error)
 				{
 					WLog_ERR(TAG, "remdesk_server_receive_pdu failed with error %" PRIu32 "!",
 					         error);
