[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdelibs/kdecore
From: David Faure <faure () kde ! org>
Date: 2010-11-26 23:28:30
Message-ID: 20101126232830.95E4CAC8A2 () svn ! kde ! org
[Download RAW message or body]
SVN commit 1201149 by dfaure:
Ensure that KStandardDirs always returns resolved paths (when $HOME or $KDEHOME is a symlink),
even when returning paths that don't exist yet. Otherwise, via caches (the kstandarddirs one
or in applications), we can end up with a different path once it does exist, and comparisons
will fail (e.g. the one in KConfigPrivate::parseConfigFiles which detects the local file).
(So this fixes "kconfigtest testRevertAllEntries" when $HOME is a symlink, but has its own
setup-independent unittest now)
M +22 -3 kernel/kstandarddirs.cpp
M +33 -0 tests/kstandarddirstest.cpp
M +1 -0 tests/kstandarddirstest.h
--- trunk/KDE/kdelibs/kdecore/kernel/kstandarddirs.cpp #1201148:1201149
@@ -923,9 +923,28 @@
return QFile::decodeName(realpath_buffer);
}
- if (!dirname.endsWith(QLatin1Char('/')))
- return dirname + QLatin1Char('/');
- return dirname;
+ // Does not exist yet; resolve symlinks in parent dirs then.
+ // This ensures that once the directory exists, it will still be resolved
+ // the same way, so that the general rule that KStandardDirs always returns
+ // canonical paths stays true, and app code can compare paths more easily.
+ QString dir = dirname;
+ if (!dir.endsWith(QLatin1Char('/')))
+ dir += QLatin1Char('/');
+ QString relative;
+ while (!KStandardDirs::exists(dir)) {
+ //qDebug() << "does not exist:" << dir;
+ const int pos = dir.lastIndexOf(QLatin1Char('/'), -2);
+ Q_ASSERT(pos > 0); // what? even "/" doesn't exist?
+ relative.prepend(dir.mid(pos+1)); // keep "subdir/"
+ dir = dir.left(pos+1);
+ Q_ASSERT(dir.endsWith(QLatin1Char('/')));
+ }
+ Q_ASSERT(!relative.isEmpty()); // infinite recursion ahead
+ if (!relative.isEmpty()) {
+ //qDebug() << "done, resolving" << dir << "and adding" << relative;
+ dir = realPath(dir) + relative;
+ }
+ return dir;
#endif
}
--- trunk/KDE/kdelibs/kdecore/tests/kstandarddirstest.cpp #1201148:1201149
@@ -26,6 +26,7 @@
#include <kstandarddirs.h>
#include <kconfig.h>
#include <kglobal.h>
+#include <ktempdir.h>
#include "config-prefix.h"
#include <QtCore/QDebug>
#include <kconfiggroup.h>
@@ -407,6 +408,38 @@
localFile.remove();
}
+void KStandarddirsTest::testSymlinkResolution()
+{
+#ifndef Q_OS_WIN
+ // This makes the save location for the david resource, "$HOME/.kde-unit-test/symlink/test/"
+ // where symlink points to "real", and the subdir test will be created later
+ // This used to confuse KStandardDirs and make it return unresolved paths,
+ // and thus making comparisons fail later on in KConfig.
+ const QString symlink = m_kdehome + "/symlink";
+ const QString expected = m_kdehome + "/real/test/";
+ QVERIFY(KTempDir::removeDir(m_kdehome + "/real"));
+ QVERIFY(QDir(m_kdehome).mkdir("real"));
+ QFile::remove(symlink);
+ QVERIFY(!QFile::exists(symlink));
+ QVERIFY(QFile::link("real", symlink));
+ QVERIFY(QFileInfo(symlink).isSymLink());
+ QVERIFY(!QFile::exists(expected));
+ KGlobal::dirs()->addResourceType("david", 0, "symlink/test");
+ QVERIFY(!QFile::exists(expected));
+ const QString saveLoc = KGlobal::dirs()->resourceDirs("david").first();
+ QVERIFY(!QFile::exists(expected));
+ // The issue at this point is that saveLoc does not actually exist yet.
+ QVERIFY(QDir(saveLoc).canonicalPath().isEmpty()); // this is why we can't use canonicalPath
+ QVERIFY(!QFile::exists(saveLoc));
+ QCOMPARE(saveLoc, KStandardDirs::realPath(saveLoc)); // must be resolved
+ QCOMPARE(saveLoc, expected);
+ QVERIFY(QDir(m_kdehome).mkpath("real/test")); // KConfig calls mkdir on its own, we simulate that here
+ const QString sameSaveLoc = KGlobal::dirs()->resourceDirs("david").first();
+ QCOMPARE(sameSaveLoc, saveLoc);
+ QCOMPARE(sameSaveLoc, KGlobal::dirs()->saveLocation("david"));
+#endif
+}
+
#include <QThreadPool>
#include <qtconcurrentrun.h>
--- trunk/KDE/kdelibs/kdecore/tests/kstandarddirstest.h #1201148:1201149
@@ -42,6 +42,7 @@
void testAddResourceDir();
void testSetXdgDataDirs();
void testRestrictedResources();
+ void testSymlinkResolution();
void testThreads();
private:
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic