[
https://issues.apache.org/jira/browse/GUACAMOLE-2091?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Nick Couchman updated GUACAMOLE-2091:
-------------------------------------
Priority: Trivial (was: Major)
> Double-width Characters Rendering Problem (First Character Missing/Corrupted)
> when Pasting from Clipboard in SSH Terminal
> -------------------------------------------------------------------------------------------------------------------------
>
> Key: GUACAMOLE-2091
> URL: https://issues.apache.org/jira/browse/GUACAMOLE-2091
> Project: Guacamole
> Issue Type: Bug
> Components: guacamole-server
> Affects Versions: 1.6.0
> Reporter: orange-guo
> Priority: Trivial
> Attachments: image-2025-06-30-10-03-00-698.png,
> image-2025-06-30-10-04-04-535.png
>
>
> *Problem Description:*
> When pasting text containing Chinese characters from the clipboard into a
> Guacamole SSH terminal session, the very first Chinese character of the
> pasted text fails to render correctly (appears missing).
> Subsequent characters within the same pasted text, render correctly.
> !image-2025-06-30-10-04-04-535.png!
> *Steps to Reproduce:*
> * Connect to a remote machine via a SSH protocol.
> * Copy a string of Chinese characters (e.g., "我是人") from your local
> machine's clipboard.
> * Paste the copied text into the terminal session.
> * Observe the terminal display: the first Chinese character (e.g., "我") is
> not visible or is corrupted, while "是人" appears correctly.
> *Example Debug Logs (before fix, pasting "我是人" starting at `col=26`):*
> {code:java}
> guacd[...]: DEBUG: echo: Codepoint ready for processing: 0x6211 ('我')
> guacd[...]: DEBUG: echo: Calling guac_terminal_set for char 0x6211 at
> (39,26).
> guacd[...]: DEBUG: Rendering char: row=39, col=26, codepoint=0x6211 ('我'),
> width=2
> guacd[...]: DEBUG: set_columns: Primary set for row=39, cols=[26,27],
> char=0x6211('我'), width=2
> guacd[...]: DEBUG: display_set_columns: row=39, input_start_col=26,
> input_end_col=27, char_codepoint=0x6211 ('我'), char_width=2
> guacd[...]: DEBUG: display_set_columns: Starting loop to set columns from
> 26 to 27 (char_width=2).
> guacd[...]: DEBUG: display_set_columns: Processing col 26,
> current_op_type=0 (GUAC_CHAR_COPY=1)
> guacd[...]: DEBUG: display_set_columns: Set op for col 26: type=2,
> char_codepoint=0x6211.
> guacd[...]: DEBUG: display_set_columns: Marking unflushed_set for row 39.
> guacd[...]: DEBUG: set_columns: Cursor detected at row=39, col=26.
> Character width is 2.
> guacd[...]: DEBUG: set_columns: Redrawing cursor char. Original
> visible_cursor_col=26. Adjusted redraw range: [26,27].
> guacd[...]: DEBUG: display_set_columns: row=39, input_start_col=26,
> input_end_col=26, char_codepoint=0x6211 ('我'), char_width=2 # <--- This line
> caused the issue
> guacd[...]: DEBUG: display_set_columns: Starting loop to set columns from
> 26 to 26 (char_width=2).
> guacd[...]: DEBUG: display_set_columns: Processing col 26,
> current_op_type=2 (GUAC_CHAR_COPY=1)
> guacd[...]: DEBUG: display_set_columns: Set op for col 26: type=2,
> char_codepoint=0x6211.
> guacd[...]: DEBUG: display_set_columns: Marking unflushed_set for row 39.
> # ... (other characters '是', '人' processing - these were fine) ...
> guacd[...]: DEBUG: display_set_columns: row=39, input_start_col=26,
> input_end_col=26, char_codepoint=0x20 (' '), char_width=1 # <--- Final
> overwrite
> guacd[...]: DEBUG: display_set_columns: Starting loop to set columns from
> 26 to 26 (char_width=1).
> guacd[...]: DEBUG: display_set_columns: Processing col 26,
> current_op_type=2 (GUAC_CHAR_COPY=1)
> guacd[...]: DEBUG: display_set_columns: Set op for col 26: type=2,
> char_codepoint=0x20.
> guacd[...]: DEBUG: display_set_columns: Marking unflushed_set for row 39.
> {code}
>
> *Root Cause Analysis*
> The root cause lies in how terminal display logic handles *double-width
> characters* (like Chinese) when they overlap with the cursor, leading to
> inconsistent updates and eventual overwrites in the display buffer.
> *Proposed Solution:*
> The problem can be resolved by ensuring that the cursor redraw logic within
> {*}guac_{*}{*}terminal_set_columns{*} correctly accounts for the full width
> of multi-column characters. This ensures that the character's state in the
> display buffer remains consistent throughout all operations.
> File: terminal.c
> Function: guac_terminal_set_columns{*}{*}
> {code:java}
> void guac_terminal_set_columns(guac_terminal* terminal, int row,
> int start_column, int end_column, guac_terminal_char* character) {
> // Primary set for the character
> __guac_terminal_set_columns(terminal, row, start_column, end_column,
> character);
> // If visible cursor in current row, preserve state
> if (row == terminal->visible_cursor_row
> && terminal->visible_cursor_col >= start_column
> && terminal->visible_cursor_col <= end_column) {
> guac_terminal_char cursor_character = *character;
> cursor_character.attributes.cursor = true;
> // Correctly calculate the redraw range to cover the entire
> character width
> int cursor_redraw_start_col = terminal->visible_cursor_col;
> int cursor_redraw_end_col = terminal->visible_cursor_col +
> character->width - 1;
> // Ensure redraw range does not exceed the original set bounds
> if (cursor_redraw_start_col < start_column)
> cursor_redraw_start_col = start_column;
> if (cursor_redraw_end_col > end_column)
> cursor_redraw_end_col = end_column;
> // Re-submit the character with cursor attributes, covering its
> full width
> __guac_terminal_set_columns(terminal, row,
> cursor_redraw_start_col,
> cursor_redraw_end_col,
> &cursor_character);
> }
> } {code}
> I can create a pull request on Github to fix this issue later, if needed.
> Here is the screen screenshot after the problem was fixed
> !https://git.fastonetech.com:8443/-/project/401/uploads/fe322ac1b7eea72bb5ccb8b0a3a0c1ef/image.png!
>
--
This message was sent by Atlassian Jira
(v8.20.10#820010)