diff --git a/lib/libmd5sum/md5.c b/lib/libmd5sum/md5.c index aece50d10..40ff825da 100644 --- a/lib/libmd5sum/md5.c +++ b/lib/libmd5sum/md5.c @@ -216,13 +216,14 @@ md5_process_bytes (buffer, len, ctx) memmove (&ctx->buffer[left_over], buffer, add); ctx->buflen += add; - if (left_over + add > 64) + if (ctx->buflen > 64) { - md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx); + md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx); + + ctx->buflen &= 63; /* The regions in the following copy operation cannot overlap. */ memmove (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], - (left_over + add) & 63); - ctx->buflen = (left_over + add) & 63; + ctx->buflen); } buffer = (const char *) buffer + add; @@ -230,18 +231,46 @@ md5_process_bytes (buffer, len, ctx) } /* Process available complete blocks. */ - if (len > 64) + if (len >= 64) { - md5_process_block (buffer, len & ~63, ctx); - buffer = (const char *) buffer + (len & ~63); - len &= 63; +#if !_STRING_ARCH_unaligned +/* To check alignment gcc has an appropriate operator. Other + compilers don't. */ +# if __GNUC__ >= 2 +# define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0) +# else +# define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0) +# endif + if (UNALIGNED_P (buffer)) + while (len > 64) + { + md5_process_block (memmove (ctx->buffer, buffer, 64), 64, ctx); + buffer = (const char *) buffer + 64; + len -= 64; + } + else +#endif + { + md5_process_block (buffer, len & ~63, ctx); + buffer = (const char *) buffer + (len & ~63); + len &= 63; + } } /* Move remaining bytes in internal buffer. */ if (len > 0) { - memmove (ctx->buffer, buffer, len); - ctx->buflen = len; + size_t left_over = ctx->buflen; + + memmove (&ctx->buffer[left_over], buffer, len); + left_over += len; + if (left_over >= 64) + { + md5_process_block (ctx->buffer, 64, ctx); + left_over -= 64; + memmove (ctx->buffer, &ctx->buffer[64], left_over); + } + ctx->buflen = left_over; } } diff --git a/lib/libmd5sum/md5.h b/lib/libmd5sum/md5.h index ad97efc32..ba1157d76 100644 --- a/lib/libmd5sum/md5.h +++ b/lib/libmd5sum/md5.h @@ -35,14 +35,11 @@ is usually not possible. */ #ifdef _LIBC -# include -typedef u_int32_t md5_uint32; +# include +typedef uint32_t md5_uint32; +typedef uintptr_t md5_uintptr; #else -# if defined __STDC__ && __STDC__ -# define UINT_MAX_32_BITS 4294967295U -# else -# define UINT_MAX_32_BITS 0xFFFFFFFF -# endif +# define UINT_MAX_32_BITS 4294967295U /* If UINT_MAX isn't defined, assume it's a 32-bit type. This should be valid for all systems GNU cares about because @@ -63,11 +60,14 @@ typedef u_int32_t md5_uint32; typedef unsigned long md5_uint32; # else /* The following line is intended to evoke an error. - Using #error is not portable enough. */ + Using #error is not portable enough. */ "Cannot determine unsigned 32-bit data type." # endif # endif # endif +/* We have to make a guess about the integer type equivalent in size + to pointers which should always be correct. */ +typedef unsigned long int md5_uintptr; #endif #undef __P