GUACAMOLE-559: Guarantee ordered modification to the clipboard. Do not allow modification of clipboard while clipboard contents are being sent.

This commit is contained in:
Michael Jumper 2018-07-30 23:20:14 -07:00
parent 860a5fca8f
commit 4f25410aa9
2 changed files with 34 additions and 2 deletions

View File

@ -24,6 +24,7 @@
#include <guacamole/protocol.h> #include <guacamole/protocol.h>
#include <guacamole/stream.h> #include <guacamole/stream.h>
#include <guacamole/user.h> #include <guacamole/user.h>
#include <pthread.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@ -37,6 +38,8 @@ guac_common_clipboard* guac_common_clipboard_alloc(int size) {
clipboard->length = 0; clipboard->length = 0;
clipboard->available = size; clipboard->available = size;
pthread_mutex_init(&(clipboard->lock), NULL);
return clipboard; 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) { 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_log(client, GUAC_LOG_DEBUG, "Broadcasting clipboard to all connected users.");
guac_client_foreach_user(client, __send_user_clipboard, clipboard); guac_client_foreach_user(client, __send_user_clipboard, clipboard);
guac_client_log(client, GUAC_LOG_DEBUG, "Broadcast of clipboard complete."); 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; clipboard->length = 0;
/* Assign given mimetype */
strncpy(clipboard->mimetype, mimetype, sizeof(clipboard->mimetype) - 1); 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) { void guac_common_clipboard_append(guac_common_clipboard* clipboard, const char* data, int length) {
pthread_mutex_lock(&(clipboard->lock));
/* Truncate data to available length */ /* Truncate data to available length */
int remaining = clipboard->available - clipboard->length; int remaining = clipboard->available - clipboard->length;
if (remaining < length) if (remaining < length)
@ -131,5 +153,7 @@ void guac_common_clipboard_append(guac_common_clipboard* clipboard, const char*
/* Update length */ /* Update length */
clipboard->length += length; clipboard->length += length;
pthread_mutex_unlock(&(clipboard->lock));
} }

View File

@ -23,6 +23,7 @@
#include "config.h" #include "config.h"
#include <guacamole/client.h> #include <guacamole/client.h>
#include <pthread.h>
/** /**
* The maximum number of bytes to send in an individual blob when * The maximum number of bytes to send in an individual blob when
@ -35,6 +36,13 @@
*/ */
typedef struct guac_common_clipboard { 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. * The mimetype of the contained clipboard data.
*/ */