Skip to content

fix: 使用 JSON 结构化序列化修复两端迁移完成列表不一致 (PMS #246975) - #779

Closed
LiHua000 wants to merge 1 commit into
linuxdeepin:release/v20from
LiHua000:agent/bugfix-leader/4c721b06
Closed

LiHua000 wants to merge 1 commit into
linuxdeepin:release/v20from
LiHua000:agent/bugfix-leader/4c721b06

Conversation

@LiHua000

@LiHua000 LiHua000 commented Aug 23, 2026 •

Copy link
Copy Markdown

修复:数据传输完成后两端迁移完成列表不一致 (PMS #246975)

根因

add_result 与 transfer_content 消息以空格作为字段分隔符,而 name/reason/filepath 均为含空格的翻译文本或文件路径。接收端按 split(" ") 严格校验字段数(add_result 要求 3 个、transfer_content 要求 4 个),含空格的值导致字段数不匹配,全部条目被 continue 丢弃。接收端完成列表为空/严重缺失,与发送端完整列表不一致。全部 11 处 addResult 的 reason 均含空格,缺陷 100% 必现。

修复方案(方案 A:JSON 结构化序列化)

改用 QJsonDocument 结构化序列化,两端格式严格同步,JSON 转义自动处理含空格/特殊字符的字段值。

add_result 通道:

  • 发送端 resultdisplay.cpp:以 QJsonArray 累积结果项(QJsonObject 含 name/success/reason),QJsonDocument::toJson(Compact) 序列化后发送,替代空格拼接的 processText
  • 接收端 transferworker.cpp:解析 JSON 数组,逐项提取字段,替代 split(";")/split(" ") + size()==3 校验

transfer_content 通道(同模式一并修复):

  • 发送端 transferringwidget.cpp:以 QJsonObject 序列化单条进度消息(type/content/progressbar/estimatedtime),替代空格拼接
  • 接收端 transferworker.cpp:解析 JSON 对象提取字段,替代 split(";")/split(" ") + size()==4 校验

边界情况

空字段、含空格/特殊字符的 name/reason/filepath、空列表、异步应用安装结果在发送前已包含等,均由 JSON 转义自动处理。

基线

  • 分支:release/v20
  • full-sha:570cb50b4f7bb810b9483e3277e2e5199add58c5

Summary by Sourcery

使用 JSON 结构化消息传输迁移结果和进度信息,确保包含空格及特殊字符的字段能够在两端正确同步。

Bug Fixes:

  • 修复数据传输过程中完成结果和传输进度消息因字段包含空格或特殊字符而被接收端丢弃,导致两端迁移完成列表不一致的问题。

Enhancements:

  • 将迁移结果和传输进度消息统一改为 JSON 结构化序列化与解析,提升消息字段传输的可靠性。

PMS bug #246975: 数据传输完成后两端迁移完成列表不一致

根因: add_result 与 transfer_content 通道以空格作为字段分隔符,
而 name/reason/filepath 均为含空格的翻译文本或文件路径,导致接收端
按 split(" ") 严格校验字段数时丢弃全部条目,接收端列表为空/缺失,
与发送端完整列表不一致。

修复方案 (方案 A): 改用 QJsonDocument 结构化序列化,两端格式严格同步。

- add_result 发送端 resultdisplay.cpp: 以 QJsonArray 累积结果,
  QJsonDocument 序列化后发送,替代 processText 空格拼接
- add_result 接收端 transferworker.cpp: 解析 JSON 数组取字段,
  替代 split(";")/split(" ") + size()==3 校验
- transfer_content 发送端 transferringwidget.cpp: 以 QJsonObject
  序列化单条进度消息,替代空格拼接
- transfer_content 接收端 transferworker.cpp: 解析 JSON 对象取字段,
  替代 split(";")/split(" ") + size()==4 校验

边界情况: 空字段、含空格/特殊字符的 name/reason/filepath、空列表、
异步应用安装结果在发送前已包含等,均由 JSON 转义自动处理。

基线: release/v20 @ 570cb50
@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: LiHua000

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

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @LiHua000, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@sourcery-ai

sourcery-ai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR replaces ad-hoc, space-delimited string protocols for migration result and progress messages with structured JSON serialization on both the GUI sender side and the transfer worker receiver side to fix dropped entries when fields contain spaces or special characters.

Sequence diagram for JSON migration result exchange

sequenceDiagram
    participant ResultDisplayWidget
    participant TransferHelper
    participant TransferHandle
    participant ReceiverUI

    ResultDisplayWidget->>ResultDisplayWidget: addResult(name, success, reason)
    ResultDisplayWidget->>TransferHelper: sendMessage(add_result, QJsonDocument::toJson(Compact))
    TransferHelper->>TransferHandle: add_result JSON array
    TransferHandle->>TransferHandle: QJsonDocument::fromJson()
    TransferHandle->>ReceiverUI: addResult(name, success, reason)
    TransferHandle->>ReceiverUI: transferFinished()
Loading

Sequence diagram for JSON transfer progress exchange

sequenceDiagram
    participant TransferringWidget
    participant TransferHelper
    participant TransferHandle
    participant ReceiverUI

    TransferringWidget->>TransferringWidget: updateProcess(type, content, progressbar, estimatedtime)
    TransferringWidget->>TransferHelper: sendMessage(transfer_content, QJsonDocument::toJson(Compact))
    TransferHelper->>TransferHandle: transfer_content JSON object
    TransferHandle->>TransferHandle: QJsonDocument::fromJson()
    TransferHandle->>ReceiverUI: transferContent(type, content, progressbar, estimatedtime)
Loading

File-Level Changes

Change Details Files
Use QJson-based structured serialization for the add_result channel instead of space-delimited strings.
  • Introduce QJsonDocument/QJsonObject/QJsonArray includes in the result display implementation.
  • Accumulate migration results in a QJsonArray of QJsonObjects with name/success/reason fields instead of appending to a QString buffer.
  • Serialize the result array to compact JSON when transfer finishes and send it via the add_result message.
  • Reset the stored results by reinitializing the QJsonArray in clear() instead of clearing a QString.
src/plugins/data-transfer/core/gui/transfer/resultdisplay.cpp
src/plugins/data-transfer/core/gui/transfer/resultdisplay.h
Use QJson-based structured serialization for transfer_content progress messages instead of space-delimited strings.
  • Include QJsonDocument/QJsonObject in the transferring widget implementation.
  • Build a QJsonObject with type/content/progressbar/estimatedtime for each progress update.
  • Serialize the progress object to compact JSON and send it via the transfer_content message on Linux instead of a concatenated QString.
src/plugins/data-transfer/core/gui/transfer/transferringwidget.cpp
Parse add_result and transfer_content messages as JSON on the receiver side instead of splitting strings and validating field counts.
  • Include QJsonDocument/QJsonObject/QJsonArray/QJsonValue in the transfer worker implementation.
  • For add_result, parse the incoming string as JSON, iterate the array of objects, and emit addResult with name/success/reason from each object, guarded by basic parse/no-array checks.
  • For transfer_content, parse the incoming string as JSON, read the single object, and emit transferContent with type/content/progressbar/estimatedtime fields, guarded by basic parse/no-object checks.
  • Remove the previous split(";")/split(" ")-based parsing and size() checks that caused entries with spaces to be discarded.
src/plugins/data-transfer/core/utils/transferworker.cpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@LiHua000

Copy link
Copy Markdown
Author

Duplicate of #780 — this PR was opened by a previous leader run that overstepped its role. The canonical fixer output is PR #780. Closing this duplicate.

@LiHua000 LiHua000 closed this Aug 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants