summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qstandardpaths_unix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qstandardpaths_unix.cpp')
-rw-r--r--src/corelib/io/qstandardpaths_unix.cpp99
1 files changed, 62 insertions, 37 deletions
diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp
index e5122ff3b6..55150f9e93 100644
--- a/src/corelib/io/qstandardpaths_unix.cpp
+++ b/src/corelib/io/qstandardpaths_unix.cpp
@@ -180,10 +180,14 @@ QString QStandardPaths::writableLocation(StandardLocation type)
case CacheLocation:
case GenericCacheLocation:
{
+ if (isTestModeEnabled())
+ return QDir::homePath() + "/.qttest/cache"_L1;
+
// http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
QString xdgCacheHome = QFile::decodeName(qgetenv("XDG_CACHE_HOME"));
- if (isTestModeEnabled())
- xdgCacheHome = QDir::homePath() + "/.qttest/cache"_L1;
+ if (!xdgCacheHome.startsWith(u'/'))
+ xdgCacheHome.clear(); // spec says relative paths should be ignored
+
if (xdgCacheHome.isEmpty())
xdgCacheHome = QDir::homePath() + "/.cache"_L1;
if (type == QStandardPaths::CacheLocation)
@@ -194,9 +198,13 @@ QString QStandardPaths::writableLocation(StandardLocation type)
case AppLocalDataLocation:
case GenericDataLocation:
{
- QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME"));
if (isTestModeEnabled())
- xdgDataHome = QDir::homePath() + "/.qttest/share"_L1;
+ return QDir::homePath() + "/.qttest/share"_L1;
+
+ QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME"));
+ if (!xdgDataHome.startsWith(u'/'))
+ xdgDataHome.clear(); // spec says relative paths should be ignored
+
if (xdgDataHome.isEmpty())
xdgDataHome = QDir::homePath() + "/.local/share"_L1;
if (type == AppDataLocation || type == AppLocalDataLocation)
@@ -207,10 +215,14 @@ QString QStandardPaths::writableLocation(StandardLocation type)
case GenericConfigLocation:
case AppConfigLocation:
{
+ if (isTestModeEnabled())
+ return QDir::homePath() + "/.qttest/config"_L1;
+
// http://standards.freedesktop.org/basedir-spec/latest/
QString xdgConfigHome = QFile::decodeName(qgetenv("XDG_CONFIG_HOME"));
- if (isTestModeEnabled())
- xdgConfigHome = QDir::homePath() + "/.qttest/config"_L1;
+ if (!xdgConfigHome.startsWith(u'/'))
+ xdgConfigHome.clear(); // spec says relative paths should be ignored
+
if (xdgConfigHome.isEmpty())
xdgConfigHome = QDir::homePath() + "/.config"_L1;
if (type == AppConfigLocation)
@@ -220,6 +232,9 @@ QString QStandardPaths::writableLocation(StandardLocation type)
case RuntimeLocation:
{
QString xdgRuntimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR"));
+ if (!xdgRuntimeDir.startsWith(u'/'))
+ xdgRuntimeDir.clear(); // spec says relative paths should be ignored
+
bool fromEnv = !xdgRuntimeDir.isEmpty();
if (xdgRuntimeDir.isEmpty() || !checkXdgRuntimeDir(xdgRuntimeDir)) {
// environment variable not set or is set to something unsuitable
@@ -246,6 +261,9 @@ QString QStandardPaths::writableLocation(StandardLocation type)
#if QT_CONFIG(regularexpression)
// http://www.freedesktop.org/wiki/Software/xdg-user-dirs
QString xdgConfigHome = QFile::decodeName(qgetenv("XDG_CONFIG_HOME"));
+ if (!xdgConfigHome.startsWith(u'/'))
+ xdgConfigHome.clear(); // spec says relative paths should be ignored
+
if (xdgConfigHome.isEmpty())
xdgConfigHome = QDir::homePath() + "/.config"_L1;
QFile file(xdgConfigHome + "/user-dirs.dirs"_L1);
@@ -253,23 +271,23 @@ QString QStandardPaths::writableLocation(StandardLocation type)
if (!key.isEmpty() && !isTestModeEnabled() && file.open(QIODevice::ReadOnly)) {
QTextStream stream(&file);
// Only look for lines like: XDG_DESKTOP_DIR="$HOME/Desktop"
- QRegularExpression exp("^XDG_(.*)_DIR=(.*)$"_L1);
+ static const QRegularExpression exp(u"^XDG_(.*)_DIR=(.*)$"_s);
QString result;
while (!stream.atEnd()) {
const QString &line = stream.readLine();
QRegularExpressionMatch match = exp.match(line);
if (match.hasMatch() && match.capturedView(1) == key) {
QStringView value = match.capturedView(2);
- if (value.length() > 2
+ if (value.size() > 2
&& value.startsWith(u'\"')
&& value.endsWith(u'\"'))
- value = value.mid(1, value.length() - 2);
+ value = value.mid(1, value.size() - 2);
// value can start with $HOME
if (value.startsWith("$HOME"_L1))
result = QDir::homePath() + value.mid(5);
else
result = value.toString();
- if (result.length() > 1 && result.endsWith(u'/'))
+ if (result.size() > 1 && result.endsWith(u'/'))
result.chop(1);
}
}
@@ -323,41 +341,48 @@ QString QStandardPaths::writableLocation(StandardLocation type)
return path;
}
-static QStringList xdgDataDirs()
+static QStringList dirsList(const QString &xdgEnvVar)
{
QStringList dirs;
// http://standards.freedesktop.org/basedir-spec/latest/
+ // Normalize paths, skip relative paths (the spec says relative paths
+ // should be ignored)
+ for (const auto dir : qTokenize(xdgEnvVar, u':'))
+ if (dir.startsWith(u'/'))
+ dirs.push_back(QDir::cleanPath(dir.toString()));
+
+ // Remove duplicates from the list, there's no use for duplicated
+ // paths in XDG_DATA_DIRS - if it's not found in the given
+ // directory the first time, it won't be there the second time.
+ // Plus duplicate paths causes problems for example for mimetypes,
+ // where duplicate paths here lead to duplicated mime types returned
+ // for a file, eg "text/plain,text/plain" instead of "text/plain"
+ dirs.removeDuplicates();
+
+ return dirs;
+}
+
+static QStringList xdgDataDirs()
+{
+ // http://standards.freedesktop.org/basedir-spec/latest/
QString xdgDataDirsEnv = QFile::decodeName(qgetenv("XDG_DATA_DIRS"));
- if (xdgDataDirsEnv.isEmpty()) {
- dirs.append(QString::fromLatin1("/usr/local/share"));
- dirs.append(QString::fromLatin1("/usr/share"));
- } else {
- // Normalize paths, skip relative paths
- for (const auto dir : qTokenize(xdgDataDirsEnv, u':')) {
- if (dir.startsWith(u'/'))
- dirs.push_back(QDir::cleanPath(dir.toString()));
- }
- // Remove duplicates from the list, there's no use for duplicated
- // paths in XDG_DATA_DIRS - if it's not found in the given
- // directory the first time, it won't be there the second time.
- // Plus duplicate paths causes problems for example for mimetypes,
- // where duplicate paths here lead to duplicated mime types returned
- // for a file, eg "text/plain,text/plain" instead of "text/plain"
- dirs.removeDuplicates();
- }
+ QStringList dirs = dirsList(xdgDataDirsEnv);
+ if (dirs.isEmpty())
+ dirs = QStringList{u"/usr/local/share"_s, u"/usr/share"_s};
+
return dirs;
}
static QStringList xdgConfigDirs()
{
- QStringList dirs;
// http://standards.freedesktop.org/basedir-spec/latest/
const QString xdgConfigDirs = QFile::decodeName(qgetenv("XDG_CONFIG_DIRS"));
- if (xdgConfigDirs.isEmpty())
- dirs.append(QString::fromLatin1("/etc/xdg"));
- else
- dirs = xdgConfigDirs.split(u':');
+
+ QStringList dirs = dirsList(xdgConfigDirs);
+ if (dirs.isEmpty())
+ dirs.push_back(u"/etc/xdg"_s);
+
return dirs;
}
@@ -371,7 +396,7 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
break;
case AppConfigLocation:
dirs = xdgConfigDirs();
- for (int i = 0; i < dirs.count(); ++i)
+ for (int i = 0; i < dirs.size(); ++i)
appendOrganizationAndApp(dirs[i]);
break;
case GenericDataLocation:
@@ -379,19 +404,19 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
break;
case ApplicationsLocation:
dirs = xdgDataDirs();
- for (int i = 0; i < dirs.count(); ++i)
+ for (int i = 0; i < dirs.size(); ++i)
dirs[i].append("/applications"_L1);
break;
case AppDataLocation:
case AppLocalDataLocation:
dirs = xdgDataDirs();
- for (int i = 0; i < dirs.count(); ++i)
+ for (int i = 0; i < dirs.size(); ++i)
appendOrganizationAndApp(dirs[i]);
break;
case FontsLocation:
dirs += QDir::homePath() + "/.fonts"_L1;
dirs += xdgDataDirs();
- for (int i = 1; i < dirs.count(); ++i)
+ for (int i = 1; i < dirs.size(); ++i)
dirs[i].append("/fonts"_L1);
break;
default: