fix: sync generated autostart desktop entries#371
Conversation
Reviewer's GuideAdds robust handling and resync of generated autostart desktop entries, ensuring files exist before use, reusing only valid existing entries, preserving Hidden state, and centralizing autostart file I/O. Sequence diagram for syncing generated autostart desktop entriessequenceDiagram
participant ApplicationManager1Service
participant ApplicationService
ApplicationManager1Service->>ApplicationService: setAutostartSource(AutostartSource)
ApplicationManager1Service->>ApplicationService: syncGeneratedAutostartEntry()
ApplicationService->>ApplicationService: autostartSourceFileExists()
alt [autostartSourceFileExists]
ApplicationService->>ApplicationService: QFile::open(ReadOnly | Text)
ApplicationService->>ApplicationService: DesktopEntry::parse()
ApplicationService->>ApplicationService: hasGeneratedAutostartSource()
alt [hasGeneratedAutostartSource]
ApplicationService->>ApplicationService: DesktopEntry::insert(XDeepinGenerateSource)
ApplicationService->>ApplicationService: DesktopEntry::insert(Hidden)
ApplicationService->>ApplicationService: saveAutostartEntry(fileName, entry)
ApplicationService->>ApplicationService: setAutostartSource(AutostartSource)
end
end
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 left some high level feedback:
- The logic for detecting generated autostart entries is duplicated between
hasGeneratedAutostartSource()andsyncGeneratedAutostartEntry()(manualgroup->get().contains(...)check); consider reusinghasGeneratedAutostartSource()insidesyncGeneratedAutostartEntry()to keep this condition centralized and less error-prone. syncGeneratedAutostartEntry()silently returns on several error paths (open/parse/validation failures) with only a generic warning; if these cases are important to diagnose in production, consider including the file path and a brief reason in each log to make it easier to trace why sync was skipped.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The logic for detecting generated autostart entries is duplicated between `hasGeneratedAutostartSource()` and `syncGeneratedAutostartEntry()` (manual `group->get().contains(...)` check); consider reusing `hasGeneratedAutostartSource()` inside `syncGeneratedAutostartEntry()` to keep this condition centralized and less error-prone.
- `syncGeneratedAutostartEntry()` silently returns on several error paths (open/parse/validation failures) with only a generic warning; if these cases are important to diagnose in production, consider including the file path and a brief reason in each log to make it easier to trace why sync was skipped.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
10def6f to
93f2f45
Compare
93f2f45 to
1980ffa
Compare
deepin pr auto review★ 总体评分:40分■ 【总体评价】
■ 【详细分析】
■ 【改进建议代码示例】 +++ b/src/dbus/applicationservice.cpp
@@ -15,6 +15,10 @@
#include <QFileInfo>
#include <QLoggingCategory>
#include <QDir>
+#include <fcntl.h>
+#include <unistd.h>
+#include <cerrno>
+#include <cstring>
Q_LOGGING_CATEGORY(appServiceLog, "deepin.app.service", QtWarningMsg)
@@ -961,14 +965,13 @@ bool ApplicationService::autostartCheck() const noexcept
bool ApplicationService::saveAutostartEntry(const QString &fileName, const DesktopEntry &entry) noexcept
{
- const QFileInfo autostartFileInfo{fileName};
- if (autostartFileInfo.isSymLink()) {
- qWarning() << "refuse to overwrite symlink autostart file:" << fileName;
+ // 使用 O_NOFOLLOW 原子化防止 TOCTOU 竞态条件导致的符号链接攻击
+ int fd = ::open(fileName.toLocal8Bit().constData(), O_WRONLY | O_NOFOLLOW | O_TRUNC | O_CLOEXEC, 0644);
+ if (fd == -1) {
+ qWarning() << "open file" << fileName << "failed:" << strerror(errno);
return false;
}
- QFile autostartFile{fileName};
- if (!autostartFile.open(QFile::WriteOnly | QFile::Text | QFile::Truncate)) {
- qWarning() << "open file" << fileName << "failed:" << autostartFile.error();
+ if (!autostartFile.open(fd, QIODevice::WriteOnly | QIODevice::Text)) {
+ qWarning() << "bind fd to QFile failed:" << fileName;
+ ::close(fd);
return false;
} |
Refresh generated autostart desktop files when application desktop entries are reloaded. - Avoid reusing stale in-memory autostart entries after the user deletes the generated file. - Rewrite AM-generated autostart entries from the current installed desktop entry. - Preserve the current Hidden value from disk so disabled autostart entries stay disabled. - Refuse to overwrite symlink autostart files and guard null desktop entries before syncing. 刷新生成的自启动 desktop 文件,使其跟随应用 desktop 更新。 - 用户删除生成文件后,避免继续复用内存中的旧自启动 entry。 - 对 AM 生成的自启动 entry,使用当前安装 desktop entry重新写入。 - 保留磁盘当前 Hidden 值,确保已禁用的自启动项不会被重新启用。 - 拒绝覆盖符号链接形式的自启动文件,并在同步前防御空 desktop entry。 Log: sync generated autostart desktop entries Pms: BUG-367265 Change-Id: I8a0e0733aa755d9481a0a2bf5f5ae0b72741d507
1980ffa to
c437b17
Compare
本服务为session级别的服务,无法提权去覆盖系统级别的文件,为误报。 |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: BLumia, yixinshark 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 |
|
/test all |
Summary
Test plan
Summary by Sourcery
Synchronize and persist generated autostart desktop entries with their source application entries while ensuring file existence checks and error handling are improved.
New Features:
Bug Fixes:
Enhancements: