[channels,cliprdr] refactor cliprdr_packet_format_list_new

* Simplify function
* Add missing arguments for ASCII names
This commit is contained in:
akallabeth 2024-08-13 15:05:20 +02:00 committed by Armin Novak
parent 92b547e91e
commit 1e19ccd76d
No known key found for this signature in database
GPG Key ID: 2CF4A2D2D3D72105
4 changed files with 51 additions and 115 deletions

View File

@ -677,7 +677,7 @@ static UINT cliprdr_client_format_list(CliprdrClientContext* context,
} }
cliprdr->initialFormatListSent = TRUE; cliprdr->initialFormatListSent = TRUE;
s = cliprdr_packet_format_list_new(&filterList, cliprdr->useLongFormatNames); s = cliprdr_packet_format_list_new(&filterList, cliprdr->useLongFormatNames, FALSE);
cliprdr_free_format_list(&filterList); cliprdr_free_format_list(&filterList);
if (!s) if (!s)

View File

@ -237,140 +237,76 @@ wStream* cliprdr_packet_file_contents_response_new(const CLIPRDR_FILE_CONTENTS_R
} }
wStream* cliprdr_packet_format_list_new(const CLIPRDR_FORMAT_LIST* formatList, wStream* cliprdr_packet_format_list_new(const CLIPRDR_FORMAT_LIST* formatList,
BOOL useLongFormatNames) BOOL useLongFormatNames, BOOL useAsciiNames)
{ {
wStream* s = NULL; WINPR_ASSERT(formatList);
size_t formatNameSize = 0;
char* szFormatName = NULL;
WCHAR* wszFormatName = NULL;
BOOL asciiNames = FALSE;
CLIPRDR_FORMAT* format = NULL;
UINT32 length = 0;
if (formatList->common.msgType != CB_FORMAT_LIST) if (formatList->common.msgType != CB_FORMAT_LIST)
WLog_WARN(TAG, "called with invalid type %08" PRIx32, formatList->common.msgType); WLog_WARN(TAG, "called with invalid type %08" PRIx32, formatList->common.msgType);
if (!useLongFormatNames) if (useLongFormatNames && useAsciiNames)
WLog_WARN(TAG, "called with invalid arguments useLongFormatNames=true && "
"useAsciiNames=true. useAsciiNames requires "
"useLongFormatNames=false, ignoring argument.");
const UINT32 length = formatList->numFormats * 36;
const size_t formatNameCharSize =
(useLongFormatNames || !useAsciiNames) ? sizeof(WCHAR) : sizeof(CHAR);
wStream* s = cliprdr_packet_new(CB_FORMAT_LIST, 0, length);
if (!s)
{ {
length = formatList->numFormats * 36; WLog_ERR(TAG, "cliprdr_packet_new failed!");
s = cliprdr_packet_new(CB_FORMAT_LIST, 0, length); return NULL;
if (!s)
{
WLog_ERR(TAG, "cliprdr_packet_new failed!");
return NULL;
}
for (UINT32 index = 0; index < formatList->numFormats; index++)
{
size_t formatNameLength = 0;
format = (CLIPRDR_FORMAT*)&(formatList->formats[index]);
Stream_Write_UINT32(s, format->formatId); /* formatId (4 bytes) */
formatNameSize = 0;
szFormatName = format->formatName;
if (asciiNames)
{
if (szFormatName)
formatNameLength = strnlen(szFormatName, 32);
if (formatNameLength > 31)
formatNameLength = 31;
Stream_Write(s, szFormatName, formatNameLength);
Stream_Zero(s, 32 - formatNameLength);
}
else
{
wszFormatName = NULL;
if (szFormatName && (strnlen(szFormatName, 2) > 0))
{
wszFormatName = ConvertUtf8ToWCharAlloc(szFormatName, &formatNameSize);
if (!wszFormatName)
{
Stream_Free(s, TRUE);
return NULL;
}
}
formatNameSize++;
if (formatNameSize > 15)
formatNameSize = 15;
/* size in bytes instead of wchar */
formatNameSize *= sizeof(WCHAR);
if (wszFormatName)
Stream_Write(s, wszFormatName, (size_t)formatNameSize);
Stream_Zero(s, (size_t)(32 - formatNameSize));
free(wszFormatName);
}
}
} }
else
for (UINT32 index = 0; index < formatList->numFormats; index++)
{ {
length = 0; const CLIPRDR_FORMAT* format = &(formatList->formats[index]);
for (UINT32 index = 0; index < formatList->numFormats; index++)
const char* szFormatName = format->formatName;
size_t formatNameLength = 0;
if (szFormatName)
formatNameLength = strlen(szFormatName);
size_t formatNameMaxLength = formatNameLength + 1; /* Ensure '\0' termination in output */
if (!Stream_EnsureRemainingCapacity(s,
4 + MAX(32, formatNameMaxLength * formatNameCharSize)))
goto fail;
Stream_Write_UINT32(s, format->formatId); /* formatId (4 bytes) */
if (!useLongFormatNames)
{ {
format = (CLIPRDR_FORMAT*)&(formatList->formats[index]); formatNameMaxLength = useAsciiNames ? 32 : 16;
length += 4; formatNameLength = MIN(formatNameMaxLength - 1, formatNameLength);
formatNameSize = sizeof(WCHAR);
if (format->formatName && (strnlen(format->formatName, 2) > 0))
{
SSIZE_T size = ConvertUtf8ToWChar(format->formatName, NULL, 0);
if (size < 0)
return NULL;
formatNameSize += (size_t)size * sizeof(WCHAR);
}
length += (UINT32)formatNameSize;
} }
s = cliprdr_packet_new(CB_FORMAT_LIST, 0, length); if (szFormatName && (formatNameLength > 0))
if (!s)
{ {
WLog_ERR(TAG, "cliprdr_packet_new failed!"); if (useAsciiNames)
return NULL;
}
for (UINT32 index = 0; index < formatList->numFormats; index++)
{
format = (CLIPRDR_FORMAT*)&(formatList->formats[index]);
Stream_Write_UINT32(s, format->formatId); /* formatId (4 bytes) */
if (format->formatName && (strnlen(format->formatName, 2) > 0))
{ {
const size_t cap = Stream_Capacity(s); Stream_Write(s, szFormatName, formatNameLength);
const size_t pos = Stream_GetPosition(s); Stream_Zero(s, formatNameMaxLength - formatNameLength);
const size_t rem = cap - pos;
if ((cap < pos) || ((rem / 2) > INT_MAX))
{
Stream_Free(s, TRUE);
return NULL;
}
const size_t len = strnlen(format->formatName, rem / sizeof(WCHAR));
if (Stream_Write_UTF16_String_From_UTF8(s, len, format->formatName, len, TRUE) < 0)
{
Stream_Free(s, TRUE);
return NULL;
}
} }
else else
{ {
Stream_Write_UINT16(s, 0); if (Stream_Write_UTF16_String_From_UTF8(s, formatNameMaxLength, szFormatName,
formatNameLength, TRUE) < 0)
goto fail;
} }
} }
else
Stream_Zero(s, formatNameMaxLength * formatNameCharSize);
} }
return s; return s;
fail:
Stream_Free(s, TRUE);
return NULL;
} }
UINT cliprdr_read_unlock_clipdata(wStream* s, CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData) UINT cliprdr_read_unlock_clipdata(wStream* s, CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData)
{ {
if (!Stream_CheckAndLogRequiredLength(TAG, s, 4)) if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))

