From f282c55c7a02caa80a53e88931725efedcae7085 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Tue, 29 Sep 2020 08:22:28 +0200 Subject: [PATCH] Added clipboard CB_HUGE_FILE_SUPPORT_ENABLED flag --- channels/cliprdr/client/cliprdr_main.c | 19 +++++++++++++++++++ channels/cliprdr/client/cliprdr_main.h | 1 + channels/cliprdr/server/cliprdr_main.c | 14 ++++++++++++++ client/Wayland/wlf_cliprdr.c | 3 ++- client/X11/xf_cliprdr.c | 3 ++- include/freerdp/channels/cliprdr.h | 1 + include/freerdp/server/cliprdr.h | 1 + server/proxy/pf_cliprdr.c | 1 + 8 files changed, 41 insertions(+), 2 deletions(-) diff --git a/channels/cliprdr/client/cliprdr_main.c b/channels/cliprdr/client/cliprdr_main.c index 188e029b8..c7457c089 100644 --- a/channels/cliprdr/client/cliprdr_main.c +++ b/channels/cliprdr/client/cliprdr_main.c @@ -119,6 +119,9 @@ static void cliprdr_print_general_capability_flags(UINT32 flags) if (flags & CB_CAN_LOCK_CLIPDATA) WLog_INFO(TAG, "\tCB_CAN_LOCK_CLIPDATA"); + if (flags & CB_HUGE_FILE_SUPPORT_ENABLED) + WLog_INFO(TAG, "\tCB_HUGE_FILE_SUPPORT_ENABLED"); + WLog_INFO(TAG, "}"); } #endif @@ -157,6 +160,7 @@ static UINT cliprdr_process_general_capability(cliprdrPlugin* cliprdr, wStream* cliprdr->streamFileClipEnabled = (generalFlags & CB_STREAM_FILECLIP_ENABLED); cliprdr->fileClipNoFilePaths = (generalFlags & CB_FILECLIP_NO_FILE_PATHS); cliprdr->canLockClipData = (generalFlags & CB_CAN_LOCK_CLIPDATA); + cliprdr->hasHugeFileSupport = (generalFlags & CB_HUGE_FILE_SUPPORT_ENABLED); cliprdr->capabilitiesReceived = TRUE; if (!context->custom) @@ -571,11 +575,14 @@ static UINT cliprdr_client_capabilities(CliprdrClientContext* context, flags &= ~CB_FILECLIP_NO_FILE_PATHS; if (!cliprdr->canLockClipData) flags &= CB_CAN_LOCK_CLIPDATA; + if (!cliprdr->hasHugeFileSupport) + flags &= CB_HUGE_FILE_SUPPORT_ENABLED; cliprdr->useLongFormatNames = flags & CB_USE_LONG_FORMAT_NAMES; cliprdr->streamFileClipEnabled = flags & CB_STREAM_FILECLIP_ENABLED; cliprdr->fileClipNoFilePaths = flags & CB_FILECLIP_NO_FILE_PATHS; cliprdr->canLockClipData = flags & CB_CAN_LOCK_CLIPDATA; + cliprdr->hasHugeFileSupport = flags & CB_HUGE_FILE_SUPPORT_ENABLED; Stream_Write_UINT32(s, flags); /* generalFlags */ WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientCapabilities"); @@ -774,6 +781,18 @@ cliprdr_client_file_contents_request(CliprdrClientContext* context, wStream* s; cliprdrPlugin* cliprdr = (cliprdrPlugin*)context->handle; + if (!cliprdr) + return ERROR_INTERNAL_ERROR; + + if (!cliprdr->hasHugeFileSupport) + { + if (((UINT64)fileContentsRequest->cbRequested + fileContentsRequest->nPositionLow) > + UINT32_MAX) + return ERROR_INVALID_PARAMETER; + if (fileContentsRequest->nPositionHigh != 0) + return ERROR_INVALID_PARAMETER; + } + s = cliprdr_packet_file_contents_request_new(fileContentsRequest); if (!s) diff --git a/channels/cliprdr/client/cliprdr_main.h b/channels/cliprdr/client/cliprdr_main.h index a23340786..b6cd7dbab 100644 --- a/channels/cliprdr/client/cliprdr_main.h +++ b/channels/cliprdr/client/cliprdr_main.h @@ -49,6 +49,7 @@ struct cliprdr_plugin BOOL streamFileClipEnabled; BOOL fileClipNoFilePaths; BOOL canLockClipData; + BOOL hasHugeFileSupport; }; typedef struct cliprdr_plugin cliprdrPlugin; diff --git a/channels/cliprdr/server/cliprdr_main.c b/channels/cliprdr/server/cliprdr_main.c index da4ab0b9b..7e0b6812e 100644 --- a/channels/cliprdr/server/cliprdr_main.c +++ b/channels/cliprdr/server/cliprdr_main.c @@ -453,6 +453,10 @@ static UINT cliprdr_server_receive_general_capability(CliprdrServerContext* cont if (context->canLockClipData) context->canLockClipData = (cap_set->generalFlags & CB_CAN_LOCK_CLIPDATA) ? TRUE : FALSE; + if (context->hasHugeFileSupport) + context->hasHugeFileSupport = + (cap_set->generalFlags & CB_HUGE_FILE_SUPPORT_ENABLED) ? TRUE : FALSE; + return CHANNEL_RC_OK; } @@ -776,6 +780,13 @@ static UINT cliprdr_server_receive_filecontents_request(CliprdrServerContext* co if ((error = cliprdr_read_file_contents_request(s, &request))) return error; + if (!context->hasHugeFileSupport) + { + if (request.nPositionHigh > 0) + return ERROR_INVALID_DATA; + if ((UINT64)request.nPositionLow + request.cbRequested > UINT32_MAX) + return ERROR_INVALID_DATA; + } IFCALLRET(context->ClientFileContentsRequest, error, context, &request); if (error) @@ -948,6 +959,9 @@ static UINT cliprdr_server_init(CliprdrServerContext* context) if (context->canLockClipData) generalFlags |= CB_CAN_LOCK_CLIPDATA; + if (context->hasHugeFileSupport) + generalFlags |= CB_HUGE_FILE_SUPPORT_ENABLED; + capabilities.msgType = CB_CLIP_CAPS; capabilities.msgFlags = 0; capabilities.dataLen = 4 + CB_CAPSTYPE_GENERAL_LEN; diff --git a/client/Wayland/wlf_cliprdr.c b/client/Wayland/wlf_cliprdr.c index dff599844..0762cfa3d 100644 --- a/client/Wayland/wlf_cliprdr.c +++ b/client/Wayland/wlf_cliprdr.c @@ -306,7 +306,8 @@ static UINT wlf_cliprdr_send_client_capabilities(wfClipboard* clipboard) generalCapabilitySet.generalFlags = CB_USE_LONG_FORMAT_NAMES; if (clipboard->streams_supported && clipboard->file_formats_registered) - generalCapabilitySet.generalFlags |= CB_STREAM_FILECLIP_ENABLED | CB_FILECLIP_NO_FILE_PATHS; + generalCapabilitySet.generalFlags |= + CB_STREAM_FILECLIP_ENABLED | CB_FILECLIP_NO_FILE_PATHS | CB_HUGE_FILE_SUPPORT_ENABLED; return clipboard->context->ClientCapabilities(clipboard->context, &capabilities); } diff --git a/client/X11/xf_cliprdr.c b/client/X11/xf_cliprdr.c index 1b238c3f0..a590551e1 100644 --- a/client/X11/xf_cliprdr.c +++ b/client/X11/xf_cliprdr.c @@ -1064,7 +1064,8 @@ static UINT xf_cliprdr_send_client_capabilities(xfClipboard* clipboard) generalCapabilitySet.generalFlags = CB_USE_LONG_FORMAT_NAMES; if (clipboard->streams_supported && clipboard->file_formats_registered) - generalCapabilitySet.generalFlags |= CB_STREAM_FILECLIP_ENABLED | CB_FILECLIP_NO_FILE_PATHS; + generalCapabilitySet.generalFlags |= + CB_STREAM_FILECLIP_ENABLED | CB_FILECLIP_NO_FILE_PATHS | CB_HUGE_FILE_SUPPORT_ENABLED; return clipboard->context->ClientCapabilities(clipboard->context, &capabilities); } diff --git a/include/freerdp/channels/cliprdr.h b/include/freerdp/channels/cliprdr.h index 78dbec13a..857e7af10 100644 --- a/include/freerdp/channels/cliprdr.h +++ b/include/freerdp/channels/cliprdr.h @@ -70,6 +70,7 @@ #define CB_STREAM_FILECLIP_ENABLED 0x00000004 #define CB_FILECLIP_NO_FILE_PATHS 0x00000008 #define CB_CAN_LOCK_CLIPDATA 0x00000010 +#define CB_HUGE_FILE_SUPPORT_ENABLED 0x00000020 /* File Contents Request Flags */ #define FILECONTENTS_SIZE 0x00000001 diff --git a/include/freerdp/server/cliprdr.h b/include/freerdp/server/cliprdr.h index ddffdcd3b..fdd48505f 100644 --- a/include/freerdp/server/cliprdr.h +++ b/include/freerdp/server/cliprdr.h @@ -94,6 +94,7 @@ struct _cliprdr_server_context BOOL streamFileClipEnabled; BOOL fileClipNoFilePaths; BOOL canLockClipData; + BOOL hasHugeFileSupport; psCliprdrOpen Open; psCliprdrClose Close; diff --git a/server/proxy/pf_cliprdr.c b/server/proxy/pf_cliprdr.c index b4904199d..dca8f0ef6 100644 --- a/server/proxy/pf_cliprdr.c +++ b/server/proxy/pf_cliprdr.c @@ -45,6 +45,7 @@ BOOL pf_server_cliprdr_init(pServerContext* ps) cliprdr->streamFileClipEnabled = TRUE; cliprdr->fileClipNoFilePaths = TRUE; cliprdr->canLockClipData = TRUE; + cliprdr->hasHugeFileSupport = TRUE; /* disable initialization sequence, for caps sync */ cliprdr->autoInitializationSequence = FALSE;