[ 
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)

Reply via email to