xpra icon
Bug tracker and wiki

Opened 3 months ago

Closed 3 months ago

#2109 closed defect (fixed)

HTML5 client clipboard doesn't fully support UTF-8

Reported by: cdrcnm Owned by: cdrcnm
Priority: major Milestone: 2.5
Component: html5 Version: 2.4.x
Keywords: Cc:

Description

The HTML5 client doesn't properly support pasting UTF-8 characters from remote to local.
Pasting UTF-8 characters display improper characters, for example the string "Каждый человек" display in the client as "Каждый человек"
The server is running XPRA v2.4.2 on Debian Stretch and the HTML5 client has the problem with v2.4.2 and trunk.
The browser used are Firefox and Chromium on Archlinux.
This bug doesn't happen when pasting from remote to local or with xpra attach.

When debugging I found that the string got the bad encoding during the call "client.send_clipboard_token(unescape(encodeURIComponent(paste_data)));" line 662 in index.html.

Attachments (1)

xpra_clipboard.txt (2.4 KB) - added by cdrcnm 3 months ago.

Download all attachments as: .zip

Change History (8)

Changed 3 months ago by cdrcnm

Attachment: xpra_clipboard.txt added

comment:1 Changed 3 months ago by Antoine Martin

Status: newassigned

The line:

client.send_clipboard_token(unescape(encodeURIComponent(paste_data)));

was added in r15512 for #1461.

You're saying "from remote to local" but this call is used for sending clipboard data from the browser (client) to the server - so this is confusing.
Where do you copy the string from? (another browser window? a terminal? does it make any difference?)
And where are you copying it into? (a terminal, a text editor?)


With "clipboard" debug enabled from the HTML5 client's connect page and -d clipboard on the server command line, I see:

  • when the client connects:
    2019-01-17 13:58:44,826 client ClientConnection(1 : Protocol(ws websocket: 127.0.0.1:10000 <- 127.0.0.1:60518)) is the clipboard peer, helper=GDKClipboardProtocolHelper
    2019-01-17 13:58:44,826  greedy=True
    2019-01-17 13:58:44,826  want targets=True
    2019-01-17 13:58:44,826  server has selections: CLIPBOARD, PRIMARY, SECONDARY
    2019-01-17 13:58:44,826  client initial selections: CLIPBOARD, PRIMARY
    2019-01-17 13:58:44,826 ClipboardProxy(CLIPBOARD).set_greedy_client(True)
    2019-01-17 13:58:44,826 ClipboardProxy(PRIMARY).set_greedy_client(True)
    2019-01-17 13:58:44,826 ClipboardProxy(SECONDARY).set_greedy_client(True)
    2019-01-17 13:58:44,826 set_want_targets_client(True)
    2019-01-17 13:58:44,826 enabling selections: CLIPBOARD, PRIMARY
    2019-01-17 13:58:44,826 ClipboardProxy(CLIPBOARD).set_enabled(True)
    2019-01-17 13:58:44,826 ClipboardProxy(PRIMARY).set_enabled(True)
    2019-01-17 13:58:44,826 ClipboardProxy(SECONDARY).set_enabled(False)
    

I copy your string Каждый человек from this browser (native), then when I paste it (control-v) into gedit running in xpra, I see:

  • browser log shows: paste event, data= Каждый человек
  • server log:
    2019-01-17 14:01:22,992 got token, selection=CLIPBOARD, targets=[], target data={'STRING': '\xd0\x9a\xd0\xb0\xd0\xb6\xd0\xb4\xd1\x8b\xd0\xb9 \xd1\x87\xd0\xb5\xd0\xbb\xd0\xbe\xd0\xb2\xd0\xb5\xd0\xba'}, claim=False, can-receive=True
    2019-01-17 14:01:22,993 clipboard CLIPBOARD set to ''\xd0\x9a\xd0\xb0\xd0\xb6\xd0\xb4\xd1\x8b\xd0\xb9 \xd1\x87\xd0\xb5\xd0\xbb\xd0\xbe\xd0\xb2\xd0\xb5\xd0\xba''
    2019-01-17 14:01:22,993 token packet without claim, not setting the token flag
    2019-01-17 14:01:22,994 clipboard: CLIPBOARD owner_changed, enabled=True, can-send=True, can-receive=True, have_token=False, greedy_client=True, block_owner_change=True
    2019-01-17 14:01:22,995 remove_block: CLIPBOARD
    

