Skip to content

Commit

Permalink
Session: Parse .desktop files manually again
Browse files Browse the repository at this point in the history
Using QSettings::IniFormat doesn't quite work. Implement a custom parser
for those files to handle them according to the specification.

Fixes #1745
  • Loading branch information
Vogtinator authored and davidedmundson committed Jun 26, 2023
1 parent 22f389b commit 5b702ae
Showing 1 changed file with 51 additions and 1 deletion.
52 changes: 51 additions & 1 deletion src/common/Session.cpp
Expand Up @@ -34,6 +34,56 @@
const QString s_entryExtention = QStringLiteral(".desktop");

namespace SDDM {
// QSettings::IniFormat can't be used to read .desktop files due to different
// syntax of values (escape sequences, quoting, automatic QStringList detection).
// So implement yet another .desktop file parser.
class DesktopFileFormat {
static bool readFunc(QIODevice &device, QSettings::SettingsMap &map)
{
QString currentSectionName;
while(!device.atEnd())
{
// Iterate each line, remove line terminators
const auto line = device.readLine().replace("\r", "").replace("\n", "");

This comment has been minimized.

Copy link
@bvbfan

bvbfan Feb 27, 2024

Why not trimmed() ?

if(line.isEmpty() || line.startsWith('#'))
continue; // Ignore empty lines and comments

if(line.startsWith('[')) // Section header
{
// Remove [ and ].
currentSectionName = QString::fromUtf8(line.mid(1, line.length() - 2));
}
else if(int equalsPos = line.indexOf('='); equalsPos > 0) // Key=Value
{
const auto key = QString::fromUtf8(line.left(equalsPos));

// Read the value, handle escape sequences
auto valueBytes = line.mid(equalsPos + 1);
valueBytes.replace("\\s", " ").replace("\\n", "\n");
valueBytes.replace("\\t", "\t").replace("\\r", "\r");
valueBytes.replace("\\\\", "\\");

auto value = QString::fromUtf8(valueBytes);
map.insert(currentSectionName + QLatin1Char('/') + key, value);
}
}

return true;
}
public:
// Register the .desktop file format if necessary, return its id.
static QSettings::Format format()
{
static QSettings::Format s_format = QSettings::InvalidFormat;
if (s_format == QSettings::InvalidFormat)
s_format = QSettings::registerFormat(QStringLiteral("desktop"),
DesktopFileFormat::readFunc, nullptr,
Qt::CaseSensitive);

return s_format;
}
};

Session::Session()
: m_valid(false)
, m_type(UnknownSession)
Expand Down Expand Up @@ -169,7 +219,7 @@ namespace SDDM {
if (!file.isOpen())
return;

QSettings settings(m_fileName, QSettings::IniFormat);
QSettings settings(m_fileName, DesktopFileFormat::format());
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
settings.setIniCodec("UTF-8");
#endif
Expand Down

0 comments on commit 5b702ae

Please sign in to comment.