fix: crashed when removing a invalid index (-1)
handle the exceptional case that location is -1 Issue: https://github.com/linuxdeepin/developer-center/issues/7964
This commit is contained in:
parent
9a29c0e09a
commit
a2892b193f
@ -909,8 +909,99 @@ std::optional<QStringList> ApplicationService::unescapeExecArgs(const QString &s
|
||||
LaunchTask ApplicationService::unescapeExec(const QString &str, const QStringList &fields) noexcept
|
||||
{
|
||||
LaunchTask task;
|
||||
auto opt = unescapeExecArgs(str);
|
||||
|
||||
QString content = str;
|
||||
QRegularExpression re{"%[fFuUickdDnNvm]"};
|
||||
QStringList list = re.match(str).capturedTexts();
|
||||
if (list.count() == 1) {
|
||||
char fieldCode = list.first().back().toLatin1();
|
||||
QString codeStr = QString(R"(%%1)").arg(fieldCode);
|
||||
switch (fieldCode) {
|
||||
case 'f': { // Defer to async job
|
||||
for (const auto &field : fields) {
|
||||
task.Resources.emplace_back(field);
|
||||
}
|
||||
} break;
|
||||
case 'u': {
|
||||
if (fields.empty()) {
|
||||
break;
|
||||
}
|
||||
if (fields.count() > 1) {
|
||||
qDebug() << R"(fields count is greater than one, %u will only take first element.)";
|
||||
}
|
||||
content.replace(codeStr, fields.first());
|
||||
} break;
|
||||
case 'F': {
|
||||
QStringList result;
|
||||
for (const auto &field : fields) {
|
||||
auto tmp = QUrl{field};
|
||||
if (auto scheme = tmp.scheme(); scheme.startsWith("file") or scheme.isEmpty()) {
|
||||
result.append(tmp.toLocalFile());
|
||||
} else {
|
||||
qWarning() << "shouldn't replace %F with an URL:" << field;
|
||||
result.append(field);
|
||||
}
|
||||
}
|
||||
content.replace(codeStr, result.join(" "));
|
||||
} break;
|
||||
case 'U': {
|
||||
content.replace(codeStr, fields.join(" "));
|
||||
} break;
|
||||
case 'i': {
|
||||
auto val = m_entry->value(DesktopFileEntryKey, "Icon");
|
||||
if (!val) {
|
||||
qDebug() << R"(Application Icons can't be found. %i will be ignored.)";
|
||||
break;
|
||||
}
|
||||
|
||||
auto iconStr = toIconString(val.value());
|
||||
if (iconStr.isEmpty()) {
|
||||
qDebug() << R"(Icons Convert to string failed. %i will be ignored.)";
|
||||
break;
|
||||
}
|
||||
content.replace(codeStr, QString("--icon") + " " + iconStr);
|
||||
} break;
|
||||
case 'c': {
|
||||
auto val = m_entry->value(DesktopFileEntryKey, "Name");
|
||||
if (!val) {
|
||||
qDebug() << R"(Application Name can't be found. %c will be ignored.)";
|
||||
break;
|
||||
}
|
||||
|
||||
const auto &rawValue = val.value();
|
||||
if (!rawValue.canConvert<QStringMap>()) {
|
||||
qDebug() << "Name's underlying type mismatch:" << "QStringMap" << rawValue.metaType().name();
|
||||
break;
|
||||
}
|
||||
|
||||
auto NameStr = toLocaleString(rawValue.value<QStringMap>(), getUserLocale());
|
||||
if (NameStr.isEmpty()) {
|
||||
qDebug() << R"(Name Convert to locale string failed. %c will be ignored.)";
|
||||
break;
|
||||
}
|
||||
content.replace(codeStr, NameStr);
|
||||
} break;
|
||||
case 'k': { // ignore all desktop file location for now.
|
||||
} break;
|
||||
case 'd':
|
||||
case 'D':
|
||||
case 'n':
|
||||
case 'N':
|
||||
case 'v':
|
||||
[[fallthrough]]; // Deprecated field codes should be removed from the command line and ignored.
|
||||
case 'm': {
|
||||
} break;
|
||||
default: {
|
||||
qDebug() << "unrecognized file code.";
|
||||
}
|
||||
}
|
||||
} else if (list.count() > 1) {
|
||||
for (const auto &code : list) {
|
||||
content.remove(code);
|
||||
}
|
||||
}
|
||||
|
||||
auto opt = unescapeExecArgs(content);
|
||||
if (!opt.has_value()) {
|
||||
qWarning() << "unescapeExecArgs failed.";
|
||||
return {};
|
||||
@ -923,134 +1014,7 @@ LaunchTask ApplicationService::unescapeExec(const QString &str, const QStringLis
|
||||
}
|
||||
|
||||
task.LaunchBin = execList.first();
|
||||
QRegularExpression re{"%[fFuUickdDnNvm]"};
|
||||
auto matcher = re.match(str);
|
||||
if (!matcher.hasMatch()) {
|
||||
task.command.append(std::move(execList));
|
||||
task.Resources.emplace_back(QString{""}); // mapReduce should run once at least
|
||||
return task;
|
||||
}
|
||||
|
||||
auto list = matcher.capturedTexts();
|
||||
if (list.count() != 1) {
|
||||
qWarning() << "invalid exec format, all filed code will be ignored.";
|
||||
for (const auto &code : list) {
|
||||
execList.removeOne(code);
|
||||
}
|
||||
task.command.append(std::move(execList));
|
||||
return task;
|
||||
}
|
||||
|
||||
auto filesCode = list.first().back().toLatin1();
|
||||
auto codeStr = QString(R"(%%1)").arg(filesCode);
|
||||
auto location = execList.indexOf(codeStr);
|
||||
|
||||
switch (filesCode) {
|
||||
case 'f': { // Defer to async job
|
||||
task.command.append(std::move(execList));
|
||||
for (const auto &field : fields) {
|
||||
task.Resources.emplace_back(field);
|
||||
}
|
||||
} break;
|
||||
case 'u': {
|
||||
execList.removeAt(location);
|
||||
if (fields.empty()) {
|
||||
task.command.append(execList);
|
||||
break;
|
||||
}
|
||||
if (fields.count() > 1) {
|
||||
qDebug() << R"(fields count is greater than one, %u will only take first element.)";
|
||||
}
|
||||
execList.insert(location, fields.first());
|
||||
task.command.append(execList);
|
||||
} break;
|
||||
case 'F': {
|
||||
execList.remove(location);
|
||||
auto it = execList.begin() + location;
|
||||
for (const auto &field : fields) {
|
||||
auto tmp = QUrl::fromUserInput(field);
|
||||
if (auto scheme = tmp.scheme(); scheme.startsWith("file") or scheme.isEmpty()) {
|
||||
it = execList.insert(it, tmp.toLocalFile());
|
||||
} else {
|
||||
qWarning() << "shouldn't replace %F with an URL:" << field;
|
||||
it = execList.insert(it, field);
|
||||
}
|
||||
++it;
|
||||
}
|
||||
task.command.append(std::move(execList));
|
||||
} break;
|
||||
case 'U': {
|
||||
execList.removeAt(location);
|
||||
auto it = execList.begin() + location;
|
||||
for (const auto &field : fields) {
|
||||
it = execList.insert(it, field);
|
||||
++it;
|
||||
}
|
||||
task.command.append(std::move(execList));
|
||||
} break;
|
||||
case 'i': {
|
||||
execList.removeAt(location);
|
||||
auto val = m_entry->value(DesktopFileEntryKey, "Icon");
|
||||
if (!val) {
|
||||
qDebug() << R"(Application Icons can't be found. %i will be ignored.)";
|
||||
task.command.append(std::move(execList));
|
||||
return task;
|
||||
}
|
||||
|
||||
auto iconStr = toIconString(val.value());
|
||||
if (iconStr.isEmpty()) {
|
||||
qDebug() << R"(Icons Convert to string failed. %i will be ignored.)";
|
||||
task.command.append(std::move(execList));
|
||||
return task;
|
||||
}
|
||||
auto it = execList.insert(location, iconStr);
|
||||
execList.insert(it, "--icon");
|
||||
task.command.append(std::move(execList));
|
||||
} break;
|
||||
case 'c': {
|
||||
execList.removeAt(location);
|
||||
auto val = m_entry->value(DesktopFileEntryKey, "Name");
|
||||
if (!val) {
|
||||
qDebug() << R"(Application Name can't be found. %c will be ignored.)";
|
||||
task.command.append(std::move(execList));
|
||||
return task;
|
||||
}
|
||||
|
||||
const auto &rawValue = val.value();
|
||||
if (!rawValue.canConvert<QStringMap>()) {
|
||||
qDebug() << "Name's underlying type mismatch:"
|
||||
<< "QStringMap" << rawValue.metaType().name();
|
||||
task.command.append(std::move(execList));
|
||||
return task;
|
||||
}
|
||||
|
||||
auto NameStr = toLocaleString(rawValue.value<QStringMap>(), getUserLocale());
|
||||
if (NameStr.isEmpty()) {
|
||||
qDebug() << R"(Name Convert to locale string failed. %c will be ignored.)";
|
||||
task.command.append(std::move(execList));
|
||||
return task;
|
||||
}
|
||||
execList.insert(location, NameStr);
|
||||
task.command.append(std::move(execList));
|
||||
} break;
|
||||
case 'k': { // ignore all desktop file location for now.
|
||||
execList.removeAt(location);
|
||||
task.command.append(std::move(execList));
|
||||
} break;
|
||||
case 'd':
|
||||
case 'D':
|
||||
case 'n':
|
||||
case 'N':
|
||||
case 'v':
|
||||
[[fallthrough]]; // Deprecated field codes should be removed from the command line and ignored.
|
||||
case 'm': {
|
||||
execList.removeAt(location);
|
||||
task.command.append(std::move(execList));
|
||||
} break;
|
||||
default: {
|
||||
qDebug() << "unrecognized file code.";
|
||||
}
|
||||
}
|
||||
task.command.append(std::move(execList));
|
||||
|
||||
if (task.Resources.isEmpty()) {
|
||||
task.Resources.emplace_back(QString{""}); // mapReduce should run once at least
|
||||
|
Loading…
Reference in New Issue
Block a user