From 83ffa524e90ae08a0f940b70cf66204477a172be Mon Sep 17 00:00:00 2001
From: akallabeth <akallabeth@posteo.net>
Date: Tue, 26 Aug 2025 10:44:13 +0200
Subject: [PATCH] [core,settings] fix ReceivedCapabilities reset

---
 libfreerdp/common/settings.c |  2 +-
 libfreerdp/core/settings.c   | 14 ++++++++++----
 libfreerdp/core/update.c     |  8 ++++++--
 3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c
index 74dbf3e9db09..70806fdacc06 100644
--- a/libfreerdp/common/settings.c
+++ b/libfreerdp/common/settings.c
@@ -897,7 +897,7 @@ BOOL freerdp_capability_buffer_resize(rdpSettings* settings, size_t count, BOOL
 		return TRUE;
 	}
 
-	const size_t oldsize = force ? 0 : settings->ReceivedCapabilitiesSize;
+	const size_t oldsize = settings->ReceivedCapabilitiesSize;
 	if (!resize_setting(settings, FreeRDP_ReceivedCapabilityDataSizes, oldsize, count,
 	                    sizeof(uint32_t)))
 		return FALSE;
diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c
index ceae4f9e7f81..1928bc0bceab 100644
--- a/libfreerdp/core/settings.c
+++ b/libfreerdp/core/settings.c
@@ -1289,6 +1289,14 @@ static void freerdp_settings_free_internal(rdpSettings* settings)
 	freerdp_settings_free_keys(settings, TRUE);
 }
 
+static void freerdp_settings_free_internal_ensure_reset(rdpSettings* settings)
+{
+	settings->ServerLicenseProductIssuersCount = 0;
+	settings->ServerLicenseProductIssuers = NULL;
+
+	settings->ReceivedCapabilitiesSize = 0;
+}
+
 void freerdp_settings_free(rdpSettings* settings)
 {
 	if (!settings)
@@ -1511,15 +1519,13 @@ BOOL freerdp_settings_copy(rdpSettings* _settings, const rdpSettings* settings)
 
 	/* This is required to free all non string buffers */
 	freerdp_settings_free_internal(_settings);
+
 	/* This copies everything except allocated non string buffers. reset all allocated buffers to
 	 * NULL to fix issues during cleanup */
 	rc = freerdp_settings_clone_keys(_settings, settings);
-
-	_settings->ServerLicenseProductIssuersCount = 0;
-	_settings->ServerLicenseProductIssuers = NULL;
-
 	if (!rc)
 		goto out_fail;
+	freerdp_settings_free_internal_ensure_reset(_settings);
 
 	/* Begin copying */
 	if (!freerdp_settings_int_buffer_copy(_settings, settings))
diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c
index afbd69111aa6..890c676788aa 100644
--- a/libfreerdp/core/update.c
+++ b/libfreerdp/core/update.c
@@ -273,7 +273,7 @@ static BOOL update_write_bitmap_update(rdpUpdate* update, wStream* s,
 	if (!Stream_EnsureRemainingCapacity(s, 32))
 		return FALSE;
 
-	Stream_Write_UINT16(s, UPDATE_TYPE_BITMAP);   /* updateType */
+	Stream_Write_UINT16(s, UPDATE_TYPE_BITMAP); /* updateType */
 	Stream_Write_UINT16(s, WINPR_ASSERTING_INT_CAST(
 	                           uint16_t, bitmapUpdate->number)); /* numberRectangles (2 bytes) */
 
@@ -1471,6 +1471,8 @@ static BOOL update_send_frame_acknowledge(rdpContext* context, UINT32 frameId)
 
 	WINPR_ASSERT(rdp);
 	WINPR_ASSERT(rdp->settings);
+	WINPR_ASSERT(rdp->settings->ReceivedCapabilities);
+	WINPR_ASSERT(rdp->settings->ReceivedCapabilitiesSize > CAPSET_TYPE_FRAME_ACKNOWLEDGE);
 	if (rdp->settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
 	{
 		UINT16 sec_flags = 0;
@@ -1554,6 +1556,8 @@ static BOOL update_send_play_sound(rdpContext* context, const PLAY_SOUND_UPDATE*
 	WINPR_ASSERT(rdp);
 	WINPR_ASSERT(rdp->settings);
 	WINPR_ASSERT(play_sound);
+	WINPR_ASSERT(rdp->settings->ReceivedCapabilities);
+	WINPR_ASSERT(rdp->settings->ReceivedCapabilitiesSize > CAPSET_TYPE_SOUND);
 	if (!rdp->settings->ReceivedCapabilities[CAPSET_TYPE_SOUND])
 	{
 		return TRUE;
@@ -2826,7 +2830,7 @@ static BOOL update_send_window_icon(rdpContext* context, const WINDOW_ORDER_INFO
 	    s, WINPR_ASSERTING_INT_CAST(uint16_t, iconInfo->cbBitsMask)); /* CbBitsMask (2 bytes) */
 	Stream_Write_UINT16(
 	    s, WINPR_ASSERTING_INT_CAST(uint16_t, iconInfo->cbBitsColor)); /* CbBitsColor (2 bytes) */
-	Stream_Write(s, iconInfo->bitsMask, iconInfo->cbBitsMask); /* BitsMask (variable) */
+	Stream_Write(s, iconInfo->bitsMask, iconInfo->cbBitsMask);         /* BitsMask (variable) */
 
 	if (iconInfo->bpp <= 8)
 	{
