Skip to content

fix(wallpaper): show video previews#3351

Open
mhduiy wants to merge 1 commit into
linuxdeepin:masterfrom
mhduiy:fixdisplaywallpaper
Open

fix(wallpaper): show video previews#3351
mhduiy wants to merge 1 commit into
linuxdeepin:masterfrom
mhduiy:fixdisplaywallpaper

Conversation

@mhduiy

@mhduiy mhduiy commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • show packaged or cached thumbnails for video wallpapers in display previews
  • share thumbnail cache and generation logic with the personalization plugin
  • generate cache files atomically and ignore stale asynchronous results

Verification

  • cmake --build build --target display personalization -j6
  • ./build/bin/dcc-wallpaper-utils-test --gtest_color=no (2 tests passed)

PMS: BUG-367369

@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 @mhduiy, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@mhduiy

mhduiy commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

/test github-pr-review-ci

@mhduiy

mhduiy commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

/test "Call CLA check / clacheck / CLAssistant (pull_request_target)"

@deepin-ci-robot

Copy link
Copy Markdown

@mhduiy: The specified target(s) for /test were not found.
The following commands are available to trigger required jobs:

  • /test deepin-auto-translation
  • /test github-pr-review-ci

Use /test all to run the following jobs that were automatically triggered:

  • github-pr-review-ci
Details

In response to this:

/test "Call CLA check / clacheck / CLAssistant (pull_request_target)"

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.

@mhduiy

mhduiy commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

/test "Call CLA check"

@deepin-ci-robot

Copy link
Copy Markdown

@mhduiy: The specified target(s) for /test were not found.
The following commands are available to trigger required jobs:

  • /test deepin-auto-translation
  • /test github-pr-review-ci

Use /test all to run the following jobs that were automatically triggered:

  • github-pr-review-ci
Details

In response to this:

/test "Call CLA check"

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.

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: caixr23, mhduiy

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

@mhduiy

mhduiy commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

/merge

@deepin-bot

deepin-bot Bot commented Jul 13, 2026

Copy link
Copy Markdown

This pr cannot be merged! (status: behind)

1. Resolve packaged and cached video thumbnails for display previews.
2. Generate shared thumbnail caches with atomic temporary files.
3. Reuse the common thumbnail utility in the personalization provider.
4. Prevent stale asynchronous results from replacing newer wallpapers.

Log: Fix missing video wallpaper previews in display settings.

fix(wallpaper): 显示视频壁纸预览

1. 为显示预览读取壁纸包缩略图和视频缩略图缓存。
2. 通过临时文件原子生成并复用公共缩略图缓存。
3. 在个性化壁纸提供者中复用公共缩略图工具。
4. 防止过期异步结果覆盖后来设置的壁纸。

Log: 修复显示设置中缺少视频壁纸预览的问题。
PMS: BUG-367369
@mhduiy mhduiy force-pushed the fixdisplaywallpaper branch from f48803d to 6e02e8f Compare July 13, 2026 12:40
@mhduiy

mhduiy commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

/test github-pr-review-ci

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

★ 总体评分:55分

■ 【总体评价】

代码实现了视频壁纸缩略图公共库的抽取与显示模块集成,消除了重复逻辑,但存在路径遍历安全漏洞。
逻辑正确但因路径遍历风险导致评分受限,且解析逻辑存在重复。

■ 【详细分析】

  • 1.语法逻辑(基本正确)✓

DisplayWorker::resolveVideoThumbnailDccWallpaperThumbnail::generate 的核心逻辑完整,临时文件机制保证了写入原子性,QPointer 的使用防止了异步回调时的悬空指针访问。
潜在问题:在 videoThumbnailReady 槽函数中,若 thumbnailPath 为空,直接 return 会导致 m_videoWallpaperMonitors 中的记录被移除但未更新壁纸状态,可能使界面停留在原始视频路径;resolveVideoThumbnail 中未对 monitor 指针进行空指针检查。
建议:在 videoThumbnailReady 中处理生成失败的情况,尝试恢复默认壁纸或记录错误日志;在将 monitor 加入列表前增加空指针校验。

  • 2.代码质量(良好)✓

提取 dcc-wallpaper-utils 公共库有效消除了 plugin-personalizationplugin-display 之间的重复代码,命名规范清晰,错误处理使用 qWarningqCWarning 记录日志。
潜在问题:DisplayWorker::resolveVideoThumbnail 中解析 metadata.json 的逻辑与 plugin-personalization 中的解析逻辑高度重复,未实现完全复用;DccWallpaperThumbnail::generate 中多次调用 QFileInfo(outputPath).size() > 0 存在冗余。
建议:将 metadata.json 的解析逻辑也下沉到 dcc-wallpaper-utils 库中;缓存 QFileInfo 结果以减少重复对象构造。

  • 3.代码性能(无性能问题)✓

