From 24f560aaa2c0a4574697bdc9b7ec41de9815c6de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20E=2E=20Garc=C3=ADa?= Date: Fri, 20 Oct 2017 16:55:02 -0600 Subject: [PATCH] Replace Optional with QVariant --- src/CMakeLists.txt | 1 - src/core/Base32.cpp | 10 +++--- src/core/Base32.h | 4 +-- src/core/Optional.h | 86 -------------------------------------------- src/totp/totp.cpp | 7 ++-- tests/TestBase32.cpp | 66 ++++++++++++++++++++++------------ 6 files changed, 54 insertions(+), 120 deletions(-) delete mode 100644 src/core/Optional.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 28170b162..5255186ea 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -61,7 +61,6 @@ set(keepassx_SOURCES core/Uuid.cpp core/Base32.h core/Base32.cpp - core/Optional.h cli/PasswordInput.cpp cli/PasswordInput.h crypto/Crypto.cpp diff --git a/src/core/Base32.cpp b/src/core/Base32.cpp index 5bd20901d..6fdecccd8 100644 --- a/src/core/Base32.cpp +++ b/src/core/Base32.cpp @@ -40,14 +40,14 @@ constexpr quint8 ASCII_a = static_cast('a'); constexpr quint8 ASCII_z = static_cast('z'); constexpr quint8 ASCII_EQ = static_cast('='); -Optional Base32::decode(const QByteArray& encodedData) +QVariant Base32::decode(const QByteArray& encodedData) { if (encodedData.size() <= 0) { - return Optional(""); + return QVariant::fromValue(QByteArray("")); } if (encodedData.size() % 8 != 0) { - return Optional(); + return QVariant(); } int nPads = 0; @@ -114,7 +114,7 @@ Optional Base32::decode(const QByteArray& encodedData) continue; } else { // illegal character - return Optional(); + return QVariant(); } } } @@ -132,7 +132,7 @@ Optional Base32::decode(const QByteArray& encodedData) } } - return Optional(data); + return QVariant::fromValue(data); } QByteArray Base32::encode(const QByteArray& data) diff --git a/src/core/Base32.h b/src/core/Base32.h index 048828974..204368c52 100644 --- a/src/core/Base32.h +++ b/src/core/Base32.h @@ -24,15 +24,15 @@ #ifndef BASE32_H #define BASE32_H -#include "Optional.h" #include +#include #include class Base32 { public: Base32() = default; - Q_REQUIRED_RESULT static Optional decode(const QByteArray&); + Q_REQUIRED_RESULT static QVariant decode(const QByteArray&); Q_REQUIRED_RESULT static QByteArray encode(const QByteArray&); Q_REQUIRED_RESULT static QByteArray addPadding(const QByteArray&); Q_REQUIRED_RESULT static QByteArray removePadding(const QByteArray&); diff --git a/src/core/Optional.h b/src/core/Optional.h deleted file mode 100644 index 0721daa3d..000000000 --- a/src/core/Optional.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2017 KeePassXC Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 or (at your option) - * version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef OPTIONAL_H -#define OPTIONAL_H - -/* - * This utility class is for providing basic support for an option type. - * It can be replaced by std::optional (C++17) or - * std::experimental::optional (C++11) when they become fully supported - * by all the main compiler toolchains. - */ - -template class Optional -{ -public: - // None - Optional() - : m_hasValue(false) - , m_value(){}; - - // Some T - Optional(const T& value) - : m_hasValue(true) - , m_value(value){}; - - // Copy - Optional(const Optional& other) - : m_hasValue(other.m_hasValue) - , m_value(other.m_value){}; - - const Optional& operator=(const Optional& other) - { - m_hasValue = other.m_hasValue; - m_value = other.m_value; - return *this; - } - - bool operator==(const Optional& other) const - { - if (m_hasValue) - return other.m_hasValue && m_value == other.m_value; - else - return !other.m_hasValue; - } - - bool operator!=(const Optional& other) const - { - return !(*this == other); - } - - bool hasValue() const - { - return m_hasValue; - } - - T valueOr(const T& other) const - { - return m_hasValue ? m_value : other; - } - - Optional static makeOptional(const T& value) - { - return Optional(value); - } - -private: - bool m_hasValue; - T m_value; -}; - -#endif // OPTIONAL_H diff --git a/src/totp/totp.cpp b/src/totp/totp.cpp index 28d808e3a..7a584def2 100644 --- a/src/totp/totp.cpp +++ b/src/totp/totp.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -98,13 +99,13 @@ QString QTotp::generateTotp(const QByteArray key, { quint64 current = qToBigEndian(time / step); - Optional secret = Base32::decode(Base32::sanitizeInput(key)); - if (!secret.hasValue()) { + QVariant secret = Base32::decode(Base32::sanitizeInput(key)); + if (secret.isNull()) { return "Invalid TOTP secret key"; } QMessageAuthenticationCode code(QCryptographicHash::Sha1); - code.setKey(secret.valueOr("")); + code.setKey(secret.toByteArray()); code.addData(QByteArray(reinterpret_cast(¤t), sizeof(current))); QByteArray hmac = code.result(); diff --git a/tests/TestBase32.cpp b/tests/TestBase32.cpp index 3d829d96b..615b356fc 100644 --- a/tests/TestBase32.cpp +++ b/tests/TestBase32.cpp @@ -25,86 +25,102 @@ void TestBase32::testDecode() { // 3 quanta, all upper case + padding QByteArray encodedData = "JBSWY3DPEB3W64TMMQXC4LQ="; - auto data = Base32::decode(encodedData); - QCOMPARE(QString::fromLatin1(data.valueOr("ERROR")), QString("Hello world...")); + QVariant data = Base32::decode(encodedData); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("Hello world...")); // 4 quanta, all upper case encodedData = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ"; data = Base32::decode(encodedData); - QCOMPARE(QString::fromLatin1(data.valueOr("ERROR")), QString("12345678901234567890")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("12345678901234567890")); // 4 quanta, all lower case encodedData = "gezdgnbvgy3tqojqgezdgnbvgy3tqojq"; data = Base32::decode(encodedData); - QCOMPARE(QString::fromLatin1(data.valueOr("ERROR")), QString("12345678901234567890")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("12345678901234567890")); // 4 quanta, mixed upper and lower case encodedData = "Gezdgnbvgy3tQojqgezdGnbvgy3tQojQ"; data = Base32::decode(encodedData); - QCOMPARE(QString::fromLatin1(data.valueOr("ERROR")), QString("12345678901234567890")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("12345678901234567890")); // 1 pad characters encodedData = "ORSXG5A="; data = Base32::decode(encodedData); - QCOMPARE(QString::fromLatin1(data.valueOr("ERROR")), QString("test")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("test")); // 3 pad characters encodedData = "L5PV6==="; data = Base32::decode(encodedData); - QCOMPARE(QString::fromLatin1(data.valueOr("ERROR")), QString("___")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("___")); // 4 pad characters encodedData = "MZXW6IDCMFZA===="; data = Base32::decode(encodedData); - QCOMPARE(QString::fromLatin1(data.valueOr("ERROR")), QString("foo bar")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("foo bar")); // six pad characters encodedData = "MZXW6YTBOI======"; data = Base32::decode(encodedData); - QCOMPARE(QString::fromLatin1(data.valueOr("ERROR")), QString("foobar")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("foobar")); encodedData = "IA======"; data = Base32::decode(encodedData); - QCOMPARE(QString::fromLatin1(data.valueOr("ERROR")), QString("@")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("@")); // error: illegal character encodedData = "1MZXW6YTBOI====="; data = Base32::decode(encodedData); - QCOMPARE(QString::fromLatin1(data.valueOr("ERROR")), QString("ERROR")); + QVERIFY(data.isNull()); // error: missing pad character encodedData = "MZXW6YTBOI====="; data = Base32::decode(encodedData); - QCOMPARE(QString::fromLatin1(data.valueOr("ERROR")), QString("ERROR")); + QVERIFY(data.isNull()); // RFC 4648 test vectors encodedData = ""; data = Base32::decode(encodedData); - QCOMPARE(QString::fromLatin1(data.valueOr("ERROR")), QString("")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("")); encodedData = "MY======"; data = Base32::decode(encodedData); - QCOMPARE(QString::fromLatin1(data.valueOr("ERROR")), QString("f")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("f")); encodedData = "MZXQ===="; data = Base32::decode(encodedData); - QCOMPARE(QString::fromLatin1(data.valueOr("ERROR")), QString("fo")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("fo")); encodedData = "MZXW6==="; data = Base32::decode(encodedData); - QCOMPARE(QString::fromLatin1(data.valueOr("ERROR")), QString("foo")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("foo")); encodedData = "MZXW6YQ="; data = Base32::decode(encodedData); - QCOMPARE(QString::fromLatin1(data.valueOr("ERROR")), QString("foob")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("foob")); encodedData = "MZXW6YTB"; data = Base32::decode(encodedData); - QCOMPARE(QString::fromLatin1(data.valueOr("ERROR")), QString("fooba")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("fooba")); encodedData = "MZXW6YTBOI======"; data = Base32::decode(encodedData); - QCOMPARE(QString::fromLatin1(data.valueOr("ERROR")), QString("foobar")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("foobar")); } void TestBase32::testEncode() @@ -258,21 +274,25 @@ void TestBase32::testSanitizeInput() // sanitize input (white space + missing padding) QByteArray encodedData = "JBSW Y3DP EB3W 64TM MQXC 4LQA"; auto data = Base32::decode(Base32::sanitizeInput(encodedData)); - QCOMPARE(QString::fromLatin1(data.valueOr("ERRROR")), QString("Hello world...")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("Hello world...")); // sanitize input (typo + missing padding) encodedData = "J8SWY3DPE83W64TMMQXC4LQA"; data = Base32::decode(Base32::sanitizeInput(encodedData)); - QCOMPARE(QString::fromLatin1(data.valueOr("ERRROR")), QString("Hello world...")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("Hello world...")); // sanitize input (other illegal characters) encodedData = "J8SWY3D[PE83W64TMMQ]XC!4LQA"; data = Base32::decode(Base32::sanitizeInput(encodedData)); - QCOMPARE(QString::fromLatin1(data.valueOr("ERRROR")), QString("Hello world...")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("Hello world...")); // sanitize input (NUL character) encodedData = "J8SWY3DPE83W64TMMQXC4LQA"; encodedData.insert(3, '\0'); data = Base32::decode(Base32::sanitizeInput(encodedData)); - QCOMPARE(QString::fromLatin1(data.valueOr("ERRROR")), QString("Hello world...")); + QVERIFY(!data.isNull()); + QCOMPARE(data.toString(), QString("Hello world...")); }