From 4f25410aa9ec6914d20c4f1b529ddefcd3e4392e Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 30 Jul 2018 23:20:14 -0700 Subject: [PATCH] GUACAMOLE-559: Guarantee ordered modification to the clipboard. Do not allow modification of clipboard while clipboard contents are being sent. --- src/common/clipboard.c | 28 ++++++++++++++++++++++++++-- src/common/common/clipboard.h | 8 ++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/common/clipboard.c b/src/common/clipboard.c index 4452bee7..eb2f5480 100644 --- a/src/common/clipboard.c +++ b/src/common/clipboard.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,8 @@ guac_common_clipboard* guac_common_clipboard_alloc(int size) { clipboard->length = 0; clipboard->available = size; + pthread_mutex_init(&(clipboard->lock), NULL); + return clipboard; } @@ -108,18 +111,37 @@ static void* __send_user_clipboard(guac_user* user, void* data) { } void guac_common_clipboard_send(guac_common_clipboard* clipboard, guac_client* client) { + + pthread_mutex_lock(&(clipboard->lock)); + guac_client_log(client, GUAC_LOG_DEBUG, "Broadcasting clipboard to all connected users."); guac_client_foreach_user(client, __send_user_clipboard, clipboard); guac_client_log(client, GUAC_LOG_DEBUG, "Broadcast of clipboard complete."); + + pthread_mutex_unlock(&(clipboard->lock)); + } -void guac_common_clipboard_reset(guac_common_clipboard* clipboard, const char* mimetype) { +void guac_common_clipboard_reset(guac_common_clipboard* clipboard, + const char* mimetype) { + + pthread_mutex_lock(&(clipboard->lock)); + + /* Clear clipboard contents */ clipboard->length = 0; - strncpy(clipboard->mimetype, mimetype, sizeof(clipboard->mimetype)-1); + + /* Assign given mimetype */ + strncpy(clipboard->mimetype, mimetype, sizeof(clipboard->mimetype) - 1); + clipboard->mimetype[sizeof(clipboard->mimetype) - 1] = '\0'; + + pthread_mutex_unlock(&(clipboard->lock)); + } void guac_common_clipboard_append(guac_common_clipboard* clipboard, const char* data, int length) { + pthread_mutex_lock(&(clipboard->lock)); + /* Truncate data to available length */ int remaining = clipboard->available - clipboard->length; if (remaining < length) @@ -131,5 +153,7 @@ void guac_common_clipboard_append(guac_common_clipboard* clipboard, const char* /* Update length */ clipboard->length += length; + pthread_mutex_unlock(&(clipboard->lock)); + } diff --git a/src/common/common/clipboard.h b/src/common/common/clipboard.h index 5ebb2617..c129a7c3 100644 --- a/src/common/common/clipboard.h +++ b/src/common/common/clipboard.h @@ -23,6 +23,7 @@ #include "config.h" #include +#include /** * The maximum number of bytes to send in an individual blob when @@ -35,6 +36,13 @@ */ typedef struct guac_common_clipboard { + /** + * Lock which restricts simultaneous access to the clipboard, guaranteeing + * ordered modifications to the clipboard and that changes to the clipboard + * are not allowed while the clipboard is being broadcast to all users. + */ + pthread_mutex_t lock; + /** * The mimetype of the contained clipboard data. */