Repository navigation
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: add-uos The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Reviewer's GuideThis PR integrates a read-only Linglong layer/UAB archive plugin, implementing bounded native parsing of layer headers and ELF section metadata, EROFS extraction via the external fsck.erofs fallback, archive browsing and selective extraction behavior, MIME/association registration, and a Qt 6 plugin-loader compatibility fix. Sequence diagram for Linglong package preview and extractionsequenceDiagram
participant User
participant Compressor
participant LayerPlugin
participant Parser
participant FsckErofs
participant FileSystem
User->>Compressor: open Linglong package
Compressor->>LayerPlugin: list()
LayerPlugin->>Parser: parseHeader()
alt layer package
Parser->>Parser: parseLayerHeader()
else ELF UAB package
Parser->>Parser: parseUabHeader()
end
Parser-->>LayerPlugin: EROFS offset and size
LayerPlugin->>FileSystem: copyPayload()
LayerPlugin->>FsckErofs: --extract=destDir bundle.erofs
FsckErofs-->>LayerPlugin: extracted files
LayerPlugin->>LayerPlugin: collectEntries()
LayerPlugin-->>Compressor: archive entries
Compressor-->>User: preview contents
User->>Compressor: extract selected files
Compressor->>LayerPlugin: extractFiles()
LayerPlugin->>FsckErofs: --extract=stagingDir bundle.erofs
FsckErofs-->>LayerPlugin: staged contents
LayerPlugin->>FileSystem: moveStagedToTarget()
FileSystem-->>Compressor: extraction result
Compressor-->>User: extraction complete
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 3 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="3rdparty/clilllayerplugin/clilllayerplugin.cpp" line_range="545-556" />
<code_context>
+ return false;
+ }
+ if (countByItems) {
+ m_qDoneSize += 1;
+ } else {
+ m_qDoneSize += QFileInfo(pair.first).isDir() ? 0 : QFileInfo(pair.first).size();
+ }
+ emit signalprogress(100.0 * m_qDoneSize / m_qTotalSize);
+ }
</code_context>
<issue_to_address>
**issue (bug_risk):** After `moveToDest()` succeeds by renaming an entry, the source path no longer exists, so `QFileInfo(pair.first).size()` returns zero and the progress counter never advances for file payloads. Extraction completes while the progress signal remains below 100%.
**Triggers:** When the staged directory and destination are on the same filesystem and files are moved by rename.
**Suggested fix:** Capture each entry's size before calling `moveToDest()` and use that saved value for progress accounting.
```suggestion
for (const auto &pair : moveList) {
emit signalCurFileName(QFileInfo(pair.first).fileName());
const qint64 entrySize = QFileInfo(pair.first).isDir() ? 0 : QFileInfo(pair.first).size();
if (!moveToDest(pair.first, pair.second)) {
return false;
}
if (countByItems) {
m_qDoneSize += 1;
} else {
m_qDoneSize += entrySize;
}
emit signalprogress(100.0 * m_qDoneSize / m_qTotalSize);
}
```
</issue_to_address>
### Comment 2
<location path="3rdparty/clilllayerplugin/clilllayerplugin.cpp" line_range="162" />
<code_context>
+ quint64 *size) -> bool {
+ for (int i = 0; i < shnum; ++i) {
+ const uchar *sh = shdrAt(i);
+ const quint32 nameOff = qFromLittleEndian<quint32>(sh); // sh_name
+ if (nameOff >= static_cast<quint32>(shstrtab.size())) {
+ continue;
+ }
+ const QByteArray secName = shstrtab.constData() + nameOff;
+ if (secName != name) {
+ continue;
</code_context>
<issue_to_address>
**🚨 issue (security):** `QByteArray secName = shstrtab.constData() + nameOff` constructs an unbounded C string from attacker-controlled ELF section-name data. If the string table has no NUL terminator after `nameOff`, parsing reads past the QByteArray allocation and can crash or trigger an out-of-bounds read on malformed UAB input.
**Triggers:** When a malformed ELF has a valid in-range section-name offset but no NUL terminator in the remaining string table.
**Suggested fix:** Bound the lookup to the remaining string-table length, for example by locating NUL with `memchr` before constructing the QByteArray.
```suggestion
const int nameEnd = shstrtab.indexOf('\0', static_cast<int>(nameOff));
if (nameEnd < 0) {
continue;
}
const QByteArray secName = shstrtab.mid(static_cast<int>(nameOff), nameEnd - static_cast<int>(nameOff));
```
</issue_to_address>
### Comment 3
<location path="3rdparty/clilllayerplugin/clilllayerplugin.cpp" line_range="464-465" />
<code_context>
+ }
+ srcFile.unsetError();
+ if (srcInfo.isSymLink()) {
+ // 注:symLinkTarget() 返回绝对路径,相对链接在回退路径下会转为绝对
+ if (QFile::link(srcInfo.symLinkTarget(), dst)) {
+ return true;
+ }
</code_context>
<issue_to_address>
**issue (broader_impact):** The fallback path recreates a relative archive symlink using `symLinkTarget()`, which resolves it to an absolute path under the staging directory. Once the temporary staging directory is removed, the extracted symlink points at the deleted staging path instead of retaining its original relative target.
**Triggers:** When renaming the staged symlink fails and the QFile::link fallback is used.
**Suggested fix:** Read and recreate the symlink's original link text rather than its resolved absolute target.
</issue_to_address>88abd37 to
a66d7b5
Compare
Add a read-only kerfuffle plugin for linglong layer/uab packages, parsing the official container formats directly and extracting the embedded EROFS image with fsck.erofs, so no linglong package is required. layer: 40-byte magic + meta JSON + EROFS payload; uab: ELF64 container, locate the bundle section via linglong.meta JSON. Register the vnd.linglong.layer mimetype and add association checkboxes; uab files keep the official vnd.linyaps.uab type registered by linglong-bin, so no self-made uab type is needed and no icon override is applied (generic file icons are kept). Also fix KPluginLoader for Qt6 where QLibrary state is not shared with QPluginLoader. uab is detected inside the app via the linglong.meta ELF section since plain mime magic would hijack all ELF executables. 新增玲珑 layer/uab 只读解压插件:直接解析官方容器格式并用 fsck.erofs 解压内嵌 EROFS 镜像,不依赖玲珑软件包。layer 为 40 字节魔数 + 元信息 JSON + EROFS 载荷;uab 为 ELF64 容器, 经 linglong.meta JSON 定位 bundle section。注册 vnd.linglong.layer mimetype 并新增文件关联勾选项;uab 保持 官方 linglong-bin 注册的 vnd.linyaps.uab 类型,不自造 uab 类型也不覆盖图标(保留通用文件图标)。修复 Qt6 下 KPluginLoader 与 QPluginLoader 不共享加载状态导致的断言问题。 应用内通过 linglong.meta ELF section 精确识别 uab,避免 magic 误伤所有可执行文件。 Log: 新增玲珑 layer/uab 包的预览与解压支持 Influence: 无 ll-builder/linglong 环境也能预览解压 layer/uab; Qt6 调试构建下插件加载断言修复。
a66d7b5 to
8496788
Compare
deepin pr auto reviewAI 代码审查报告
总体评价总分: 96 / 100 (优秀) 本 PR 为 deepin-compressor 添加玲珑(linglong)layer 和 uab 包格式的只读插件支持,实现了包格式解析、EROFS 载荷提取、文件列表预览和解压功能。代码质量优秀,安全防护完善,二进制格式解析有严格的边界检查和整数溢出防护,与 commit 目的完全一致。 漏洞统计
漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个 四维度评分维度1: 语法逻辑 ✓ (25/25)
分析内容: 本 PR 新增了 clilllayerplugin 插件,实现了玲珑 layer/uab 包的格式解析与解压功能。代码逻辑清晰,各函数职责明确:
无编译错误,无内存泄漏,无空指针风险,无竞态条件。 维度2: 代码质量 ✓ (22/25)
分析内容: 注释完整性(5/5): clilllayerplugin.h 中每个函数都有完整的 Doxygen 风格注释,包含 @brief、@PARAM、@return;clilllayerplugin.cpp 中有详细的二进制格式布局注释;mimetypes.cpp 中 elfContainsSection 有完整的函数说明注释。类级别注释解释了 layer/uab 格式布局,对齐官方实现。 代码重复(2/5): ELF64 头解析逻辑在 结构合理性(5/5): 函数长度适中,最长函数 调试信息清理(5/5): 改进建议: // 建议提取 ELF 解析为公共工具函数,减少重复
// 例如在 interface 层新增 ElfParser 工具类
class ElfParser {
public:
static bool containsSection(const QString &path, const QByteArray §ionName);
static bool findSection(QFile &file, const QByteArray &name,
quint64 *offset, quint64 *size, QString *errOut);
};
// clilllayerplugin.cpp 和 mimetypes.cpp 均可复用维度3: 代码性能 ✓ (19/20)
分析内容: 算法复杂度: 所有解析函数复杂度合理—— 资源管理: QTemporaryDir 自动清理临时目录,QProcess 有10分钟超时保护, 已知限制: 轻微优化空间: // 优化建议:复用 QFileInfo 对象
for (const QString &name : itemsToMove) {
const QString src = srcRoot + QLatin1Char('/') + name;
const QString dst = targetPath + QLatin1Char('/') + name;
const QFileInfo srcInfo(src); // 只创建一次
m_qTotalSize += srcInfo.isDir() ? 0 : srcInfo.size();
moveList << qMakePair(src, dst);
}
// ...
for (const auto &pair : moveList) {
const QFileInfo srcInfo(pair.first); // 只创建一次
const qint64 entrySize = srcInfo.isDir() ? 0 : srcInfo.size();
// ...
}维度4: 代码安全 ✓ (30/30)
分析内容: 命令注入防护: 缓冲区溢出防护:
路径遍历防护:
拒绝服务防护:
整数安全: 信息泄露: 无硬编码密钥或敏感信息,日志仅输出文件路径和操作状态,符合桌面应用规范。 修改文件清单
审查结论本 PR 代码质量优秀,为 deepin-compressor 添加了完整的玲珑 layer/uab 包只读插件支持。代码实现了二进制格式解析(layer 魔数 + uab ELF64 容器)、EROFS 载荷提取(fsck.erofs 解压)、文件列表预览和解压功能。安全防护完善,包含命令注入防护、缓冲区溢出防护、整数溢出检查、路径遍历防护和拒绝服务防护。与 commit 目的"add linglong layer and uab package support"完全一致。建议合并。 |
|
TAG Bot New tag: 6.5.35 |
功能说明
新增玲珑(linglong)
layer/uab软件包的只读解压插件kerfuffle_clilllayer,压缩包管理器可以直接预览和解压玲珑包。实现方式
复刻官方 linglong 库(linyaps
libs/linglong)的容器解析逻辑,不再依赖ll-builder/ll-cli:[40B 魔数][4B LE 长度][LayerInfo JSON][EROFS 载荷至文件尾],对齐官方LayerFile::binaryDataOffset()linglong.metasection(JSON)中sections.bundle指向的 EROFS section,对齐官方UABFile::unpack()fsck.erofs --extract解压(与官方 LayerPackager/UABFile 无 erofsfuse 时的回退路径一致),仅需系统安装 erofs-utils,无 root / 挂载要求mimetype 注册
application/vnd.linglong.layer:glob*.layer+ 40 字节魔数 magicapplication/vnd.linglong.uab:仅 glob*.uab(uab 本质是 ELF 容器,注册 ELF magic 会误伤所有可执行文件)determineMimeType()通过 ELFlinglong.metasection 特征精确识别 uab,使用inherits(x-executable)兼容 PIE 等子类型判定其他
KPluginLoader::load()中Q_ASSERT(lib.isLoaded())误触发(Qt6 的 QLibrary 与 QPluginLoader 不共享加载状态),改为显式lib.load()测试
ET_ArchiveDamaged,无崩溃无挂死Commit: 88abd37
Summary by Sourcery
Add Linglong layer and UAB package handling so the archive manager can safely identify, preview, and extract these packages.
New Features:
Bug Fixes:
Enhancements:
Build: