diff options
Diffstat (limited to 'tests/auto/corelib/tools/qcryptographichash')
3 files changed, 210 insertions, 64 deletions
diff --git a/tests/auto/corelib/tools/qcryptographichash/CMakeLists.txt b/tests/auto/corelib/tools/qcryptographichash/CMakeLists.txt index d8de1798f3..8a0c08fcad 100644 --- a/tests/auto/corelib/tools/qcryptographichash/CMakeLists.txt +++ b/tests/auto/corelib/tools/qcryptographichash/CMakeLists.txt @@ -1,9 +1,16 @@ -# Generated from qcryptographichash.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qcryptographichash Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qcryptographichash LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + # Collect test data file(GLOB_RECURSE test_data_glob RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} @@ -16,20 +23,6 @@ qt_internal_add_test(tst_qcryptographichash TESTDATA ${test_data} ) -## Scopes: -##################################################################### - -if(ANDROID) - # Resources: - set(testdata_resource_files - "data/2c1517dad3678f03917f15849b052fd5.md5" - "data/d41d8cd98f00b204e9800998ecf8427e.md5" - ) - - qt_internal_add_resource(tst_qcryptographichash "testdata" - PREFIX - "/" - FILES - ${testdata_resource_files} - ) +if(QT_FEATURE_sanitize_address) + set_property(TEST tst_qcryptographichash APPEND PROPERTY ENVIRONMENT "QTEST_FUNCTION_TIMEOUT=900000") endif() diff --git a/tests/auto/corelib/tools/qcryptographichash/testdata.qrc b/tests/auto/corelib/tools/qcryptographichash/testdata.qrc deleted file mode 100644 index 8f7bcea63c..0000000000 --- a/tests/auto/corelib/tools/qcryptographichash/testdata.qrc +++ /dev/null @@ -1,6 +0,0 @@ -<RCC> - <qresource prefix="/"> - <file>data/2c1517dad3678f03917f15849b052fd5.md5</file> - <file>data/d41d8cd98f00b204e9800998ecf8427e.md5</file> - </qresource> -</RCC> diff --git a/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp b/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp index 6b61349d01..c08afd67c4 100644 --- a/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp +++ b/tests/auto/corelib/tools/qcryptographichash/tst_qcryptographichash.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtCore/QCoreApplication> @@ -33,9 +8,7 @@ #include <QCryptographicHash> #include <QtCore/QMetaEnum> -#if QT_CONFIG(cxx11_future) -# include <thread> -#endif +#include <thread> Q_DECLARE_METATYPE(QCryptographicHash::Algorithm) @@ -50,16 +23,24 @@ private slots: void sha1(); void sha3_data(); void sha3(); + void keccak(); + void keccak_data(); void blake2_data(); void blake2(); void files_data(); void files(); void hashLength_data(); void hashLength(); + void addDataAcceptsNullByteArrayView_data() { hashLength_data(); } + void addDataAcceptsNullByteArrayView(); + void move(); + void swap(); // keep last void moreThan4GiBOfData_data(); void moreThan4GiBOfData(); + void keccakBufferOverflow(); private: + void ensureLargeData(); std::vector<char> large; }; @@ -74,6 +55,8 @@ void tst_QCryptographicHash::repeated_result() QCryptographicHash::Algorithm _algo = QCryptographicHash::Algorithm(algo); QCryptographicHash hash(_algo); + QCOMPARE_EQ(hash.algorithm(), _algo); + QFETCH(QByteArray, first); hash.addData(first); @@ -169,6 +152,27 @@ void tst_QCryptographicHash::intermediary_result_data() << QByteArray("abc") << QByteArray("abc") << QByteArray::fromHex("B751850B1A57168A5693CD924B6B096E08F621827444F70D884F5D0240D2712E10E116E9192AF3C91A7EC57647E3934057340B4CF408D5A56592F8274EEC53F0") << QByteArray::fromHex("BB582DA40D15399ACF62AFCBBD6CFC9EE1DD5129B1EF9935DD3B21668F1A73D7841018BE3B13F281C3A8E9DA7EDB60F57B9F9F1C04033DF4CE3654B7B2ADB310"); + + QTest::newRow("keccak_224_abc_abc") + << int(QCryptographicHash::Keccak_224) + << QByteArray("abc") << QByteArray("abc") + << QByteArray::fromHex("c30411768506ebe1c2871b1ee2e87d38df342317300a9b97a95ec6a8") + << QByteArray::fromHex("048330e7c7c8b4a41ab713b3a6f958d77b8cf3ee969930f1584dd550"); + QTest::newRow("keccak_256_abc_abc") + << int(QCryptographicHash::Keccak_256) + << QByteArray("abc") << QByteArray("abc") + << QByteArray::fromHex("4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45") + << QByteArray::fromHex("9f0adad0a59b05d2e04a1373342b10b9eb16c57c164c8a3bfcbf46dccee39a21"); + QTest::newRow("keccak_384_abc_abc") + << int(QCryptographicHash::Keccak_384) + << QByteArray("abc") << QByteArray("abc") + << QByteArray::fromHex("f7df1165f033337be098e7d288ad6a2f74409d7a60b49c36642218de161b1f99f8c681e4afaf31a34db29fb763e3c28e") + << QByteArray::fromHex("d733b87d392d270889d3da23ae113f349e25574b445f319cde4cd3f877c753e9e3c65980421339b3a131457ff393939f"); + QTest::newRow("keccak_512_abc_abc") + << int(QCryptographicHash::Keccak_512) + << QByteArray("abc") << QByteArray("abc") + << QByteArray::fromHex("18587dc2ea106b9a1563e32b3312421ca164c7f1f07bc922a9c83d77cea3a1e5d0c69910739025372dc14ac9642629379540c17e2a65b19d77aa511a9d00bb96") + << QByteArray::fromHex("a7c392d2a42155761ca76bddde1c47d55486b007edf465397bfb9dfa74d11c8f0d7c86cd29415283f1b5e7f655cec25b869c9e9c33a8986f0b38542fb12bfb93"); } void tst_QCryptographicHash::intermediary_result() @@ -275,6 +279,68 @@ void tst_QCryptographicHash::sha3() QCOMPARE(result, expectedResult); } +void tst_QCryptographicHash::keccak_data() +{ + QTest::addColumn<QCryptographicHash::Algorithm>("algorithm"); + QTest::addColumn<QByteArray>("data"); + QTest::addColumn<QByteArray>("expectedResult"); + +#define ROW(Tag, Algorithm, Input, Result) \ + QTest::newRow(Tag) << Algorithm << QByteArrayLiteral(Input) << QByteArray::fromHex(Result) + + ROW("keccak_224_pangram", + QCryptographicHash::Keccak_224, + "The quick brown fox jumps over the lazy dog", + "310aee6b30c47350576ac2873fa89fd190cdc488442f3ef654cf23fe"); + + ROW("keccak_224_pangram_dot", + QCryptographicHash::Keccak_224, + "The quick brown fox jumps over the lazy dog.", + "c59d4eaeac728671c635ff645014e2afa935bebffdb5fbd207ffdeab"); + + ROW("keccak_256_pangram", + QCryptographicHash::Keccak_256, + "The quick brown fox jumps over the lazy dog", + "4d741b6f1eb29cb2a9b9911c82f56fa8d73b04959d3d9d222895df6c0b28aa15"); + + ROW("keccak_256_pangram_dot", + QCryptographicHash::Keccak_256, + "The quick brown fox jumps over the lazy dog.", + "578951e24efd62a3d63a86f7cd19aaa53c898fe287d2552133220370240b572d"); + + ROW("keccak_384_pangram", + QCryptographicHash::Keccak_384, + "The quick brown fox jumps over the lazy dog", + "283990fa9d5fb731d786c5bbee94ea4db4910f18c62c03d173fc0a5e494422e8a0b3da7574dae7fa0baf005e504063b3"); + + ROW("keccak_384_pangram_dot", + QCryptographicHash::Keccak_384, + "The quick brown fox jumps over the lazy dog.", + "9ad8e17325408eddb6edee6147f13856ad819bb7532668b605a24a2d958f88bd5c169e56dc4b2f89ffd325f6006d820b"); + + ROW("skeccak_512_pangram", + QCryptographicHash::Keccak_512, + "The quick brown fox jumps over the lazy dog", + "d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609"); + + ROW("keccak_512_pangram_dot", + QCryptographicHash::Keccak_512, + "The quick brown fox jumps over the lazy dog.", + "ab7192d2b11f51c7dd744e7b3441febf397ca07bf812cceae122ca4ded6387889064f8db9230f173f6d1ab6e24b6e50f065b039f799f5592360a6558eb52d760"); + +#undef ROW +} + +void tst_QCryptographicHash::keccak() +{ + QFETCH(QCryptographicHash::Algorithm, algorithm); + QFETCH(QByteArray, data); + QFETCH(QByteArray, expectedResult); + + const auto result = QCryptographicHash::hash(data, algorithm); + QCOMPARE(result, expectedResult); +} + void tst_QCryptographicHash::blake2_data() { QTest::addColumn<QCryptographicHash::Algorithm>("algorithm"); @@ -414,7 +480,7 @@ void tst_QCryptographicHash::hashLength_data() auto metaEnum = QMetaEnum::fromType<QCryptographicHash::Algorithm>(); for (int i = 0, value = metaEnum.value(i); value != -1; value = metaEnum.value(++i)) { auto algorithm = QCryptographicHash::Algorithm(value); - QTest::addRow("%s", metaEnum.valueToKey(value)) << algorithm; + QTest::addRow("%s", metaEnum.key(i)) << algorithm; } } @@ -422,16 +488,81 @@ void tst_QCryptographicHash::hashLength() { QFETCH(const QCryptographicHash::Algorithm, algorithm); - QByteArray output = QCryptographicHash::hash("test", algorithm); - QCOMPARE(QCryptographicHash::hashLength(algorithm), output.length()); + qsizetype expectedSize; + if (algorithm == QCryptographicHash::NumAlgorithms) { + // It's UB to call ::hash() with NumAlgorithms, but hashLength() is + // fine and returns 0 for invalid values: + expectedSize = 0; + } else { + expectedSize = QCryptographicHash::hash("test", algorithm).size(); + } + QCOMPARE(QCryptographicHash::hashLength(algorithm), expectedSize); +} + +void tst_QCryptographicHash::addDataAcceptsNullByteArrayView() +{ + QFETCH(const QCryptographicHash::Algorithm, algorithm); + + if (!QCryptographicHash::supportsAlgorithm(algorithm)) + QSKIP("QCryptographicHash doesn't support this algorithm"); + + QCryptographicHash hash1(algorithm); + hash1.addData("meep"); + hash1.addData(QByteArrayView{}); // after other data + + QCryptographicHash hash2(algorithm); + hash2.addData(QByteArrayView{}); // before any other data + hash2.addData("meep"); + + const auto expected = QCryptographicHash::hash("meep", algorithm); + + QCOMPARE(hash1.resultView(), expected); + QCOMPARE(hash2.resultView(), expected); } -void tst_QCryptographicHash::moreThan4GiBOfData_data() +void tst_QCryptographicHash::move() +{ + QCryptographicHash hash1(QCryptographicHash::Sha1); + hash1.addData("a"); + + // move constructor + auto hash2(std::move(hash1)); + hash2.addData("b"); + + // move assign operator + QCryptographicHash hash3(QCryptographicHash::Sha256); + hash3.addData("no effect on the end result"); + hash3 = std::move(hash2); + hash3.addData("c"); + + QCOMPARE(hash3.resultView(), QByteArray::fromHex("A9993E364706816ABA3E25717850C26C9CD0D89D")); +} + +void tst_QCryptographicHash::swap() +{ + QCryptographicHash hash1(QCryptographicHash::Sha1); + QCryptographicHash hash2(QCryptographicHash::Sha256); + + hash1.addData("da"); + hash2.addData("te"); + + hash1.swap(hash2); + + hash2.addData("ta"); + hash1.addData("st"); + + QCOMPARE(hash2.result(), QCryptographicHash::hash("data", QCryptographicHash::Sha1)); + QCOMPARE(hash1.result(), QCryptographicHash::hash("test", QCryptographicHash::Sha256)); +} + +void tst_QCryptographicHash::ensureLargeData() { #if QT_POINTER_SIZE > 4 QElapsedTimer timer; timer.start(); const size_t GiB = 1024 * 1024 * 1024; + if (large.size() == 4 * GiB + 1) + return; try { large.resize(4 * GiB + 1, '\0'); } catch (const std::bad_alloc &) { @@ -440,7 +571,14 @@ void tst_QCryptographicHash::moreThan4GiBOfData_data() QCOMPARE(large.size(), 4 * GiB + 1); large.back() = '\1'; qDebug("created dataset in %lld ms", timer.elapsed()); +#endif +} +void tst_QCryptographicHash::moreThan4GiBOfData_data() +{ +#if QT_POINTER_SIZE > 4 + if (ensureLargeData(); large.empty()) + return; QTest::addColumn<QCryptographicHash::Algorithm>("algorithm"); auto me = QMetaEnum::fromType<QCryptographicHash::Algorithm>(); auto row = [me] (QCryptographicHash::Algorithm algo) { @@ -465,14 +603,7 @@ void tst_QCryptographicHash::moreThan4GiBOfData() { QFETCH(const QCryptographicHash::Algorithm, algorithm); -# if QT_CONFIG(cxx11_future) using MaybeThread = std::thread; -# else - struct MaybeThread { - std::function<void()> func; - void join() { func(); } - }; -# endif QElapsedTimer timer; timer.start(); @@ -503,5 +634,33 @@ void tst_QCryptographicHash::moreThan4GiBOfData() QCOMPARE(single, chunked); } +void tst_QCryptographicHash::keccakBufferOverflow() +{ +#if QT_POINTER_SIZE == 4 + QSKIP("This is a 64-bit-only test"); +#else + + if (ensureLargeData(); large.empty()) + return; + + QElapsedTimer timer; + timer.start(); + const auto sg = qScopeGuard([&] { + qDebug() << "test finished in" << timer.restart() << "ms"; + }); + + constexpr qsizetype magic = INT_MAX/4; + QCOMPARE_GE(large.size(), size_t(magic + 1)); + + QCryptographicHash hash(QCryptographicHash::Algorithm::Keccak_224); + const auto first = QByteArrayView{large}.first(1); + const auto second = QByteArrayView{large}.sliced(1, magic); + hash.addData(first); + hash.addData(second); + (void)hash.resultView(); + QVERIFY(true); // didn't crash +#endif +} + QTEST_MAIN(tst_QCryptographicHash) #include "tst_qcryptographichash.moc" |