From 716012051a41788ccb92f63da9bcd3edd94d9b29 Mon Sep 17 00:00:00 2001 From: zhangsheng Date: Wed, 5 Aug 2026 15:03:27 +0800 Subject: [PATCH] fix: restrict path traversal check to file scheme in DEnumerator buildUrl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. DEnumeratorPrivate::buildUrl() 对所有 scheme 的文件名做路径遍历检查,导致 gio trash:/// 后端使用反斜杠分隔的扁平文件名被误判为恶意路径并返回空 URL; 2. 将路径遍历检查限制为仅对 file:/// 或无 scheme 的本地文件系统生效,gio trash:/// 等虚拟文件系统的合法文件名不受影响; 3. 修复手动分区场景下 /media 挂载点的回收站文件无法显示和清空的问题; Log: 修复 buildUrl 路径遍历安全检查误伤 gio trash 反斜杠文件名导致回收站无法显示和清空的问题 PMS: BUG-372733 Bug: https://pms.uniontech.com/bug-view-372733.html --- src/dfm-io/dfm-io/denumerator.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/dfm-io/dfm-io/denumerator.cpp b/src/dfm-io/dfm-io/denumerator.cpp index 36531169..ae8cf75e 100644 --- a/src/dfm-io/dfm-io/denumerator.cpp +++ b/src/dfm-io/dfm-io/denumerator.cpp @@ -451,10 +451,17 @@ QUrl DEnumeratorPrivate::buildUrl(const QUrl &url, const char *fileName) return QUrl(); } - // 拦截路径遍历攻击,防止恶意文件名越权 QByteArray fileNameBa(fileName); - if (fileNameBa.contains('/') || fileNameBa.contains('\\') || fileNameBa == "." || fileNameBa == "..") { - return QUrl(); + + // 路径遍历检查仅对本地文件系统 (file:/// 或无 scheme) 生效 + // gio 的 trash:/// 后端对非用户主目录挂载点的回收站文件,使用反斜杠分隔的扁平路径 + // 作为 GFileInfo 的 standard::name(例如 "\media\user\dev\.Trash-1000\files\x"), + // 这是合法的 trash 文件名而非恶意路径,故不应对其做路径遍历拦截。 + const QString scheme = url.scheme(); + if (scheme.isEmpty() || scheme == QLatin1String("file")) { + if (fileNameBa.contains("../") || fileNameBa.contains("..\\") || fileNameBa.startsWith("..")) { + return QUrl(); + } } QByteArray path;