diff options
-rw-r--r-- | src/libs/kdtools/updatefinder.cpp | 56 | ||||
-rw-r--r-- | tests/auto/installer/compareversion/compareversion.pro | 6 | ||||
-rw-r--r-- | tests/auto/installer/compareversion/tst_compareversion.cpp | 93 | ||||
-rw-r--r-- | tests/auto/installer/installer.pro | 1 | ||||
-rw-r--r-- | tools/common/repositorygen.cpp | 5 |
5 files changed, 146 insertions, 15 deletions
diff --git a/src/libs/kdtools/updatefinder.cpp b/src/libs/kdtools/updatefinder.cpp index ec1be8a4e..b64f922c3 100644 --- a/src/libs/kdtools/updatefinder.cpp +++ b/src/libs/kdtools/updatefinder.cpp @@ -590,34 +590,62 @@ int KDUpdater::compareVersion(const QString &v1, const QString &v2) if (v1 == v2) return 0; - // Split version numbers across "." - const QStringList v1_comps = v1.split(QRegExp(QLatin1String( "\\.|-"))); - const QStringList v2_comps = v2.split(QRegExp(QLatin1String( "\\.|-"))); + // Split version components across ".", "-" or "_" + QStringList v1_comps = v1.split(QRegExp(QLatin1String( "\\.|-|_"))); + QStringList v2_comps = v2.split(QRegExp(QLatin1String( "\\.|-|_"))); // Check each component of the version int index = 0; while (true) { - if (index == v1_comps.count() && index < v2_comps.count()) - return -1; - if (index < v1_comps.count() && index == v2_comps.count()) - return +1; + bool v1_ok = false; + bool v2_ok = false; + + if (index == v1_comps.count() && index < v2_comps.count()) { + v2_comps.at(index).toInt(&v2_ok); + return v2_ok ? -1 : +1; + } + if (index < v1_comps.count() && index == v2_comps.count()) { + v1_comps.at(index).toInt(&v1_ok); + return v1_ok ? +1 : -1; + } if (index >= v1_comps.count() || index >= v2_comps.count()) break; - bool v1_ok, v2_ok; - int v1_comp = v1_comps[index].toInt(&v1_ok); - int v2_comp = v2_comps[index].toInt(&v2_ok); + int v1_comp = v1_comps.at(index).toInt(&v1_ok); + int v2_comp = v2_comps.at(index).toInt(&v2_ok); if (!v1_ok) { - if (v1_comps[index] == QLatin1String("x")) + if (v1_comps.at(index) == QLatin1String("x")) return 0; } if (!v2_ok) { - if (v2_comps[index] == QLatin1String("x")) + if (v2_comps.at(index) == QLatin1String("x")) return 0; } - if (!v1_ok && !v2_ok) - return v1_comps[index].compare(v2_comps[index]); + if (!v1_ok && !v2_ok) { + // try remove equal start + int i = 0; + while (i < v1_comps.at(index).size() + && i < v2_comps.at(index).size() + && v1_comps.at(index).at(i) == v2_comps.at(index).at(i)) { + ++i; + } + if (i > 0) { + v1_comps[index] = v1_comps.at(index).mid(i); + v2_comps[index] = v2_comps.at(index).mid(i); + // compare again + continue; + } + } + if (!v1_ok || !v2_ok) { + int res = v1_comps.at(index).compare(v2_comps.at(index)); + if (res == 0) { + // v1_comps.at(index) == v2_comps(index) + ++index; + continue; + } + return res > 0 ? +1 : -1; + } if (v1_comp < v2_comp) return -1; diff --git a/tests/auto/installer/compareversion/compareversion.pro b/tests/auto/installer/compareversion/compareversion.pro new file mode 100644 index 000000000..4f941df4a --- /dev/null +++ b/tests/auto/installer/compareversion/compareversion.pro @@ -0,0 +1,6 @@ +include(../../qttest.pri) + +QT -= gui + +SOURCES += tst_compareversion.cpp + diff --git a/tests/auto/installer/compareversion/tst_compareversion.cpp b/tests/auto/installer/compareversion/tst_compareversion.cpp new file mode 100644 index 000000000..24ebe9ba6 --- /dev/null +++ b/tests/auto/installer/compareversion/tst_compareversion.cpp @@ -0,0 +1,93 @@ +/************************************************************************** +** +** Copyright (C) 2017 Konstantin Podsvirov <konstantin@podsvirov.pro> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Installer Framework. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +**************************************************************************/ + +#include "updater.h" + +#include <QTest> + +class tst_CompareVersion : public QObject +{ + Q_OBJECT + +private slots: + void compareVersion(); + void compareVersionX(); + void compareVersionAll(); + void compareVersionExtra(); +}; + +void tst_CompareVersion::compareVersion() +{ + QCOMPARE(KDUpdater::compareVersion("2.0", "2.1"), -1); + QCOMPARE(KDUpdater::compareVersion("2.1", "2.0"), +1); + QCOMPARE(KDUpdater::compareVersion("2.0", "2.0"), 0); + QCOMPARE(KDUpdater::compareVersion("2.1", "2.1"), 0); + + QCOMPARE(KDUpdater::compareVersion("2.0.12.4", "2.1.10.4"), -1); +} + +void tst_CompareVersion::compareVersionX() +{ + QCOMPARE(KDUpdater::compareVersion("2.0", "2.x"), 0); + QCOMPARE(KDUpdater::compareVersion("2.x", "2.0"), 0); + + QCOMPARE(KDUpdater::compareVersion("2.0.12.x", "2.0.x"), 0); + QCOMPARE(KDUpdater::compareVersion("2.1.12.x", "2.0.x"), +1); + QCOMPARE(KDUpdater::compareVersion("2.1.12.x", "2.x"), 0); + QCOMPARE(KDUpdater::compareVersion("2.x", "2.1.12.x"), 0); +} + +void tst_CompareVersion::compareVersionAll() +{ + QCOMPARE(KDUpdater::compareVersion("version-1", "version-2"), -1); + + QCOMPARE(KDUpdater::compareVersion("v2.0", "v2.x"), 0); + QCOMPARE(KDUpdater::compareVersion("v2.x", "v2.0"), 0); + + QCOMPARE(KDUpdater::compareVersion("v2.0-alpha", "v2.0-alpha"), 0); + + QCOMPARE(KDUpdater::compareVersion("v2.0-alpha", "v2.0-beta"), -1); + QCOMPARE(KDUpdater::compareVersion("v2.0-beta", "v2.0-alpha"), +1); + + QCOMPARE(KDUpdater::compareVersion("v2.0-rc1", "v2.0-beta"), +1); + QCOMPARE(KDUpdater::compareVersion("v2.0-rc1", "v2.0-rc2"), -1); + QCOMPARE(KDUpdater::compareVersion("v2.0-rc2", "v2.0-rc11"), -1); + QCOMPARE(KDUpdater::compareVersion("v2.0-rc22", "v2.0-rc2"), +1); + + QCOMPARE(KDUpdater::compareVersion("v2.0", "v2.0-rc3"), +1); +} + +void tst_CompareVersion::compareVersionExtra() +{ + QCOMPARE(KDUpdater::compareVersion("OpenSSL_1_0_2k", "OpenSSL_1_0_2l"), -1); + QCOMPARE(KDUpdater::compareVersion("OpenSSL_1_1_0f", "OpenSSL_1_0_2k"), +1); +} + +QTEST_MAIN(tst_CompareVersion) + +#include "tst_compareversion.moc" diff --git a/tests/auto/installer/installer.pro b/tests/auto/installer/installer.pro index ba2dd0244..01a26da47 100644 --- a/tests/auto/installer/installer.pro +++ b/tests/auto/installer/installer.pro @@ -3,6 +3,7 @@ TEMPLATE = subdirs SUBDIRS += \ settings \ repository \ + compareversion\ componentmodel \ fakestopprocessforupdateoperation \ messageboxhandler \ diff --git a/tools/common/repositorygen.cpp b/tools/common/repositorygen.cpp index 1c4a877c0..908020ea4 100644 --- a/tools/common/repositorygen.cpp +++ b/tools/common/repositorygen.cpp @@ -481,7 +481,10 @@ PackageInfoVector QInstallerTools::createListOfPackages(const QStringList &packa PackageInfo info; info.name = it->fileName(); info.version = packageElement.firstChildElement(QLatin1String("Version")).text(); - if (!QRegExp(QLatin1String("[0-9]+((\\.|-)[0-9]+)*")).exactMatch(info.version)) { + // Version cannot start with comparison characters, be an empty string + // or have whitespaces at the beginning or at the end + if (!QRegExp(QLatin1String("(?![<=>\\s]+)(.+)")).exactMatch(info.version) || + (info.version != info.version.trimmed())) { if (ignoreInvalidPackages) continue; throw QInstaller::Error(QString::fromLatin1("Component version for \"%1\" is invalid! <Version>%2</Version>") |