Skip to content

fix: handle UTF-8 text in basic ClientCutText path to fix clipboard garbled text - #8

Open
liyigang1 wants to merge 1 commit into
deepin-community:masterfrom
liyigang1:master
Open

liyigang1 wants to merge 1 commit into
deepin-community:masterfrom
liyigang1:master

Conversation

@liyigang1

Copy link
Copy Markdown

Root Cause Analysis

When a VNC client sends clipboard text via the basic ClientCutText message (used by TightVNC, UltraVNC, and many other clients that lack Extended Clipboard support), the server in rfbserver.c always routes it to setXCutText — the Latin-1 handler — without checking the actual text encoding. Clients that send UTF-8 encoded Chinese text through this basic path have their multi-byte UTF-8 sequences split into individual Latin-1 characters, producing garbled output on the server side. The Extended Clipboard extension path (rfbserver.c:2197-2198) correctly calls setXCutTextUTF8, but it only activates when setXCutTextUTF8 is non-NULL (default NULL in main.c:1044) and the client declares support — conditions often unmet.

Fix

Two changes: (1) In the basic ClientCutText path (rfbserver.c), when setXCutTextUTF8 is available, validate the received text with a new rfbIsValidUTF8() function; if valid UTF-8, route to setXCutTextUTF8 instead of setXCutText, otherwise fall back to the Latin-1 handler. (2) In rfbGetScreen() (main.c), detect whether the system locale uses UTF-8 via nl_langinfo(CODESET); if so, install rfbDefaultSetXCutTextUTF8 (which delegates to setXCutText) as the default callback instead of NULL, enabling both Extended Clipboard negotiation and basic-path UTF-8 detection without requiring the application to explicitly set the callback.

Change Safety Assessment

Code Safety

  • Risk Level: Low
  • Target code originates from the initial import commit (upstream 0.9.15), not a previous bug fix — this change does not revert any historical fix.
  • The new conditional branch only activates when setXCutTextUTF8 is non-NULL (UTF-8 systems); the default callback is a pure delegation to setXCutText with null guards. Non-UTF-8 systems and NULL-callback scenarios behave exactly as before.

Business Impact Scope

Affects VNC clipboard text reception on the server side. Specifically: when users copy text containing non-ASCII characters (e.g., Chinese) from a VNC client to a UOS VNC server, the server now correctly handles UTF-8 encoded text. All scenarios that previously worked (ASCII-only text, Extended Clipboard clients) remain unaffected.

Verification Suggestion

Test copying Chinese text from both Windows VNC clients (TightVNC/UltraVNC) and UOS VNC clients to a UOS VNC server — verify pasted text is correct, not garbled. Also test copying ASCII-only text to confirm no regression.


根因分析

当 VNC 客户端通过基本 ClientCutText 消息发送剪贴板文本时(TightVNC、UltraVNC 等不支持 Extended Clipboard 的客户端使用此路径),服务端在 rfbserver.c 中始终调用 setXCutText(Latin-1 处理器),不检测文本实际编码。通过此基本路径发送 UTF-8 编码中文的客户端,其多字节 UTF-8 序列被拆分为多个 Latin-1 字符,在服务端产生乱码。Extended Clipboard 扩展路径(rfbserver.c:2197-2198)正确调用 setXCutTextUTF8,但仅在 setXCutTextUTF8 非 NULL(默认 NULL)且客户端声明支持时才启用——这些条件常常不满足。

修复方案

两处改动:(1)在基本 ClientCutText 路径(rfbserver.c)中,当 setXCutTextUTF8 可用时,用新增的 rfbIsValidUTF8() 函数验证接收到的文本;若为合法 UTF-8,则调用 setXCutTextUTF8 而非 setXCutText,否则回退到 Latin-1 处理器。(2)在 rfbGetScreen()(main.c)中,通过 nl_langinfo(CODESET) 检测系统是否使用 UTF-8 编码;若是,则安装 rfbDefaultSetXCutTextUTF8(委托给 setXCutText)作为默认回调而非 NULL,使 Extended Clipboard 协商和基本路径 UTF-8 检测无需应用显式设置回调即可生效。

改动安全评估

代码安全评估

  • 风险等级: 低风险
  • 目标代码源自初始导入 commit(上游 0.9.15),非之前 bug 修复产物——本次改动不撤销任何历史修复。
  • 新增条件分支仅在 setXCutTextUTF8 非 NULL(UTF-8 系统)时生效;默认回调为对 setXCutText 的纯委托并带空指针保护。非 UTF-8 系统和 NULL 回调场景行为与原来完全一致。

业务影响范围

影响 VNC 服务端剪贴板文本接收。具体为:用户从 VNC 客户端向 UOS VNC 服务端复制包含非 ASCII 字符(如中文)的文本时,服务端现在能正确处理 UTF-8 编码文本。此前正常工作的场景(纯 ASCII 文本、Extended Clipboard 客户端)不受影响。

验证建议

测试从 Windows VNC 客户端(TightVNC/UltraVNC)和 UOS VNC 客户端向 UOS VNC 服务端复制中文文本——验证粘贴文本正确无乱码。同时测试纯 ASCII 文本复制,确认无回归。

@deepin-ci-robot

Copy link
Copy Markdown
Contributor

Hi @liyigang1. Thanks for your PR. 😃

@deepin-ci-robot

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign xzl01 for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@deepin-ci-robot

Copy link
Copy Markdown
Contributor

Hi @liyigang1. Thanks for your PR.

I'm waiting for a deepin-community member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

…arbled text

Use quilt patch (debian/patches/0003_fix-utf8-clipboard-text.patch) instead
of direct source modification, and add Debian changelog entry.

When a VNC client sends text via the basic ClientCutText message (as
opposed to the Extended Clipboard extension), the server always called
setXCutText (the Latin-1 handler) without checking the actual encoding.
Many VNC clients send UTF-8 encoded text through this basic path, causing
multi-byte UTF-8 sequences to be treated as individual Latin-1 characters
and producing garbled text on the server side.

This fix adds two changes:

1. UTF-8 detection in the basic ClientCutText path (rfbserver.c):
   When setXCutTextUTF8 callback is available, validate the received text
   as UTF-8. If valid, route to setXCutTextUTF8 instead of setXCutText.
   ASCII text (also valid Latin-1) is unaffected. Non-UTF-8 Latin-1 text
   correctly falls back to setXCutText.

2. Default setXCutTextUTF8 callback on UTF-8 systems (main.c):
   When the system locale uses UTF-8 encoding (detected via
   nl_langinfo(CODESET)), install rfbDefaultSetXCutTextUTF8 as the default
   callback instead of NULL. This default delegates to setXCutText, enabling
   Extended Clipboard negotiation and basic-path UTF-8 detection without
   requiring the application to explicitly set the callback.
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown

TAG Bot

TAG: 0.9.15+dfsg-1+deb13u1deepin1
EXISTED: no
DISTRIBUTION: deepin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants