Enable utf8 I/O stuff when compiling with MinGW.
[platform/upstream/flac.git] / src / libFLAC / memory.c
index 956cb29..3207774 100644 (file)
@@ -1,5 +1,5 @@
 /* libFLAC - Free Lossless Audio Codec library
- * Copyright (C) 2001,2002,2003,2004,2005,2006  Josh Coalson
+ * Copyright (C) 2001,2002,2003,2004,2005,2006,2007,2008,2009  Josh Coalson
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,6 +35,7 @@
 
 #include "private/memory.h"
 #include "FLAC/assert.h"
+#include "share/alloc.h"
 
 void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address)
 {
@@ -44,16 +45,33 @@ void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address)
 
 #ifdef FLAC__ALIGN_MALLOC_DATA
        /* align on 32-byte (256-bit) boundary */
-       x = malloc(bytes+31);
-       *aligned_address = (void*)(((unsigned)x + 31) & -32);
+       x = safe_malloc_add_2op_(bytes, /*+*/31);
+#ifdef SIZEOF_VOIDP
+#if SIZEOF_VOIDP == 4
+               /* could do  *aligned_address = x + ((unsigned) (32 - (((unsigned)x) & 31))) & 31; */
+               *aligned_address = (void*)(((unsigned)x + 31) & -32);
+#elif SIZEOF_VOIDP == 8
+               *aligned_address = (void*)(((FLAC__uint64)x + 31) & (FLAC__uint64)(-((FLAC__int64)32)));
 #else
-       x = malloc(bytes);
+# error  Unsupported sizeof(void*)
+#endif
+#else
+       /* there's got to be a better way to do this right for all archs */
+       if(sizeof(void*) == sizeof(unsigned))
+               *aligned_address = (void*)(((unsigned)x + 31) & -32);
+       else if(sizeof(void*) == sizeof(FLAC__uint64))
+               *aligned_address = (void*)(((FLAC__uint64)x + 31) & (FLAC__uint64)(-((FLAC__int64)32)));
+       else
+               return 0;
+#endif
+#else
+       x = safe_malloc_(bytes);
        *aligned_address = x;
 #endif
        return x;
 }
 
-FLAC__bool FLAC__memory_alloc_aligned_int32_array(unsigned elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer)
+FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer)
 {
        FLAC__int32 *pu; /* unaligned pointer */
        union { /* union needed to comply with C99 pointer aliasing rules */
@@ -66,7 +84,10 @@ FLAC__bool FLAC__memory_alloc_aligned_int32_array(unsigned elements, FLAC__int32
        FLAC__ASSERT(0 != aligned_pointer);
        FLAC__ASSERT(unaligned_pointer != aligned_pointer);
 
-       pu = (FLAC__int32*)FLAC__memory_alloc_aligned(sizeof(FLAC__int32) * elements, &u.pv);
+       if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+               return false;
+
+       pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
        if(0 == pu) {
                return false;
        }
@@ -79,7 +100,7 @@ FLAC__bool FLAC__memory_alloc_aligned_int32_array(unsigned elements, FLAC__int32
        }
 }
 
-FLAC__bool FLAC__memory_alloc_aligned_uint32_array(unsigned elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer)
+FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer)
 {
        FLAC__uint32 *pu; /* unaligned pointer */
        union { /* union needed to comply with C99 pointer aliasing rules */
@@ -92,7 +113,10 @@ FLAC__bool FLAC__memory_alloc_aligned_uint32_array(unsigned elements, FLAC__uint
        FLAC__ASSERT(0 != aligned_pointer);
        FLAC__ASSERT(unaligned_pointer != aligned_pointer);
 
-       pu = (FLAC__uint32*)FLAC__memory_alloc_aligned(sizeof(FLAC__uint32) * elements, &u.pv);
+       if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+               return false;
+
+       pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
        if(0 == pu) {
                return false;
        }
@@ -105,7 +129,7 @@ FLAC__bool FLAC__memory_alloc_aligned_uint32_array(unsigned elements, FLAC__uint
        }
 }
 
-FLAC__bool FLAC__memory_alloc_aligned_uint64_array(unsigned elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer)
+FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer)
 {
        FLAC__uint64 *pu; /* unaligned pointer */
        union { /* union needed to comply with C99 pointer aliasing rules */
@@ -118,7 +142,10 @@ FLAC__bool FLAC__memory_alloc_aligned_uint64_array(unsigned elements, FLAC__uint
        FLAC__ASSERT(0 != aligned_pointer);
        FLAC__ASSERT(unaligned_pointer != aligned_pointer);
 
-       pu = (FLAC__uint64*)FLAC__memory_alloc_aligned(sizeof(FLAC__uint64) * elements, &u.pv);
+       if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+               return false;
+
+       pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
        if(0 == pu) {
                return false;
        }
@@ -131,7 +158,7 @@ FLAC__bool FLAC__memory_alloc_aligned_uint64_array(unsigned elements, FLAC__uint
        }
 }
 
-FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(unsigned elements, unsigned **unaligned_pointer, unsigned **aligned_pointer)
+FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, unsigned **unaligned_pointer, unsigned **aligned_pointer)
 {
        unsigned *pu; /* unaligned pointer */
        union { /* union needed to comply with C99 pointer aliasing rules */
@@ -144,7 +171,10 @@ FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(unsigned elements, unsigned
        FLAC__ASSERT(0 != aligned_pointer);
        FLAC__ASSERT(unaligned_pointer != aligned_pointer);
 
-       pu = (unsigned*)FLAC__memory_alloc_aligned(sizeof(unsigned) * elements, &u.pv);
+       if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+               return false;
+
+       pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
        if(0 == pu) {
                return false;
        }
@@ -159,7 +189,7 @@ FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(unsigned elements, unsigned
 
 #ifndef FLAC__INTEGER_ONLY_LIBRARY
 
-FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer)
+FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer)
 {
        FLAC__real *pu; /* unaligned pointer */
        union { /* union needed to comply with C99 pointer aliasing rules */
@@ -172,7 +202,10 @@ FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real *
        FLAC__ASSERT(0 != aligned_pointer);
        FLAC__ASSERT(unaligned_pointer != aligned_pointer);
 
-       pu = (FLAC__real*)FLAC__memory_alloc_aligned(sizeof(FLAC__real) * elements, &u.pv);
+       if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+               return false;
+
+       pu = FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
        if(0 == pu) {
                return false;
        }
@@ -186,3 +219,12 @@ FLAC__bool FLAC__memory_alloc_aligned_real_array(unsigned elements, FLAC__real *
 }
 
 #endif
+
+void *safe_malloc_mul_2op_p(size_t size1, size_t size2)
+{
+       if(!size1 || !size2)
+               return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
+       if(size1 > SIZE_MAX / size2)
+               return 0;
+       return malloc(size1*size2);
+}