From ca34cc75294e0d2a8bc491a2c679fe8a69cd0408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 26 Aug 2011 15:43:06 +0200 Subject: Wrap calls to Sequence::push_back In C++11 push_back is overloaded to support rvalue-references, void std::vector::push_back(const T &); void std::vector::push_back(T &&); so attempting to get the address for push_back is ambiguous. Instead of hardcoding the function signature, the better and more general solution is to allow the compiler to do the required overload resolution itself, also allowing for implicit conversions to take place. Task-number: QTBUG-18996 Done-with: Liang Qi Reviewed-by: Olivier Goffart --- src/corelib/concurrent/qtconcurrentfilter.h | 20 +++++++++----------- .../concurrent/qtconcurrentfunctionwrappers.h | 19 +++++++++++++++++++ src/corelib/concurrent/qtconcurrentmap.h | 8 ++++---- tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp | 4 ---- 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/corelib/concurrent/qtconcurrentfilter.h b/src/corelib/concurrent/qtconcurrentfilter.h index 4b9c4ae..d8c5f43 100644 --- a/src/corelib/concurrent/qtconcurrentfilter.h +++ b/src/corelib/concurrent/qtconcurrentfilter.h @@ -102,10 +102,9 @@ namespace QtConcurrent { namespace QtConcurrent { -template -ThreadEngineStarter filterInternal(Sequence &sequence, KeepFunctor keep, T (C::*reduce)(U)) +template +ThreadEngineStarter filterInternal(Sequence &sequence, KeepFunctor keep, ReduceFunctor reduce) { - typedef MemberFunctionWrapper1 ReduceFunctor; typedef typename Sequence::const_iterator Iterator; typedef FilterKernel KernelType; return startThreadEngine(new KernelType(sequence, keep, reduce)); @@ -115,7 +114,7 @@ ThreadEngineStarter filterInternal(Sequence &sequence, KeepFunctor keep, T template QFuture filter(Sequence &sequence, KeepFunctor keep) { - return filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), &Sequence::push_back); + return filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::PushBackWrapper()); } // filteredReduced() on sequences @@ -184,7 +183,7 @@ QFuture::value_type> filtered(Iterator begin, Iter template void blockingFilter(Sequence &sequence, KeepFunctor keep) { - filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), &Sequence::push_back).startBlocking(); + filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::PushBackWrapper()).startBlocking(); } // blocking filteredReduced() on sequences @@ -246,18 +245,17 @@ typename QtPrivate::ReduceResultType::ResultType blockingFiltered template Sequence blockingFiltered(const Sequence &sequence, KeepFunctor keep) { - return blockingFilteredReduced(sequence, QtPrivate::createFunctionWrapper(keep), &Sequence::push_back, OrderedReduce); + return startFilteredReduced(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::PushBackWrapper(), OrderedReduce).startBlocking(); } // blocking filtered() on iterators template OutputSequence blockingFiltered(Iterator begin, Iterator end, KeepFunctor keep) { - return blockingFilteredReduced(begin, - end, - QtPrivate::createFunctionWrapper(keep), - &OutputSequence::push_back, - OrderedReduce); + return startFilteredReduced(begin, end, + QtPrivate::createFunctionWrapper(keep), + QtPrivate::PushBackWrapper(), + OrderedReduce).startBlocking(); } } // namespace QtConcurrent diff --git a/src/corelib/concurrent/qtconcurrentfunctionwrappers.h b/src/corelib/concurrent/qtconcurrentfunctionwrappers.h index 4bf2736..1e09221 100644 --- a/src/corelib/concurrent/qtconcurrentfunctionwrappers.h +++ b/src/corelib/concurrent/qtconcurrentfunctionwrappers.h @@ -195,6 +195,25 @@ QtConcurrent::ConstMemberFunctionWrapper createFunctionWrapper(T (C::*func return QtConcurrent::ConstMemberFunctionWrapper(func); } +struct PushBackWrapper +{ + typedef void result_type; + + template + inline void operator()(C &c, const U &u) const + { + return c.push_back(u); + } + +#ifdef Q_COMPILER_RVALUE_REFS + template + inline void operator()(C &c, U &&u) const + { + return c.push_back(u); + } +#endif +}; + template ::Value> struct LazyResultType { typedef typename Functor::result_type Type; }; template diff --git a/src/corelib/concurrent/qtconcurrentmap.h b/src/corelib/concurrent/qtconcurrentmap.h index 37a4143..166d5c8 100644 --- a/src/corelib/concurrent/qtconcurrentmap.h +++ b/src/corelib/concurrent/qtconcurrentmap.h @@ -271,7 +271,7 @@ OutputSequence blockingMapped(const InputSequence &sequence, MapFunctor map) return blockingMappedReduced (sequence, QtPrivate::createFunctionWrapper(map), - &OutputSequence::push_back, + QtPrivate::PushBackWrapper(), QtConcurrent::OrderedReduce); } @@ -282,7 +282,7 @@ typename QtPrivate::MapResultType::ResultType blockin return blockingMappedReduced (sequence, QtPrivate::createFunctionWrapper(map), - &OutputSequence::push_back, + QtPrivate::PushBackWrapper(), QtConcurrent::OrderedReduce); } @@ -293,7 +293,7 @@ Sequence blockingMapped(Iterator begin, Iterator end, MapFunctor map) return blockingMappedReduced (begin, end, QtPrivate::createFunctionWrapper(map), - &Sequence::push_back, + QtPrivate::PushBackWrapper(), QtConcurrent::OrderedReduce); } @@ -304,7 +304,7 @@ typename QtPrivate::MapResultType::ResultType blockingMapp return blockingMappedReduced (begin, end, QtPrivate::createFunctionWrapper(map), - &OutputSequence::push_back, + QtPrivate::PushBackWrapper(), QtConcurrent::OrderedReduce); } diff --git a/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp index f4249ab..336dc71 100644 --- a/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp +++ b/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp @@ -2320,10 +2320,6 @@ void tst_QtConcurrentMap::stlContainers() { #ifdef QT_NO_STL QSKIP("Qt compiled without STL support", SkipAll); -#elif defined(Q_COMPILER_RVALUE_REFS) - //mapped uses &Container::push_back, but in c++0x, std::vector has two overload of it - // meaning it is not possible to take the address of that function anymore. - QSKIP("mapped do not work with c++0x stl vector", SkipAll); #else std::vector vector; vector.push_back(1); -- cgit v0.12 From ddf5a09d469a1ded5490cffe54e0013a0d5ba347 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 1 Sep 2011 15:04:33 +0100 Subject: Fix comparison of absolute, unclean paths in QDir QDir::operator== was creating a clean absolute path for comparison purposes if the original path was relative. However original absolute paths were trusted, even though they could be unclean. Now they are checked for cleanliness first. Task-Number: QTBUG-19995 Task-Number: QTBUG-20495 Change-Id: I047a1a40ae5151e4604085e4ac87f30a4e4979c4 Reviewed-on: http://codereview.qt.nokia.com/4099 Reviewed-by: Qt Sanity Bot Reviewed-by: Prasanth Ullattil --- src/corelib/io/qdir.cpp | 2 +- src/corelib/io/qfilesystementry.cpp | 31 +++++++++++++++++++++ src/corelib/io/qfilesystementry_p.h | 1 + tests/auto/qdir/tst_qdir.cpp | 13 +++++++++ .../auto/qfilesystementry/tst_qfilesystementry.cpp | 32 ++++++++++++++++++++++ 5 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index c0c62e1..3271148 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -198,7 +198,7 @@ inline void QDirPrivate::resolveAbsoluteEntry() const QString absoluteName; if (fileEngine.isNull()) { - if (!dirEntry.isRelative()) { + if (!dirEntry.isRelative() && dirEntry.isClean()) { absoluteDirEntry = dirEntry; return; } diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index bb7cb4e..2f37542 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -380,4 +380,35 @@ void QFileSystemEntry::findFileNameSeparators() const } } +bool QFileSystemEntry::isClean() const +{ + resolveFilePath(); + int dots = 0; + bool dotok = true; // checking for ".." or "." starts to relative paths + bool slashok = true; + for (QString::const_iterator iter = m_filePath.constBegin(); iter != m_filePath.constEnd(); iter++) { + if (*iter == QLatin1Char('/')) { + if (dots == 1 || dots == 2) + return false; // path contains "./" or "../" + if (!slashok) + return false; // path contains "//" + dots = 0; + dotok = true; + slashok = false; + } else if (dotok) { + slashok = true; + if (*iter == QLatin1Char('.')) { + dots++; + if (dots > 2) + dotok = false; + } else { + //path element contains a character other than '.', it's clean + dots = 0; + dotok = false; + } + } + } + return (dots != 1 && dots != 2); // clean if path doesn't end in . or .. +} + QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h index 34b083a..8d524c0 100644 --- a/src/corelib/io/qfilesystementry_p.h +++ b/src/corelib/io/qfilesystementry_p.h @@ -91,6 +91,7 @@ public: QString completeSuffix() const; bool isAbsolute() const; bool isRelative() const; + bool isClean() const; #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) bool isDriveRoot() const; diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index 419eaae..7e5ec79 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -1133,6 +1133,11 @@ void tst_QDir::absolutePath_data() QTest::newRow("4") << "c:/machine/share/dir1" << "c:/machine/share/dir1"; QTest::newRow("5") << "c:\\machine\\share\\dir1" << "c:/machine/share/dir1"; #endif + //test dirty paths are cleaned (QTBUG-19995) + QTest::newRow("/home/qt/.") << QDir::rootPath() + "home/qt/." << QDir::rootPath() + "home/qt"; + QTest::newRow("/system/data/../config") << QDir::rootPath() + "system/data/../config" << QDir::rootPath() + "system/config"; + QTest::newRow("//home//qt/") << QDir::rootPath() + "/home//qt/" << QDir::rootPath() + "home/qt"; + QTest::newRow("foo/../bar") << "foo/../bar" << QDir::currentPath() + "/bar"; QTest::newRow("resource") << ":/prefix/foo.bar" << ":/prefix/foo.bar"; } @@ -1942,6 +1947,14 @@ void tst_QDir::equalityOperator_data() << "./entrylist" << "*.cpp" << int(QDir::Name) << int(QDir::Files) << true; + QTest::newRow("QTBUG-20495") << QDir::currentPath() + "/entrylist/.." << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << "." << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << true; + + QTest::newRow("QTBUG-20495-root") << QDir::rootPath() + "tmp/.." << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << QDir::rootPath() << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << true; + QTest::newRow("diff-filters") << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files) << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Dirs) << false; diff --git a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp index 016bcbf..2daabee 100644 --- a/tests/auto/qfilesystementry/tst_qfilesystementry.cpp +++ b/tests/auto/qfilesystementry/tst_qfilesystementry.cpp @@ -68,6 +68,8 @@ private slots: void absoluteOrRelative_data(); void absoluteOrRelative(); #endif + void isClean_data(); + void isClean(); }; #if defined(WIN_STUFF) @@ -383,5 +385,35 @@ void tst_QFileSystemEntry::absoluteOrRelative() } #endif +void tst_QFileSystemEntry::isClean_data() +{ + QTest::addColumn("path"); + QTest::addColumn("isClean"); + + QTest::newRow("simple") << "foo" << true; + QTest::newRow("complex") << "/foo/bar/bz" << true; + QTest::newRow(".file") << "/foo/.file" << true; + QTest::newRow("..file") << "/foo/..file" << true; + QTest::newRow("...") << "/foo/.../bar" << true; + QTest::newRow("./") << "./" << false; + QTest::newRow("../") << "../" << false; + QTest::newRow(".") << "." << false; + QTest::newRow("..") << ".." << false; + QTest::newRow("/.") << "/." << false; + QTest::newRow("/..") << "/.." << false; + QTest::newRow("/../") << "foo/../bar" << false; + QTest::newRow("/./") << "foo/./bar" << false; + QTest::newRow("//") << "foo//bar" << false; +} + +void tst_QFileSystemEntry::isClean() +{ + QFETCH(QString, path); + QFETCH(bool, isClean); + + QFileSystemEntry fi(path); + QCOMPARE(fi.isClean(), isClean); +} + QTEST_MAIN(tst_QFileSystemEntry) #include -- cgit v0.12 From 4a6617b83612d79c8557102c9d313c28aee2aa0e Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 2 Sep 2011 18:39:16 +0100 Subject: Fix compile error on MSVC2008 Change-Id: I4f6192b9db601076688b52bfd794ea80a7346729 Reviewed-on: http://codereview.qt.nokia.com/4153 Reviewed-by: Qt Sanity Bot Reviewed-by: Prasanth Ullattil --- tests/auto/qfileinfo/tst_qfileinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index c7d9979..4e4b92d 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -1395,7 +1395,7 @@ void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data() wchar_t errstr[0x100]; DWORD count = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, 0, err, 0, errstr, 0x100, 0); - QString error(QString::fromUtf16(errstr, count)); + QString error(QString::fromWCharArray (errstr, count)); qWarning() << error; //we need at least one data set for the test not to assert fail when skipping _data function QDir target("target"); -- cgit v0.12 From ef774ee93cb561d072137f2a11c2d347bedf6342 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 2 Sep 2011 18:40:45 +0100 Subject: Restore Qt4.7 behaviour of QFileInfo::absolute(File)Path Many applications relied on the undefined behaviour that the filesystem engines returned clean paths (despite the documentation stating that they may not), and consequently suffered regressions with Qt 4.8. Unix paths are once again cleaned if necessary. Windows/Symbian paths were already cleaned, but now use the utility function to check if a path is dirty, to avoid duplicated code. Task-number: QTBUG-19995 Change-Id: If8c18469f149291c9d079ae3da23bc2087bbd49a Reviewed-on: http://codereview.qt.nokia.com/4154 Reviewed-by: Qt Sanity Bot Reviewed-by: Prasanth Ullattil --- src/corelib/io/qfilesystemengine_symbian.cpp | 4 +--- src/corelib/io/qfilesystemengine_unix.cpp | 2 +- src/corelib/io/qfilesystemengine_win.cpp | 6 +----- tests/auto/qfileinfo/tst_qfileinfo.cpp | 10 +++++++++- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_symbian.cpp b/src/corelib/io/qfilesystemengine_symbian.cpp index 18c52cb..c8c1dfd 100644 --- a/src/corelib/io/qfilesystemengine_symbian.cpp +++ b/src/corelib/io/qfilesystemengine_symbian.cpp @@ -114,9 +114,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) { QString orig = entry.filePath(); const bool isAbsolute = entry.isAbsolute(); - const bool isDirty = (orig.contains(QLatin1String("/../")) || orig.contains(QLatin1String("/./")) || - orig.contains(QLatin1String("//")) || - orig.endsWith(QLatin1String("/..")) || orig.endsWith(QLatin1String("/."))); + const bool isDirty = !entry.isClean(); if (isAbsolute && !isDirty) return entry; diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index b0ebfbd..cfb17de 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -223,7 +223,7 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry, //static QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) { - if (entry.isAbsolute()) + if (entry.isAbsolute() && entry.isClean()) return entry; QByteArray orig = entry.nativeFilePath(); diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 764ee6d..031d64b 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -508,11 +508,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) if (!entry.isRelative()) { #if !defined(Q_OS_WINCE) - if (entry.isAbsolute() - && !entry.filePath().contains(QLatin1String("/../")) - && !entry.filePath().contains(QLatin1String("/./")) - && !entry.filePath().endsWith(QLatin1String("/..")) - && !entry.filePath().endsWith(QLatin1String("/."))) { + if (entry.isAbsolute() && entry.isClean()) { ret = entry.filePath(); } else { ret = QDir::fromNativeSeparators(nativeAbsoluteFilePath(entry.filePath())); diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp index 4e4b92d..d7d57f6 100644 --- a/tests/auto/qfileinfo/tst_qfileinfo.cpp +++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp @@ -482,6 +482,11 @@ void tst_QFileInfo::absolutePath_data() QTest::newRow("c:\\autoexec.bat") << "c:\\autoexec.bat" << "C:/" << "autoexec.bat"; #endif + QTest::newRow("QTBUG-19995.1") << drivePrefix + "/System/Library/StartupItems/../Frameworks" + << drivePrefix + "/System/Library" + << "Frameworks"; + QTest::newRow("QTBUG-19995.2") << drivePrefix + "/System/Library/StartupItems/../Frameworks/" + << drivePrefix + "/System/Library/Frameworks" << ""; } void tst_QFileInfo::absolutePath() @@ -503,6 +508,7 @@ void tst_QFileInfo::absFilePath_data() QTest::newRow("relativeFile") << "tmp.txt" << QDir::currentPath() + "/tmp.txt"; QTest::newRow("relativeFileInSubDir") << "temp/tmp.txt" << QDir::currentPath() + "/" + "temp/tmp.txt"; + QString drivePrefix; #if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN) QString curr = QDir::currentPath(); @@ -511,7 +517,7 @@ void tst_QFileInfo::absFilePath_data() QTest::newRow("absFilePath") << "c:\\home\\andy\\tmp.txt" << "C:/home/andy/tmp.txt"; // Make sure drive-relative paths return correct absolute paths (task 255326) - QString drivePrefix = QDir::currentPath().left(2); + drivePrefix = QDir::currentPath().left(2); QString nonCurrentDrivePrefix = drivePrefix.left(1).compare("X", Qt::CaseInsensitive) == 0 ? QString("Y:") : QString("X:"); @@ -521,6 +527,8 @@ void tst_QFileInfo::absFilePath_data() #else QTest::newRow("absFilePath") << "/home/andy/tmp.txt" << "/home/andy/tmp.txt"; #endif + QTest::newRow("QTBUG-19995") << drivePrefix + "/System/Library/StartupItems/../Frameworks" + << drivePrefix + "/System/Library/Frameworks"; } void tst_QFileInfo::absFilePath() -- cgit v0.12 From 64adbd0c5775f97343afbe0e7b5fde0d70bdaedd Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Mon, 5 Sep 2011 12:53:49 +0200 Subject: QSslCertificate: block all DigiNotar (intermediate and root) certs and do not only check leaf certificates, but all intermediates and the root. Tested manually with the cross-signed intermediates. Reviewed-by: Richard J. Moore --- src/network/ssl/qsslcertificate.cpp | 27 +++++++++++++++++++++++++-- src/network/ssl/qsslsocket_openssl.cpp | 15 +++++++++------ 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index ab09932..2a2ad55 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -792,15 +792,38 @@ static const char *certificate_blacklist[] = { "92:39:d5:34:8f:40:d1:69:5a:74:54:70:e1:f2:3f:43", "addons.mozilla.org", // Comodo "b0:b7:13:3e:d0:96:f9:b5:6f:ae:91:c8:74:bd:3a:c0", "login.live.com", // Comodo "d8:f3:5f:4e:b7:87:2b:2d:ab:06:92:e3:15:38:2f:b0", "global trustee", // Comodo - "05:e2:e6:a4:cd:09:ea:54:d6:65:b0:75:fe:22:a2:56", "*.google.com", // DigiNotar + + "05:e2:e6:a4:cd:09:ea:54:d6:65:b0:75:fe:22:a2:56", "*.google.com", // leaf certificate issued by DigiNotar + "0c:76:da:9c:91:0c:4e:2c:9e:fe:15:d0:58:93:3c:4c", "DigiNotar Root CA", // DigiNotar root + "f1:4a:13:f4:87:2b:56:dc:39:df:84:ca:7a:a1:06:49", "DigiNotar Services CA", // DigiNotar intermediate signed by DigiNotar Root + "36:16:71:55:43:42:1b:9d:e6:cb:a3:64:41:df:24:38", "DigiNotar Services 1024 CA", // DigiNotar intermediate signed by DigiNotar Root + "0a:82:bd:1e:14:4e:88:14:d7:5b:1a:55:27:be:bf:3e", "DigiNotar Root CA G2", // other DigiNotar Root CA + "a4:b6:ce:e3:2e:d3:35:46:26:3c:b3:55:3a:a8:92:21", "CertiID Enterprise Certificate Authority", // DigiNotar intermediate signed by "DigiNotar Root CA G2" + "5b:d5:60:9c:64:17:68:cf:21:0e:35:fd:fb:05:ad:41", "DigiNotar Qualified CA", // DigiNotar intermediate signed by DigiNotar Root + + "1184640176", "DigiNotar Services 1024 CA", // DigiNotar intermediate cross-signed by Entrust + "120000525", "DigiNotar Cyber CA", // DigiNotar intermediate cross-signed by CyberTrust + "120000505", "DigiNotar Cyber CA", // DigiNotar intermediate cross-signed by CyberTrust + "120000515", "DigiNotar Cyber CA", // DigiNotar intermediate cross-signed by CyberTrust + "20015536", "DigiNotar PKIoverheid CA Overheid en Bedrijven", // DigiNotar intermediate cross-signed by the Dutch government + "20001983", "DigiNotar PKIoverheid CA Organisatie - G2", // DigiNotar intermediate cross-signed by the Dutch government + "d6:d0:29:77:f1:49:fd:1a:83:f2:b9:ea:94:8c:5c:b4", "DigiNotar Extended Validation CA", // DigiNotar intermediate signed by DigiNotar EV Root + "1e:7d:7a:53:3d:45:30:41:96:40:0f:71:48:1f:45:04", "DigiNotar Public CA 2025", // DigiNotar intermediate +// "(has not been seen in the wild so far)", "DigiNotar Public CA - G2", // DigiNotar intermediate +// "(has not been seen in the wild so far)", "Koninklijke Notariele Beroepsorganisatie CA", // compromised during DigiNotar breach +// "(has not been seen in the wild so far)", "Stichting TTP Infos CA," // compromised during DigiNotar breach + "1184640175", "DigiNotar Root CA", // DigiNotar intermediate cross-signed by Entrust + "1184644297", "DigiNotar Root CA", // DigiNotar intermediate cross-signed by Entrust 0 }; bool QSslCertificatePrivate::isBlacklisted(const QSslCertificate &certificate) { for (int a = 0; certificate_blacklist[a] != 0; a++) { + QString blacklistedCommonName = QString::fromUtf8(certificate_blacklist[(a+1)]); if (certificate.serialNumber() == certificate_blacklist[a++] && - certificate.subjectInfo(QSslCertificate::CommonName) == QString::fromUtf8(certificate_blacklist[a])) + (certificate.subjectInfo(QSslCertificate::CommonName) == blacklistedCommonName || + certificate.issuerInfo(QSslCertificate::CommonName) == blacklistedCommonName)) return true; } return false; diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 5a606af..8e53974 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -1246,12 +1246,15 @@ bool QSslSocketBackendPrivate::startHandshake() // Start translating errors. QList errors; - if (QSslCertificatePrivate::isBlacklisted(configuration.peerCertificate)) { - QSslError error(QSslError::CertificateBlacklisted, configuration.peerCertificate); - errors << error; - emit q->peerVerifyError(error); - if (q->state() != QAbstractSocket::ConnectedState) - return false; + // check the whole chain for blacklisting (including root, as we check for subjectInfo and issuer) + foreach (const QSslCertificate &cert, configuration.peerCertificateChain) { + if (QSslCertificatePrivate::isBlacklisted(cert)) { + QSslError error(QSslError::CertificateBlacklisted, cert); + errors << error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } } bool doVerifyPeer = configuration.peerVerifyMode == QSslSocket::VerifyPeer -- cgit v0.12 From ad35d25e78c8252a72108a4ba931934047c4707e Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 6 Sep 2011 16:43:29 +0100 Subject: Merge fixes for QDir::operator== There were two fixes in 4.8 which each fixed a part of the problem. Comparing canonical paths is more correct, but is only possible where both directories exist. If neither directory exists, then compare absolute paths instead. Changed a regression test, because /tmp is a symbolic link on MacOS. I.E. "/tmp/.." is canonically "/private" and not "/" as expected. Task-Number: QTBUG-20495 Reviewed-By: joao --- src/corelib/io/qdir.cpp | 15 +++++++++++++-- tests/auto/qdir/tst_qdir.cpp | 22 +++++++++++++++++++++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 3271148..9081e31 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -1638,8 +1638,19 @@ bool QDir::operator==(const QDir &dir) const if (d->dirEntry.filePath() == other->dirEntry.filePath()) return true; - // Fallback to expensive canonical path computation - return canonicalPath().compare(dir.canonicalPath(), sensitive) == 0; + if (exists()) { + if (!dir.exists()) + return false; //can't be equal if only one exists + // Both exist, fallback to expensive canonical path computation + return canonicalPath().compare(dir.canonicalPath(), sensitive) == 0; + } else { + if (dir.exists()) + return false; //can't be equal if only one exists + // Neither exists, compare absolute paths rather than canonical (which would be empty strings) + d->resolveAbsoluteEntry(); + other->resolveAbsoluteEntry(); + return d->absoluteDirEntry.filePath().compare(other->absoluteDirEntry.filePath(), sensitive) == 0; + } } return false; } diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index 7e5ec79..9693480 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -1951,10 +1951,30 @@ void tst_QDir::equalityOperator_data() << "." << "*.cpp" << int(QDir::Name) << int(QDir::Files) << true; - QTest::newRow("QTBUG-20495-root") << QDir::rootPath() + "tmp/.." << "*.cpp" << int(QDir::Name) << int(QDir::Files) + //need a path in the root directory that is unlikely to be a symbolic link. +#if defined (Q_OS_WIN) + QString pathinroot("c:/windows/.."); +#elif defined (Q_OS_SYMBIAN) + QString pathinroot("c:/data/.."); +#else + QString pathinroot("/sbin/.."); +#endif + QTest::newRow("QTBUG-20495-root") << pathinroot << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << QDir::rootPath() << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << true; + + QTest::newRow("slashdot") << QDir::rootPath() + "." << "*.cpp" << int(QDir::Name) << int(QDir::Files) << QDir::rootPath() << "*.cpp" << int(QDir::Name) << int(QDir::Files) << true; + QTest::newRow("slashdotslash") << QDir::rootPath() + "./" << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << QDir::rootPath() << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << true; + + QTest::newRow("nonexistantpaths") << "dir-that-dont-exist" << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << "another-dir-that-dont-exist" << "*.cpp" << int(QDir::Name) << int(QDir::Files) + << false; + QTest::newRow("diff-filters") << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Files) << SRCDIR << "*.cpp" << int(QDir::Name) << int(QDir::Dirs) << false; -- cgit v0.12