Large patch from Ben Allison fixing the MSVC build.
[platform/upstream/flac.git] / src / libFLAC / md5.c
index db1a65f..e251d50 100644 (file)
@@ -6,10 +6,7 @@
 #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.
@@ -138,16 +135,39 @@ static void FLAC__MD5Transform(FLAC__uint32 buf[4], FLAC__uint32 const in[16])
 
 #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
 
 /*
@@ -171,7 +191,7 @@ static void FLAC__MD5Update(FLAC__MD5Context *ctx, FLAC__byte const *buf, unsign
        }
        /* 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;
@@ -179,7 +199,7 @@ static void FLAC__MD5Update(FLAC__MD5Context *ctx, FLAC__byte const *buf, unsign
        /* 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;
@@ -224,7 +244,7 @@ void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx)
 
        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;
@@ -239,12 +259,12 @@ void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx)
 
        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 */
 }
 
 /*
@@ -373,16 +393,23 @@ static void format_input_(FLAC__byte *buf, const FLAC__int32 * const signal[], u
  */
 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;
        }