Commit 81c6066f for guacamole.apache.org
commit 81c6066f1235b8689481b05a98a1ab257174b98e
Merge: 2b010738 4e776b73
Author: Virtually Nick <vnick@apache.org>
Date: Fri May 1 13:54:08 2026 -0400
Merge patch branch changes to main.
diff --cc src/protocols/vnc/clipboard.c
index aea0bcd2,3d4a400d..83334250
--- a/src/protocols/vnc/clipboard.c
+++ b/src/protocols/vnc/clipboard.c
@@@ -115,32 -102,49 +116,59 @@@ int guac_vnc_clipboard_blob_handler(gua
int guac_vnc_clipboard_end_handler(guac_user* user, guac_stream* stream) {
guac_vnc_client* vnc_client = (guac_vnc_client*) user->client->data;
+
+ /* Ignore end of stream if no clipboard structure is available to handle
+ * the data that was received */
+ guac_common_clipboard* clipboard = vnc_client->clipboard;
+ if (clipboard == NULL)
+ return 0;
+
rfbClient* rfb_client = vnc_client->rfb_client;
+ /* Send via VNC only if finished connecting */
+ if (rfb_client == NULL)
+ return 0;
+
+ /*
+ * Guacamole stores clipboard text as UTF-8. The clipboard-encoding
+ * setting only applies to the classic VNC clipboard path, where text
+ * must be converted from UTF-8 to the configured wire encoding.
+ *
+ * If clipboard-encoding is UTF-8, try the Extended Clipboard path first
+ * since it can send UTF-8 directly. Otherwise, or if that fails, fall
+ * back to classic clipboard conversion.
+ *
+ * Text coming back from the VNC server follows the same idea in reverse:
+ * classic clipboard text is decoded using clipboard-encoding, while
+ * Extended Clipboard text is already UTF-8.
+ */
+
+ const char* clipboard_encoding = vnc_client->settings->clipboard_encoding;
+ int use_utf8_clipboard = clipboard_encoding != NULL &&
+ strcmp(clipboard_encoding, "UTF-8") == 0;
+
+ if (use_utf8_clipboard) {
+ if (SendClientCutTextUTF8(rfb_client, vnc_client->clipboard->buffer,
+ vnc_client->clipboard->length))
+ return 0;
+ }
+
+ /* Fall back to classic clipboard with encoding conversion */
- char output_data[GUAC_COMMON_CLIPBOARD_MAX_LENGTH];
+ int output_buf_size = clipboard->available;
+ char* output_data = guac_mem_alloc(output_buf_size);
- const char* input = vnc_client->clipboard->buffer;
+ const char* input = clipboard->buffer;
char* output = output_data;
guac_iconv_write* writer = vnc_client->clipboard_writer;
/* Convert clipboard contents */
- guac_iconv(GUAC_READ_UTF8, &input, vnc_client->clipboard->length,
- writer, &output, sizeof(output_data));
+ guac_iconv(GUAC_READ_UTF8, &input, clipboard->length,
+ writer, &output, output_buf_size);
- /* Send via VNC only if finished connecting */
- if (rfb_client != NULL)
- SendClientCutText(rfb_client, output_data, output - output_data);
+ SendClientCutText(rfb_client, output_data, output - output_data);
+ guac_mem_free(output_data);
+
return 0;
}
@@@ -169,6 -172,31 +197,32 @@@ void guac_vnc_cut_text(rfbClient* clien
guac_common_clipboard_append(vnc_client->clipboard, received_data, output - received_data);
guac_common_clipboard_send(vnc_client->clipboard, gc);
+ guac_mem_free(received_data);
}
+ void guac_vnc_cut_text_utf8(rfbClient* client, const char* text, int textlen) {
+
+ guac_client* gc = rfbClientGetClientData(client, GUAC_VNC_CLIENT_KEY);
+ guac_vnc_client* vnc_client = (guac_vnc_client*) gc->data;
+
+ /* Ignore received text if outbound clipboard transfer is disabled */
+ if (vnc_client->settings->disable_copy)
+ return;
+
+ char received_data[GUAC_COMMON_CLIPBOARD_MAX_LENGTH];
+
+ const char* input = text;
+ char* output = received_data;
+
+ /* Extended clipboard always delivers UTF-8; iconv() here enforces
+ * GUAC_COMMON_CLIPBOARD_MAX_LENGTH and replaces invalid lead bytes
+ * with the Unicode replacement character (U+FFFD, ?) */
+ guac_iconv(GUAC_READ_UTF8, &input, textlen,
+ GUAC_WRITE_UTF8, &output, sizeof(received_data));
+
+ /* Send converted data */
+ guac_common_clipboard_reset(vnc_client->clipboard, "text/plain");
+ guac_common_clipboard_append(vnc_client->clipboard, received_data, output - received_data);
+ guac_common_clipboard_send(vnc_client->clipboard, gc);
+
+ }