So it looks like that this line was meant to convert the unicode string we get from the browser into a UTF8 byte array.
But there are two problems:

  • it doesn't do that!
  • we still send the string as STRING rather than UTF8 so the server and the client application running there may not interpret it correctly

comment:2 Changed 3 months ago by cdrcnm

Sorry I made a mistake. It was from local to remote, from the client to the server. Copying from the server to my computer works properly.

The applications doesn't make any differences. I tried with a text editor, a browser window, a terminal and a Qt application, both on remote(xpra server) and local(my computer) and the result is always the same.

comment:3 Changed 3 months ago by Antoine Martin

Owner: changed from Antoine Martin to cdrcnm
Status: assignednew

Turns out that fixing (2) is enough: r21379 works for me.

@cdrcnm: if this works for you, please close this ticket.

comment:4 Changed 3 months ago by cdrcnm

It's working, but only with a server compiled from trunk.
With the server in version 2.4.2 (.deb package) or 2.4.x and client up-to-date the bug is still present.

The log:

2019-01-17 15:56:40,698 clipboard_nesting_check(receiving, clipboard-token, ClientConnection(1 : Protocol(ws websocket: 172.17.0.4:14500 <- 172.16.15.10:46764)))
2019-01-17 15:56:40,699 process clipboard handler(clipboard-token)=<bound method GDKClipboardProtocolHelper._process_clipboard_token of GDKClipboardProtocolHelper>
2019-01-17 15:56:40,699 process clipboard token selection=CLIPBOARD, local clipboard name=CLIPBOARD, proxy=ClipboardProxy(CLIPBOARD)
2019-01-17 15:56:40,699 wire selection to raw, encoding=bytes, type=UTF8_STRING, format=28, len(data)=28
2019-01-17 15:56:40,699 got token, selection=CLIPBOARD, targets=[], target data={'UTF8_STRING': '\xd0\x9a\xd0\xb0\xd0\xb6\xd0\xb4\xd1\x8b\xd0\xb9 \xd1\x87\xd0\xb5\xd0\xbb\xd0\xbe\xd0\xb2\xd0\xb5\xd0\xba '}, claim=False, can-receive=True
2019-01-17 15:56:40,699 clipboard CLIPBOARD set to ''\xd0\x9a\xd0\xb0\xd0\xb6\xd0\xb4\xd1\x8b\xd0\xb9 \xd1\x87\xd0\xb5\xd0\xbb\xd0\xbe\xd0\xb2\xd0\xb5\xd0\xba ''
2019-01-17 15:56:40,699 clear_func(<gtk.Clipboard object at 0x7f171c903fa0 (GtkClipboard at 0x563b40b1e2a0)>, None) value=Каждый человек
2019-01-17 15:56:40,700 token packet without claim, not setting the token flag
2019-01-17 15:56:40,700 clipboard: CLIPBOARD owner_changed, enabled=True, can-send=True, can-receive=True, have_token=False, greedy_client=True, block_owner_change=True
2019-01-17 15:56:40,700 remove_block: CLIPBOARD
2019-01-17 15:56:40,742 get_func(<gtk.Clipboard object at 0x7f171c903fa0 (GtkClipboard at 0x563b40b1e2a0)>, <GtkSelectionData at 0x7ffc223856e0>, 0, None) value=Каждый человек
2019-01-17 15:56:40,762 get_func(<gtk.Clipboard object at 0x7f171c903fa0 (GtkClipboard at 0x563b40b1e2a0)>, <GtkSelectionData at 0x7ffc223856e0>, 0, None) value=Каждый человек

comment:5 Changed 3 months ago by cdrcnm

I checked the code changes and run a few tests. This fix works since this commit: r21134 so backporting it to 2.4.x require more changes.

Last edited 3 months ago by Antoine Martin (previous) (diff)

comment:6 Changed 3 months ago by Antoine Martin

Please try r21383.

comment:7 Changed 3 months ago by cdrcnm

Resolution: fixed
Status: newclosed

It's working.

Note: See TracTickets for help on using tickets.