aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Faure <faure@kde.org>2022-04-24 15:08:59 +0200
committerDavid Faure <faure@kde.org>2022-05-04 09:37:32 +0000
commita0bf7b8e857eba8032e2c828ea2ed0ade09abbad (patch)
tree00da8f36c58a00bf5c8f2547f6f2bcba16a68eec
parent329c4f2ef85a1617cabc1b096b33dd114075138c (diff)
downloadkconfig-a0bf7b8e857eba8032e2c828ea2ed0ade09abbad.tar.gz
kconfig-a0bf7b8e857eba8032e2c828ea2ed0ade09abbad.tar.bz2
KConfigGroup: fix writePathEntry/readPathEntry roundtrip for symlinks
If $HOME isn't canonical (e.g. on FreeBSD it's /home/user while the canonical path is /usr/home/user), replacing the canonical version of $HOME with $HOME means that we'll read back a different value than we wrote in. It might seem "equivalent" but it leads to surprises like KRecentDocuments showing duplicates because /usr/home/user became /home/user in the KConfig roundtrip (but not in the XBEL roundtrip). This commit loses the replacement of /usr/home/user with $HOME on FreeBSD, but I think an exact roundtrip is what we expect, rather than stuff being modified under our feet. The alternative would be to canonicalize everything in KRecentDocuments but users don't want to see the /usr in front, I assume (so we would have to use a cache of canonicalized path, for the removal of duplicates, awful performance wise).
-rw-r--r--autotests/kconfigtest.cpp3
-rw-r--r--src/core/kconfiggroup.cpp17
2 files changed, 10 insertions, 10 deletions
diff --git a/autotests/kconfigtest.cpp b/autotests/kconfigtest.cpp
index 77d0ddde..49b60f55 100644
--- a/autotests/kconfigtest.cpp
+++ b/autotests/kconfigtest.cpp
@@ -83,6 +83,7 @@ static const QVariantList s_variantlist_entry2{s_point_entry, s_size_entry};
static const QString s_homepath{homePath() + QLatin1String{"/foo"}};
static const QString s_homepath_escape{homePath() + QLatin1String("/foo/$HOME")};
+static const QString s_canonical_homepath{QFileInfo(homePath()).canonicalFilePath() + QLatin1String("/foo")};
static const QString s_dollargroup{QStringLiteral("$i")};
static const QString s_test_subdir{QStringLiteral("kconfigtest_subdir/")};
static const QString s_kconfig_test_subdir(s_test_subdir + QLatin1String("kconfigtest"));
@@ -189,6 +190,7 @@ void KConfigTest::initTestCase()
cg = KConfigGroup(&sc, "Path Type");
cg.writePathEntry("homepath", s_homepath);
cg.writePathEntry("homepathescape", s_homepath_escape);
+ cg.writePathEntry("canonicalHomePath", s_canonical_homepath);
cg = KConfigGroup(&sc, "Enum Types");
#if defined(_MSC_VER) && _MSC_VER == 1600
@@ -507,6 +509,7 @@ void KConfigTest::testPath()
KConfigGroup sc3(&sc2, "Path Type");
QCOMPARE(sc3.readPathEntry(QStringLiteral("homepath"), QString{}), s_homepath);
QCOMPARE(sc3.readPathEntry(QStringLiteral("homepathescape"), QString{}), s_homepath_escape);
+ QCOMPARE(sc3.readPathEntry(QStringLiteral("canonicalHomePath"), QString{}), s_canonical_homepath);
QCOMPARE(sc3.entryMap().value(QStringLiteral("homepath")), s_homepath);
qputenv("WITHSLASH", "/a/");
diff --git a/src/core/kconfiggroup.cpp b/src/core/kconfiggroup.cpp
index 8b7cd863..f3ab2202 100644
--- a/src/core/kconfiggroup.cpp
+++ b/src/core/kconfiggroup.cpp
@@ -425,16 +425,13 @@ static QString translatePath(QString path) // krazy:exclude=passbyvalue
return path;
}
- // we can not use KGlobal::dirs()->relativeLocation("home", path) here,
- // since it would not recognize paths without a trailing '/'.
- // All of the 3 following functions to return the user's home directory
- // can return different paths. We have to test all them.
- const QString homeDir0 = QFile::decodeName(qgetenv("HOME"));
- const QString homeDir1 = QDir::homePath();
- const QString homeDir2 = QDir(homeDir1).canonicalPath();
- if (cleanHomeDirPath(path, homeDir0) || cleanHomeDirPath(path, homeDir1) || cleanHomeDirPath(path, homeDir2)) {
- // qDebug() << "Path was replaced\n";
- }
+ // Use the same thing as what expandString() will do, to keep data intact
+#ifdef Q_OS_WIN
+ const QString homeDir = QDir::homePath();
+#else
+ const QString homeDir = QFile::decodeName(qgetenv("HOME"));
+#endif
+ (void)cleanHomeDirPath(path, homeDir);
if (startsWithFile) {
path = QUrl::fromLocalFile(path).toString();