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 <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2024-05-21 11:28:40 +02:00
parent c70c81b371
commit fa8256bb5a
4 changed files with 26 additions and 13 deletions

View File

@ -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);
}

View File

@ -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)
{

View File

@ -1166,22 +1166,29 @@ QByteArray QCryptographicHash::hash(QByteArrayView data, Algorithm method)
/*!
\since 6.8
\fn QCryptographicHash::hashInto(QSpan<char> buffer, QSpan<const QByteArrayView> data, Algorithm method);
\fn QCryptographicHash::hashInto(QSpan<uchar> buffer, QSpan<const QByteArrayView> data, Algorithm method);
\fn QCryptographicHash::hashInto(QSpan<std::byte> buffer, QSpan<const QByteArrayView> data, Algorithm method);
\fn QCryptographicHash::hashInto(QSpan<char> buffer, QByteArrayView data, Algorithm method);
\fn QCryptographicHash::hashInto(QSpan<uchar> buffer, QByteArrayView data, Algorithm method);
\fn QCryptographicHash::hashInto(QSpan<std::byte> 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<std::byte> buffer, QByteArrayView data,
QByteArrayView QCryptographicHash::hashInto(QSpan<std::byte> buffer,
QSpan<const QByteArrayView> 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())

View File

@ -94,10 +94,16 @@ public:
static QByteArray hash(QByteArrayView data, Algorithm method);
static QByteArrayView hashInto(QSpan<char> 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<uchar> buffer, QByteArrayView data, Algorithm method) noexcept
{ return hashInto(as_writable_bytes(buffer), {&data, 1}, method); }
static QByteArrayView hashInto(QSpan<std::byte> buffer, QByteArrayView data, Algorithm method) noexcept
{ return hashInto(buffer, {&data, 1}, method); }
static QByteArrayView hashInto(QSpan<char> buffer, QSpan<const QByteArrayView> data, Algorithm method) noexcept
{ return hashInto(as_writable_bytes(buffer), data, method); }
static QByteArrayView hashInto(QSpan<std::byte> buffer, QByteArrayView data, Algorithm method) noexcept;
static QByteArrayView hashInto(QSpan<uchar> buffer, QSpan<const QByteArrayView> data, Algorithm method) noexcept
{ return hashInto(as_writable_bytes(buffer), data, method); }
static QByteArrayView hashInto(QSpan<std::byte> buffer, QSpan<const QByteArrayView> data, Algorithm method) noexcept;
static int hashLength(Algorithm method);
static bool supportsAlgorithm(Algorithm method);