summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qcryptographichash.cpp
diff options
context:
space:
mode:
authorGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2020-07-12 14:29:24 +0200
committerGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2020-07-12 21:48:18 +0200
commit23444d4b26a13677a2029a2b5a53bfae76647b71 (patch)
treec0960b1bba12da08dd2924d22b261c5e4b674576 /src/corelib/tools/qcryptographichash.cpp
parent20848f6e8316fc440202a3bc193956aee7a00b5a (diff)
QCryptographicHash: explicitly activate the used union member
A union member lifetime does not start automatically if one takes a pointer to a union member and writes into the member. Only the subscript syntax in an assignment features such automatic lifetime start [class.union§6]. In the other cases, one is allowed to get a pointer to the storage ([basic.life§6]) but has to start lifetime explicitly via placement new. Hence, do so, or we end up in UB land. We're left with the problem of reset() which may be called multiple times. I think we can actually just create a new object in the same storage without destroying the pre-existing object by exploiting [basic.life§5]: reusing the storage causes lifetime end for the old object. Moreover, since the union is over trivial datatypes (C structs), there's no side effects in the destructor of the old object, so there is no need to call it. Drive by fix, apply some DRY for SHA3. Change-Id: Idc351568635e59d45421311f043956ab3aabf389 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Linus Jahn <lnj@kaidan.im>
Diffstat (limited to 'src/corelib/tools/qcryptographichash.cpp')
-rw-r--r--src/corelib/tools/qcryptographichash.cpp16
1 files changed, 9 insertions, 7 deletions
diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp
index 1d4afabedd..8c02ea21f9 100644
--- a/src/corelib/tools/qcryptographichash.cpp
+++ b/src/corelib/tools/qcryptographichash.cpp
@@ -308,6 +308,7 @@ void QCryptographicHash::reset()
{
switch (d->method) {
case Sha1:
+ new (&d->sha1Context) Sha1State;
sha1InitState(&d->sha1Context);
break;
#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
@@ -317,38 +318,39 @@ void QCryptographicHash::reset()
break;
#else
case Md4:
+ new (&d->md4Context) md4_context;
md4_init(&d->md4Context);
break;
case Md5:
+ new (&d->md5Context) MD5Context;
MD5Init(&d->md5Context);
break;
case Sha224:
+ new (&d->sha224Context) SHA224Context;
SHA224Reset(&d->sha224Context);
break;
case Sha256:
+ new (&d->sha256Context) SHA256Context;
SHA256Reset(&d->sha256Context);
break;
case Sha384:
+ new (&d->sha384Context) SHA384Context;
SHA384Reset(&d->sha384Context);
break;
case Sha512:
+ new (&d->sha512Context) SHA512Context;
SHA512Reset(&d->sha512Context);
break;
case RealSha3_224:
case Keccak_224:
- sha3Init(&d->sha3Context, 224);
- break;
case RealSha3_256:
case Keccak_256:
- sha3Init(&d->sha3Context, 256);
- break;
case RealSha3_384:
case Keccak_384:
- sha3Init(&d->sha3Context, 384);
- break;
case RealSha3_512:
case Keccak_512:
- sha3Init(&d->sha3Context, 512);
+ new (&d->sha3Context) SHA3Context;
+ sha3Init(&d->sha3Context, hashLength(d->method) * 8);
break;
#endif
}