diff options
author | joe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845> | 2013-03-18 10:33:56 +0000 |
---|---|---|
committer | joe <joe@61a7d7f5-40b7-0310-9c16-bb0ea8cb1845> | 2013-03-18 10:33:56 +0000 |
commit | 38f4b96dadd8df634aa94e92429bc21c194c0152 (patch) | |
tree | d61432bb2f477c23aa704b356e941e7873952506 | |
parent | 1efb8c4d68191b1262c2160fa1141817d2c30473 (diff) | |
download | neon-38f4b96dadd8df634aa94e92429bc21c194c0152.tar.gz |
* src/ne_md5.c (md5_finish_ctx): Fix aliasing problem.
http://permalink.gmane.org/gmane.comp.gnu.binutils/58378
git-svn-id: http://svn.webdav.org/repos/projects/neon/trunk@1896 61a7d7f5-40b7-0310-9c16-bb0ea8cb1845
-rw-r--r-- | src/ne_md5.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/src/ne_md5.c b/src/ne_md5.c index 3022c6f..35d7109 100644 --- a/src/ne_md5.c +++ b/src/ne_md5.c @@ -139,6 +139,7 @@ md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) { /* Take yet unprocessed bytes into account. */ md5_uint32 bytes = ctx->buflen; + md5_uint32 swap_bytes; size_t pad; /* Now count remaining bytes. */ @@ -149,10 +150,13 @@ md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; memcpy (&ctx->buffer[bytes], fillbuf, pad); - /* Put the 64-bit file length in *bits* at the end of the buffer. */ - *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3); - *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) | - (ctx->total[0] >> 29)); + /* Put the 64-bit file length in *bits* at the end of the buffer. + Use memcpy to avoid aliasing problems. On most systems, this + will be optimized away to the same code. */ + swap_bytes = SWAP (ctx->total[0] << 3); + memcpy (&ctx->buffer[bytes + pad], &swap_bytes, sizeof (swap_bytes)); + swap_bytes = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29)); + memcpy (&ctx->buffer[bytes + pad + 4], &swap_bytes, sizeof (swap_bytes)); /* Process last bytes. */ md5_process_block (ctx->buffer, bytes + pad + 8, ctx); |