#include <string.h> /* for memcpy() */
#include "private/md5.h"
-
-#ifndef FLaC__INLINE
-#define FLaC__INLINE
-#endif
+#include "share/alloc.h"
/*
* This code implements the MD5 message-digest algorithm.
#if WORDS_BIGENDIAN
//@@@@@@ OPT: use bswap/intrinsics
-FLaC__INLINE static void byteSwap(FLAC__uint32 *buf, unsigned words)
+static void byteSwap(FLAC__uint32 *buf, unsigned words)
{
+ register FLAC__uint32 x;
do {
- FLAC__byte *p = (FLAC__byte *)buf;
- *buf++ = (FLAC__uint32)((unsigned)p[3] << 8 | p[2]) << 16 | ((unsigned)p[1] << 8 | p[0]);
- p += 4;
+ x = *buf;
+ x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff);
+ *buf++ = (x >> 16) | (x << 16);
} while (--words);
}
+static void byteSwapX16(FLAC__uint32 *buf)
+{
+ register FLAC__uint32 x;
+
+ x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
+ x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
+ x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
+ x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
+ x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
+ x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
+ x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
+ x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
+ x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
+ x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
+ x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
+ x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
+ x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
+ x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
+ x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16);
+ x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf = (x >> 16) | (x << 16);
+}
#else
#define byteSwap(buf, words)
+#define byteSwapX16(buf)
#endif
/*
}
/* First chunk is an odd size */
memcpy((FLAC__byte *)ctx->in + 64 - t, buf, t);
- byteSwap(ctx->in, 16);
+ byteSwapX16(ctx->in);
FLAC__MD5Transform(ctx->buf, ctx->in);
buf += t;
len -= t;
/* Process data in 64-byte chunks */
while (len >= 64) {
memcpy(ctx->in, buf, 64);
- byteSwap(ctx->in, 16);
+ byteSwapX16(ctx->in);
FLAC__MD5Transform(ctx->buf, ctx->in);
buf += 64;
len -= 64;
if (count < 0) { /* Padding forces an extra block */
memset(p, 0, count + 8);
- byteSwap(ctx->in, 16);
+ byteSwapX16(ctx->in);
FLAC__MD5Transform(ctx->buf, ctx->in);
p = (FLAC__byte *)ctx->in;
count = 56;
byteSwap(ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
- memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
if(0 != ctx->internal_buf) {
free(ctx->internal_buf);
ctx->internal_buf = 0;
ctx->capacity = 0;
}
+ memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
}
/*
*/
FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample)
{
- const unsigned bytes_needed = channels * samples * bytes_per_sample;
+ const size_t bytes_needed = (size_t)channels * (size_t)samples * (size_t)bytes_per_sample;
+
+ /* overflow check */
+ if((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample)
+ return false;
+ if((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples)
+ return false;
if(ctx->capacity < bytes_needed) {
- FLAC__byte *tmp = (FLAC__byte*)realloc(ctx->internal_buf, bytes_needed);
+ FLAC__byte *tmp = realloc(ctx->internal_buf, bytes_needed);
if(0 == tmp) {
free(ctx->internal_buf);
- if(0 == (ctx->internal_buf = (FLAC__byte*)malloc(bytes_needed)))
+ if(0 == (ctx->internal_buf = safe_malloc_(bytes_needed)))
return false;
}
- ctx->internal_buf = tmp;
+ else
+ ctx->internal_buf = tmp;
ctx->capacity = bytes_needed;
}