Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
dde-application-manager (1.2.27) unstable; urgency=medium

* fix: convert file:// to local path

-- heyuming <heyuming@deepin.org> Thu, 10 Apr 2025 16:52:52 +0800

dde-application-manager (1.2.26) unstable; urgency=medium

* fix: abnormal splitting of parameters enclosed in quotation marks in Exec
Expand Down Expand Up @@ -96,7 +102,7 @@ dde-application-manager (1.2.11) unstable; urgency=medium

dde-application-manager (1.2.10) unstable; urgency=medium

* fix: crashed when launching a application contains "%U"
* fix: crashed when launching a application contains "%U"
* fix: revert "crashed when removing a invalid index"

-- Wang Fei <wangfei@deepin.org> Fri, 10 May 2024 15:18:39 +0800
Expand Down
77 changes: 42 additions & 35 deletions src/dbus/applicationservice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,32 +371,55 @@ ApplicationService::Launch(const QString &action, const QStringList &fields, con

return objectPath;
}
QStringList rawRes;
if(value.canConvert<QStringList>()){
rawRes = value.toStringList();
}

if (task.argNum != -1) {
if (task.argNum >= newCommands.size()) {
qCritical() << "task.argNum >= task.command.size()";
return QDBusError::Failed;
}

auto tmp = task.command;
if (task.fieldLocation == -1) {
for(int i = 0; i < rawRes.size(); i++){
tmp.insert(task.argNum + 1 + i, rawRes.at(i));
}
QStringList rawRes;
if (value.canConvert<QStringList>()) { // from %F, %U
rawRes = value.toStringList();
} else if (value.canConvert<QString>()) { // from %f, %u
rawRes.append(value.toString());
} else {
qWarning() << "value type mismatch:" << value;
return QDBusError::Failed;
}

if (task.local) {
std::for_each(rawRes.begin(), rawRes.end(), [](QString &str) {
auto url = QUrl::fromUserInput(str);

if (url.isLocalFile()) {
str = url.toLocalFile();
return;
}

// TODO: processing remote files
// str = downloadToLocal(url).toLocalFile();
});
}

auto newCmds = task.command;
Copy link

Choose a reason for hiding this comment

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

issue (complexity): Consider replacing lambdas and reverse-iterator insertions with explicit loops to improve readability and maintainability of the code.

Consider replacing these lambdas and reverse-iterator insertions with explicit, simple loops. For example, instead of this:

    std::for_each(
        rawRes.rbegin(), rawRes.rend(), 
        [&newCmds, &it](QString &str) { it = newCmds.insert(it, str); }
    );

you could simplify it to a clear reverse loop:

    if (task.fieldLocation == -1) {
        for (int i = rawRes.size() - 1; i >= 0; --i) {
            newCmds.insert(task.argNum + 1, rawRes.at(i));
        }
    } else {
        auto arg = newCmds.begin() + task.argNum + 1;
        arg->insert(task.fieldLocation, rawRes.takeFirst());
        ++arg;
        for (int i = rawRes.size() - 1; i >= 0; --i) {
            newCmds.insert(arg, rawRes.at(i));
        }
    }

Similarly, for URL processing, replace the lambda with a range-based loop:

    if (task.local) {
        for (auto &str : rawRes) {
            QUrl url = QUrl::fromUserInput(str);
            if (url.isLocalFile()) {
                str = url.toLocalFile();
            }
            // Optionally handle remote files in a separate function.
        }
    }

These changes preserve functionality while reducing layered abstractions and nested lambdas, improving readability and maintainability.

if (task.fieldLocation == -1) { // single field, e.g. "demo %U"
auto it = newCmds.begin() + task.argNum + 1;
std::for_each(
rawRes.rbegin(), rawRes.rend(), [&newCmds, &it](QString &str) { it = newCmds.insert(it, str); });
} else {
auto arg = tmp.at(task.argNum);
for(int i = 0; i < rawRes.size(); i++){
tmp.insert(task.fieldLocation, rawRes.at(i));
}
tmp[task.argNum] = arg;
auto arg = newCmds.begin() + task.argNum + 1;
arg->insert(task.fieldLocation, rawRes.takeFirst());
++arg;

// expand the rest of res
std::for_each(
rawRes.rbegin(), rawRes.rend(), [&newCmds, &arg](QString &str) { arg = newCmds.insert(arg, str); });
}

newCommands.append(std::move(tmp));
newCommands.append(std::move(newCmds));
}

newCommands.push_front(QString{"--SourcePath=%1"}.arg(m_desktopSource.sourcePath()));
newCommands.push_front(QString{R"(--unitName=DDE-%1@%2.service)"}.arg(this->id(), instanceRandomUUID));

Expand Down Expand Up @@ -1066,20 +1089,6 @@ LaunchTask ApplicationService::unescapeExec(const QString &str, QStringList fiel
return {};
}

auto processUrl = [](const QString &str) {
auto url = QUrl::fromUserInput(str);
if (!url.isValid()) {
qDebug() << "url is invalid, pass to exec directly.";
return str;
}

if (url.isLocalFile()) {
return url.toLocalFile();
}

return url.toString();
};

task.LaunchBin = args->first();
const QChar percentage{'%'};
bool exclusiveField{false};
Expand Down Expand Up @@ -1129,6 +1138,7 @@ LaunchTask ApplicationService::unescapeExec(const QString &str, QStringList fiel

task.argNum = std::distance(args->begin(), arg) - 1;
task.fieldLocation = std::distance(arg->cbegin(), it) - 1;
task.local = true;
} break;
case 'u':
case 'U': {
Expand All @@ -1143,15 +1153,12 @@ LaunchTask ApplicationService::unescapeExec(const QString &str, QStringList fiel
break;
}

QStringList urls;
std::transform(fields.cbegin(), fields.cend(), std::back_inserter(urls), processUrl);
fields.clear();

// respect the original url, pass it to exec directly
if (c == 'U') {
task.Resources.emplace_back(urls.join(' '));
task.Resources.emplace_back(std::move(fields));
} else {
std::for_each(
urls.begin(), urls.end(), [&task](QString &url) { task.Resources.emplace_back(std::move(url)); });
fields.begin(), fields.end(), [&task](QString &url) { task.Resources.emplace_back(std::move(url)); });
}

task.argNum = std::distance(args->begin(), arg) - 1;
Expand Down
2 changes: 1 addition & 1 deletion src/dbus/jobmanager1service.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct LaunchTask
QString LaunchBin;
QStringList command;
QVariantList Resources;
bool singleInstance{false};
bool local{false};
int argNum{-1};
int fieldLocation{-1};
};
Expand Down
Loading