View File

@ -42,7 +42,7 @@ cliprdr_packet_file_contents_request_new(const CLIPRDR_FILE_CONTENTS_REQUEST* re
FREERDP_LOCAL wStream* FREERDP_LOCAL wStream*
cliprdr_packet_file_contents_response_new(const CLIPRDR_FILE_CONTENTS_RESPONSE* response); cliprdr_packet_file_contents_response_new(const CLIPRDR_FILE_CONTENTS_RESPONSE* response);
FREERDP_LOCAL wStream* cliprdr_packet_format_list_new(const CLIPRDR_FORMAT_LIST* formatList, FREERDP_LOCAL wStream* cliprdr_packet_format_list_new(const CLIPRDR_FORMAT_LIST* formatList,
BOOL useLongFormatNames); BOOL useLongFormatNames, BOOL useAsciiNames);
FREERDP_LOCAL UINT cliprdr_read_lock_clipdata(wStream* s, FREERDP_LOCAL UINT cliprdr_read_lock_clipdata(wStream* s,
CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData); CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData);

View File

@ -230,7 +230,7 @@ static UINT cliprdr_server_format_list(CliprdrServerContext* context,
cliprdr = (CliprdrServerPrivate*)context->handle; cliprdr = (CliprdrServerPrivate*)context->handle;
s = cliprdr_packet_format_list_new(formatList, context->useLongFormatNames); s = cliprdr_packet_format_list_new(formatList, context->useLongFormatNames, FALSE);
if (!s) if (!s)
{ {
WLog_ERR(TAG, "cliprdr_packet_format_list_new failed!"); WLog_ERR(TAG, "cliprdr_packet_format_list_new failed!");