缩略图生成任务通过 QtConcurrent::run 在后台线程执行,不阻塞主线程;缓存机制避免了重复生成;对同一视频的多次请求通过 m_videoWallpaperMonitors 进行了合并处理。
潜在问题:每次调用 resolveVideoThumbnail 都会重新读取并解析 metadata.json 文件,在频繁更新壁纸时会产生不必要的 I/O 开销。
建议:考虑对 metadata.json 的解析结果进行内存缓存,监听文件变化时更新。

  • 4.代码安全(存在 1 个安全漏洞)✕

漏洞对比统计:新增漏洞 1 个,减少漏洞 0 个,持平 0 个
总体风险描述:在解析 metadata.json 获取缩略图路径时,未对相对路径进行安全校验,可能导致路径遍历,读取系统任意文件。

  • 安全漏洞1(【中危】):路径遍历 在 DisplayWorker::resolveVideoThumbnail 中,metadata.json 中的 thumbnail 字段直接通过 liveDir.absoluteFilePath(thumbnailRel) 拼接路径,未校验是否包含 ../ 等目录跳转字符。攻击者若能篡改 metadata.json,可使 thumbAbsPath 指向系统任意文件(如 /etc/passwd),导致敏感信息泄露或加载恶意文件作为壁纸。——非常重要

  • 建议:使用 QDir::cleanPath 清理路径后,检查结果是否仍位于 liveDir 目录内,若不在则拒绝访问。

■ 【改进建议代码示例】

// 修复 DisplayWorker::resolveVideoThumbnail 中的路径遍历漏洞
QString DisplayWorker::resolveVideoThumbnail(const QString &videoPath, Monitor *monitor)
{
    QDir liveDir(SysLiveWallpaperDir);
    if (liveDir.exists()) {
        QFile metaFile(liveDir.absoluteFilePath("metadata.json"));
        if (metaFile.open(QIODevice::ReadOnly)) {
            QJsonParseError parseErr;
            QJsonDocument doc = QJsonDocument::fromJson(metaFile.readAll(), &parseErr);
            metaFile.close();
            if (parseErr.error != QJsonParseError::NoError || !doc.isArray()) {
                qCWarning(DdcDisplayWorker) << "metadata.json parse error:" << parseErr.errorString();
            } else {
                for (const auto &entry : doc.array()) {
                    QJsonObject obj = entry.toObject();
                    QString videoAbsPath = liveDir.absoluteFilePath(obj.value("path").toString());
                    if (videoAbsPath == videoPath) {
                        QString thumbnailRel = obj.value("thumbnail").toString();
                        if (!thumbnailRel.isEmpty()) {
                            // 修复路径遍历:确保拼接后的路径仍在 liveDir 目录下
                            QString thumbAbsPath = liveDir.absoluteFilePath(thumbnailRel);
                            QString cleanedPath = QDir::cleanPath(thumbAbsPath);
                            QString cleanedLiveDir = QDir::cleanPath(liveDir.absolutePath());
                            
                            if (cleanedPath.startsWith(cleanedLiveDir + "/") && QFile::exists(cleanedPath)) {
                                return cleanedPath;
                            } else {
                                qCWarning(DdcDisplayWorker) << "Invalid thumbnail path detected:" << thumbnailRel;
                            }
                        }
                        break;
                    }
                }
            }
        }
    }

    const QString cachePath = DccWallpaperThumbnail::cachePath(videoPath);

    if (QFile::exists(cachePath)) {
        return cachePath;
    }

    if (monitor && m_videoWallpaperMonitors.contains(videoPath)) {
        m_videoWallpaperMonitors[videoPath].append(monitor);
        return videoPath;
    }

    if (monitor) {
        m_videoWallpaperMonitors[videoPath] = { monitor };
    }

    QPointer<DisplayWorker> guard(this);
    (void)QtConcurrent::run([guard, videoPath]() {
        const QString thumbnailPath = DccWallpaperThumbnail::generate(videoPath);
        if (guard)
            Q_EMIT guard->videoThumbnailReady(videoPath, thumbnailPath);
    });

    return videoPath;
}

// 修复 videoThumbnailReady 槽函数中的逻辑瑕疵
// 在构造函数中连接的 lambda
connect(this, &DisplayWorker::videoThumbnailReady, this, [this](const QString &videoPath, const QString &thumbnailPath) {
    const auto monitors = m_videoWallpaperMonitors.take(videoPath);
    if (thumbnailPath.isEmpty()) {
        qCWarning(DdcDisplayWorker) << "Failed to generate thumbnail for:" << videoPath;
        // 可选:在此处恢复默认壁纸或进行其他错误处理
        return;
    }

    for (const auto &monitor : monitors) {
        if (monitor && monitor->wallpaper() == videoPath)
            monitor->setWallpaper(thumbnailPath);
    }
});

@deepin-ci-robot

Copy link
Copy Markdown

@mhduiy: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
github-pr-review-ci 6e02e8f link true /test github-pr-review-ci

Full PR test history. Your PR dashboard.

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. I understand the commands that are listed here.

@deepin-bot

deepin-bot Bot commented Jul 16, 2026

Copy link
Copy Markdown

TAG Bot

New tag: 6.1.100
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #3354

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.

3 participants