From fa8256bb5a36aa18480bc603d538bf07c8464ec7 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 21 May 2024 11:28:40 +0200 Subject: [PATCH] QCryptographicHash: extend hashInto to more than one piece of data This allows use of the noexcept static function in cases where more than one piece of data needs to be hashed, and concatenation of said data would have to allocate memory. Port QUuid to use the new function, allowing to mark the V3 and V5 create functions noexcept. As a drive-by, take QUuid by value in the internal helper function, fixing a Clazy warning. Task-number: QTBUG-125431 Change-Id: I17938f0be44c91085e2aaa5574953f8dceacc990 Reviewed-by: Thiago Macieira --- src/corelib/plugin/quuid.cpp | 14 +++++++------- src/corelib/plugin/quuid.h | 4 ++-- src/corelib/tools/qcryptographichash.cpp | 11 +++++++++-- src/corelib/tools/qcryptographichash.h | 10 ++++++++-- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index 8c3b758aaca..99f8ee30b0d 100644 --- a/src/corelib/plugin/quuid.cpp +++ b/src/corelib/plugin/quuid.cpp @@ -116,12 +116,12 @@ static QUuid _q_uuidFromHex(const char *src) return QUuid(); } -static QUuid createFromName(const QUuid &ns, const QByteArray &baseData, QCryptographicHash::Algorithm algorithm, int version) +static QUuid createFromName(QUuid ns, QByteArrayView baseData, QCryptographicHash::Algorithm algorithm, int version) noexcept { - QCryptographicHash hash(algorithm); - hash.addData(QByteArrayView{ns.toBytes()}); - hash.addData(baseData); - QByteArrayView hashResult = hash.resultView(); + std::byte buffer[20]; + Q_ASSERT(sizeof buffer >= size_t(QCryptographicHash::hashLength(algorithm))); + QByteArrayView hashResult + = QCryptographicHash::hashInto(buffer, {QByteArrayView{ns.toBytes()}, baseData}, algorithm); Q_ASSERT(hashResult.size() >= 16); hashResult.truncate(16); // Sha1 will be too long @@ -570,13 +570,13 @@ QUuid QUuid::fromString(QAnyStringView text) noexcept \sa variant(), version(), createUuidV3() */ #ifndef QT_BOOTSTRAPPED -QUuid QUuid::createUuidV3(const QUuid &ns, const QByteArray &baseData) +QUuid QUuid::createUuidV3(const QUuid &ns, const QByteArray &baseData) noexcept { return createFromName(ns, baseData, QCryptographicHash::Md5, 3); } #endif -QUuid QUuid::createUuidV5(const QUuid &ns, const QByteArray &baseData) +QUuid QUuid::createUuidV5(const QUuid &ns, const QByteArray &baseData) noexcept { return createFromName(ns, baseData, QCryptographicHash::Sha1, 5); } diff --git a/src/corelib/plugin/quuid.h b/src/corelib/plugin/quuid.h index 14029f1abc9..580784723c7 100644 --- a/src/corelib/plugin/quuid.h +++ b/src/corelib/plugin/quuid.h @@ -221,9 +221,9 @@ public: public: static QUuid createUuid(); #ifndef QT_BOOTSTRAPPED - static QUuid createUuidV3(const QUuid &ns, const QByteArray &baseData); + static QUuid createUuidV3(const QUuid &ns, const QByteArray &baseData) noexcept; #endif - static QUuid createUuidV5(const QUuid &ns, const QByteArray &baseData); + static QUuid createUuidV5(const QUuid &ns, const QByteArray &baseData) noexcept; #ifndef QT_BOOTSTRAPPED static inline QUuid createUuidV3(const QUuid &ns, const QString &baseData) { diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp index 3807e32a723..f64f11ee44c 100644 --- a/src/corelib/tools/qcryptographichash.cpp +++ b/src/corelib/tools/qcryptographichash.cpp @@ -1166,22 +1166,29 @@ QByteArray QCryptographicHash::hash(QByteArrayView data, Algorithm method) /*! \since 6.8 + \fn QCryptographicHash::hashInto(QSpan buffer, QSpan data, Algorithm method); + \fn QCryptographicHash::hashInto(QSpan buffer, QSpan data, Algorithm method); + \fn QCryptographicHash::hashInto(QSpan buffer, QSpan data, Algorithm method); \fn QCryptographicHash::hashInto(QSpan buffer, QByteArrayView data, Algorithm method); \fn QCryptographicHash::hashInto(QSpan buffer, QByteArrayView data, Algorithm method); \fn QCryptographicHash::hashInto(QSpan buffer, QByteArrayView data, Algorithm method); Returns the hash of \a data using \a method, using \a buffer to store the result. + If \a data is a span, adds all the byte array views to the hash, in the order given. + The return value will be a sub-span of \a buffer, unless \a buffer is of insufficient size, in which case a null QByteArrayView is returned. \sa hash() */ -QByteArrayView QCryptographicHash::hashInto(QSpan buffer, QByteArrayView data, +QByteArrayView QCryptographicHash::hashInto(QSpan buffer, + QSpan data, Algorithm method) noexcept { QCryptographicHashPrivate hash(method); - hash.addData(data); + for (QByteArrayView part : data) + hash.addData(part); hash.finalizeUnchecked(); // no mutex needed: no-one but us has access to 'hash' auto result = hash.resultView(); if (buffer.size() < result.size()) diff --git a/src/corelib/tools/qcryptographichash.h b/src/corelib/tools/qcryptographichash.h index 3d91c1f917c..8c4f70457f8 100644 --- a/src/corelib/tools/qcryptographichash.h +++ b/src/corelib/tools/qcryptographichash.h @@ -94,10 +94,16 @@ public: static QByteArray hash(QByteArrayView data, Algorithm method); static QByteArrayView hashInto(QSpan buffer, QByteArrayView data, Algorithm method) noexcept - { return hashInto(as_writable_bytes(buffer), data, method); } + { return hashInto(as_writable_bytes(buffer), {&data, 1}, method); } static QByteArrayView hashInto(QSpan buffer, QByteArrayView data, Algorithm method) noexcept + { return hashInto(as_writable_bytes(buffer), {&data, 1}, method); } + static QByteArrayView hashInto(QSpan buffer, QByteArrayView data, Algorithm method) noexcept + { return hashInto(buffer, {&data, 1}, method); } + static QByteArrayView hashInto(QSpan buffer, QSpan data, Algorithm method) noexcept { return hashInto(as_writable_bytes(buffer), data, method); } - static QByteArrayView hashInto(QSpan buffer, QByteArrayView data, Algorithm method) noexcept; + static QByteArrayView hashInto(QSpan buffer, QSpan data, Algorithm method) noexcept + { return hashInto(as_writable_bytes(buffer), data, method); } + static QByteArrayView hashInto(QSpan buffer, QSpan data, Algorithm method) noexcept; static int hashLength(Algorithm method); static bool supportsAlgorithm(Algorithm method);