Sophie

Sophie

distrib > * > 2008.0 > x86_64 > by-pkgid > 93872804043c360ea0ffd364e51b203c > files > 1

flac-1.2.0-1.1mdv2008.0.src.rpm

--- src/flac/encode.c-dist	2007-07-10 04:10:44.000000000 +0200
+++ src/flac/encode.c	2007-10-12 15:04:29.000000000 +0200
@@ -40,6 +40,7 @@
 #include <stdlib.h> /* for malloc */
 #include <string.h> /* for strcmp(), strerror( */
 #include "FLAC/all.h"
+#include "share/alloc.h"
 #include "share/grabbag.h"
 #include "encode.h"
 
--- src/flac/main.c-dist	2007-07-07 07:50:58.000000000 +0200
+++ src/flac/main.c	2007-10-12 15:05:44.000000000 +0200
@@ -34,6 +34,7 @@
 #include <unistd.h> /* for unlink() */
 #endif
 #include "FLAC/all.h"
+#include "share/alloc.h"
 #include "share/grabbag.h"
 #include "analyze.h"
 #include "decode.h"
@@ -1783,7 +1784,7 @@ int encode_file(const char *infilename, 
 	if(encode_infile != stdin && grabbag__file_are_same(infilename, outfilename)) {
 		static const char *tmp_suffix = ".tmp,fl-ac+en'c";
 		/*@@@@ still a remote possibility that a file with this filename exists */
-		if(0 == (internal_outfilename = malloc(strlen(outfilename)+strlen(tmp_suffix)+1))) {
+		if(0 == (internal_outfilename = (char *)safe_malloc_add_3op_(strlen(outfilename), /*+*/strlen(tmp_suffix), /*+*/1))) {
 			flac__utils_printf(stderr, 1, "ERROR allocating memory for tempfile name\n");
 			conditional_fclose(encode_infile);
 			return 1;
--- src/metaflac/operations.c-dist	2007-02-02 07:58:23.000000000 +0100
+++ src/metaflac/operations.c	2007-10-12 15:04:37.000000000 +0200
@@ -25,6 +25,7 @@
 #include "utils.h"
 #include "FLAC/assert.h"
 #include "FLAC/metadata.h"
+#include "share/alloc.h"
 #include "share/grabbag.h"
 #include <stdio.h>
 #include <stdlib.h>
@@ -445,8 +446,8 @@ FLAC__bool do_shorthand_operation__add_r
 	}
 
 	if(
-		0 == (title_gains = (float*)malloc(sizeof(float) * num_files)) ||
-		0 == (title_peaks = (float*)malloc(sizeof(float) * num_files))
+		0 == (title_gains = (float*)safe_malloc_mul_2op_(sizeof(float), /*times*/num_files)) ||
+		0 == (title_peaks = (float*)safe_malloc_mul_2op_(sizeof(float), /*times*/num_files))
 	)
 		die("out of memory allocating space for title gains/peaks");
 
--- src/metaflac/options.c-dist	2007-07-07 06:30:11.000000000 +0200
+++ src/metaflac/options.c	2007-10-12 15:04:37.000000000 +0200
@@ -24,6 +24,7 @@
 #include "usage.h"
 #include "utils.h"
 #include "FLAC/assert.h"
+#include "share/alloc.h"
 #include "share/grabbag/replaygain.h"
 #include <ctype.h>
 #include <stdio.h>
@@ -185,7 +186,7 @@ FLAC__bool parse_options(int argc, char 
 
 	if(options->num_files > 0) {
 		unsigned i = 0;
-		if(0 == (options->filenames = (char**)malloc(sizeof(char*) * options->num_files)))
+		if(0 == (options->filenames = (char**)safe_malloc_mul_2op_(sizeof(char*), /*times*/options->num_files)))
 			die("out of memory allocating space for file names list");
 		while(share__optind < argc)
 			options->filenames[i++] = local_strdup(argv[share__optind++]);
@@ -718,8 +719,10 @@ void append_new_operation(CommandLineOpt
 	}
 	if(options->ops.capacity <= options->ops.num_operations) {
 		unsigned original_capacity = options->ops.capacity;
-		options->ops.capacity *= 4;
-		if(0 == (options->ops.operations = (Operation*)realloc(options->ops.operations, sizeof(Operation) * options->ops.capacity)))
+		if(options->ops.capacity > SIZE_MAX / 2) /* overflow check */
+			die("out of memory allocating space for option list");
+		options->ops.capacity *= 2;
+		if(0 == (options->ops.operations = (Operation*)safe_realloc_mul_2op_(options->ops.operations, sizeof(Operation), /*times*/options->ops.capacity)))
 			die("out of memory allocating space for option list");
 		memset(options->ops.operations + original_capacity, 0, sizeof(Operation) * (options->ops.capacity - original_capacity));
 	}
@@ -737,8 +740,10 @@ void append_new_argument(CommandLineOpti
 	}
 	if(options->args.capacity <= options->args.num_arguments) {
 		unsigned original_capacity = options->args.capacity;
-		options->args.capacity *= 4;
-		if(0 == (options->args.arguments = (Argument*)realloc(options->args.arguments, sizeof(Argument) * options->args.capacity)))
+		if(options->args.capacity > SIZE_MAX / 2) /* overflow check */
+			die("out of memory allocating space for option list");
+		options->args.capacity *= 2;
+		if(0 == (options->args.arguments = (Argument*)safe_realloc_mul_2op_(options->args.arguments, sizeof(Argument), /*times*/options->args.capacity)))
 			die("out of memory allocating space for option list");
 		memset(options->args.arguments + original_capacity, 0, sizeof(Argument) * (options->args.capacity - original_capacity));
 	}
@@ -969,7 +974,7 @@ FLAC__bool parse_block_number(const char
 
 	/* make space */
 	FLAC__ASSERT(out->num_entries > 0);
-	if(0 == (out->entries = (unsigned*)malloc(sizeof(unsigned) * out->num_entries)))
+	if(0 == (out->entries = (unsigned*)safe_malloc_mul_2op_(sizeof(unsigned), /*times*/out->num_entries)))
 		die("out of memory allocating space for option list");
 
 	/* load 'em up */
@@ -1008,7 +1013,7 @@ FLAC__bool parse_block_type(const char *
 
 	/* make space */
 	FLAC__ASSERT(out->num_entries > 0);
-	if(0 == (out->entries = (Argument_BlockTypeEntry*)malloc(sizeof(Argument_BlockTypeEntry) * out->num_entries)))
+	if(0 == (out->entries = (Argument_BlockTypeEntry*)safe_malloc_mul_2op_(sizeof(Argument_BlockTypeEntry), /*times*/out->num_entries)))
 		die("out of memory allocating space for option list");
 
 	/* load 'em up */
--- src/metaflac/utils.c-dist	2007-02-02 07:58:23.000000000 +0100
+++ src/metaflac/utils.c	2007-10-12 15:04:37.000000000 +0200
@@ -22,6 +22,7 @@
 
 #include "utils.h"
 #include "FLAC/assert.h"
+#include "share/alloc.h"
 #include "share/utf8.h"
 #include <ctype.h>
 #include <stdarg.h>
@@ -57,7 +58,7 @@ char *local_strdup(const char *source)
 
 void local_strcat(char **dest, const char *source)
 {
-	unsigned ndest, nsource;
+	size_t ndest, nsource;
 
 	FLAC__ASSERT(0 != dest);
 	FLAC__ASSERT(0 != source);
@@ -68,7 +69,7 @@ void local_strcat(char **dest, const cha
 	if(nsource == 0)
 		return;
 
-	*dest = (char*)realloc(*dest, ndest + nsource + 1);
+	*dest = (char*)safe_realloc_add_3op_(*dest, ndest, /*+*/nsource, /*+*/1);
 	if(0 == *dest)
 		die("out of memory growing string");
 	strcpy((*dest)+ndest, source);
--- src/plugin_xmms/plugin.c-dist	2007-02-02 07:58:23.000000000 +0100
+++ src/plugin_xmms/plugin.c	2007-10-12 15:04:38.000000000 +0200
@@ -400,8 +400,13 @@ void FLAC_XMMS__get_song_info(char *file
 		if(title) {
 			if (!is_http_source(filename)) {
 				static const char *errtitle = "Invalid FLAC File: ";
-				*title = g_malloc(strlen(errtitle) + 1 + strlen(filename) + 1 + 1);
-				sprintf(*title, "%s\"%s\"", errtitle, filename);
+				if(strlen(errtitle) + 1 + strlen(filename) + 1 + 1 < strlen(filename)) { /* overflow check */
+					*title = NULL;
+				}
+				else {
+					*title = g_malloc(strlen(errtitle) + 1 + strlen(filename) + 1 + 1);
+					sprintf(*title, "%s\"%s\"", errtitle, filename);
+				}
 			} else {
 				*title = NULL;
 			}
--- src/share/utf8/utf8.c-dist	2007-06-14 08:13:25.000000000 +0200
+++ src/share/utf8/utf8.c	2007-10-12 15:04:38.000000000 +0200
@@ -2,6 +2,8 @@
  * Copyright (C) 2001 Peter Harris <peter.harris@hummingbird.com>
  * Copyright (C) 2001 Edmund Grimley Evans <edmundo@rano.org>
  *
+ * Buffer overflow checking added: Josh Coalson, 9/9/2007
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -28,6 +30,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "share/alloc.h"
 #include "utf8.h"
 #include "charset.h"
 
@@ -43,7 +46,8 @@
 
 static unsigned char *make_utf8_string(const wchar_t *unicode)
 {
-    int size = 0, index = 0, out_index = 0;
+    size_t size = 0, n;
+    int index = 0, out_index = 0;
     unsigned char *out;
     unsigned short c;
 
@@ -51,16 +55,19 @@ static unsigned char *make_utf8_string(c
     c = unicode[index++];
     while(c) {
         if(c < 0x0080) {
-            size += 1;
+            n = 1;
         } else if(c < 0x0800) {
-            size += 2;
+            n = 2;
         } else {
-            size += 3;
+            n = 3;
         }
+        if(size+n < size) /* overflow check */
+            return NULL;
+        size += n;
         c = unicode[index++];
-    }	
+    }
 
-    out = malloc(size + 1);
+    out = safe_malloc_add_2op_(size, /*+*/1);
     if (out == NULL)
         return NULL;
     index = 0;
@@ -87,7 +94,8 @@ static unsigned char *make_utf8_string(c
 
 static wchar_t *make_unicode_string(const unsigned char *utf8)
 {
-    int size = 0, index = 0, out_index = 0;
+    size_t size = 0;
+    int index = 0, out_index = 0;
     wchar_t *out;
     unsigned char c;
 
@@ -101,11 +109,15 @@ static wchar_t *make_unicode_string(cons
         } else {
             index += 1;
         }
-        size += 1;
+        if(size + 1 == 0) /* overflow check */
+            return NULL;
+        size++;
         c = utf8[index++];
-    }	
+    }
 
-    out = malloc((size + 1) * sizeof(wchar_t));
+    if(size + 1 == 0) /* overflow check */
+        return NULL;
+    out = safe_malloc_mul_2op_(size+1, /*times*/sizeof(wchar_t));
     if (out == NULL)
         return NULL;
     index = 0;
@@ -147,7 +159,10 @@ int utf8_encode(const char *from, char *
 		return -1;
 	}
 
-	unicode = calloc(wchars + 1, sizeof(unsigned short));
+	if(wchars < 0) /* underflow check */
+		return -1;
+
+	unicode = safe_calloc_((size_t)wchars + 1, sizeof(unsigned short));
 	if(unicode == NULL) 
 	{
 		fprintf(stderr, "Out of memory processing string to UTF8\n");
@@ -190,6 +205,9 @@ int utf8_decode(const char *from, char *
     chars = WideCharToMultiByte(GetConsoleCP(), WC_COMPOSITECHECK, unicode,
             -1, NULL, 0, NULL, NULL);
 
+    if(chars < 0) /* underflow check */
+        return -1;
+
     if(chars == 0)
     {
         fprintf(stderr, "Unicode translation error %d\n", GetLastError());
@@ -197,7 +215,7 @@ int utf8_decode(const char *from, char *
         return -1;
     }
 
-    *to = calloc(chars + 1, sizeof(unsigned char));
+    *to = safe_calloc_((size_t)chars + 1, sizeof(unsigned char));
     if(*to == NULL) 
     {
         fprintf(stderr, "Out of memory processing string to local charset\n");
@@ -279,7 +297,7 @@ static int convert_string(const char *fr
   if (ret != -1)
     return ret;
 
-  s = malloc(fromlen + 1);
+  s = safe_malloc_add_2op_(fromlen, /*+*/1);
   if (!s)
     return -1;
   strcpy(s, from);
--- src/share/utf8/charset.c-dist	2006-05-24 06:41:37.000000000 +0200
+++ src/share/utf8/charset.c	2007-10-12 15:04:38.000000000 +0200
@@ -35,6 +35,7 @@
 
 #include <stdlib.h>
 
+#include "share/alloc.h"
 #include "charset.h"
 
 #include "charmaps.h"
@@ -492,7 +493,7 @@ int charset_convert(const char *fromcode
   if (!charset1 || !charset2 )
     return -1;
 
-  tobuf = (char *)malloc(fromlen * charset2->max + 1);
+  tobuf = (char *)safe_malloc_mul2add_(fromlen, /*times*/charset2->max, /*+*/1);
   if (!tobuf)
     return -2;
 
--- src/share/utf8/iconvert.c-dist	2006-05-24 06:41:37.000000000 +0200
+++ src/share/utf8/iconvert.c	2007-10-12 15:06:52.000000000 +0200
@@ -27,6 +27,7 @@
 #include <iconv.h>
 #include <stdlib.h>
 #include <string.h>
+#include "share/alloc.h"
 
 /*
  * Convert data from one encoding to another. Return:
@@ -79,7 +80,7 @@ int iconvert(const char *fromcode, const
      * This is deliberately not a config option as people often
      * change their iconv library without rebuilding applications.
      */
-    tocode1 = (char *)malloc(strlen(tocode) + 11);
+    tocode1 = (char *)safe_malloc_add_2op_(strlen(tocode), /*+*/11);
     if (!tocode1)
       goto fail;
 
@@ -117,6 +118,8 @@ int iconvert(const char *fromcode, const
       break;
     if (obl < 6) {
       /* Enlarge the buffer */
+      if(utflen*2 < utflen) /* overflow check */
+	goto fail;
       utflen *= 2;
       newbuf = (char *)realloc(utfbuf, utflen);
       if (!newbuf)
@@ -143,7 +146,7 @@ int iconvert(const char *fromcode, const
       iconv_close(cd1);
       return ret;
     }
-    newbuf = (char *)realloc(utfbuf, (ob - utfbuf) + 1);
+    newbuf = (char *)safe_realloc_add_2op_(utfbuf, (ob - utfbuf), /*+*/1);
     if (!newbuf)
       goto fail;
     ob = (ob - utfbuf) + newbuf;
@@ -194,7 +197,7 @@ int iconvert(const char *fromcode, const
   outlen += ob - tbuf;
 
   /* Convert from UTF-8 for real */
-  outbuf = (char *)malloc(outlen + 1);
+  outbuf = (char *)safe_malloc_add_2op_(outlen, /*+*/1);
   if (!outbuf)
     goto fail;
   ib = utfbuf;
--- src/share/grabbag/picture.c-dist	2007-02-06 02:40:37.000000000 +0100
+++ src/share/grabbag/picture.c	2007-10-12 15:04:38.000000000 +0200
@@ -20,6 +20,7 @@
 #  include <config.h>
 #endif
 
+#include "share/alloc.h"
 #include "share/grabbag.h"
 #include "FLAC/assert.h"
 #include <stdio.h>
@@ -29,7 +30,7 @@
 /* slightly different that strndup(): this always copies 'size' bytes starting from s into a NUL-terminated string. */
 static char *local__strndup_(const char *s, size_t size)
 {
-	char *x = (char*)malloc(size+1);
+	char *x = (char*)safe_malloc_add_2op_(size, /*+*/1);
 	if(x) {
 		memcpy(x, s, size);
 		x[size] = '\0';
@@ -357,7 +358,7 @@ FLAC__StreamMetadata *grabbag__picture_p
 				if(size < 0)
 					*error_message = error_messages[5];
 				else {
-					FLAC__byte *buffer = (FLAC__byte*)malloc(size);
+					FLAC__byte *buffer = (FLAC__byte*)safe_malloc_(size);
 					if(0 == buffer)
 						*error_message = error_messages[0];
 					else {
--- src/libFLAC/md5.c-dist	2007-03-22 04:14:12.000000000 +0100
+++ src/libFLAC/md5.c	2007-10-12 15:04:37.000000000 +0200
@@ -6,6 +6,7 @@
 #include <string.h>		/* for memcpy() */
 
 #include "private/md5.h"
+#include "share/alloc.h"
 
 #ifndef FLaC__INLINE
 #define FLaC__INLINE
@@ -396,13 +397,19 @@ static void format_input_(FLAC__byte *bu
  */
 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);
 		if(0 == tmp) {
 			free(ctx->internal_buf);
-			if(0 == (ctx->internal_buf = (FLAC__byte*)malloc(bytes_needed)))
+			if(0 == (ctx->internal_buf = (FLAC__byte*)safe_malloc_(bytes_needed)))
 				return false;
 		}
 		ctx->internal_buf = tmp;
--- src/libFLAC/metadata_iterators.c-dist	2007-02-02 07:58:22.000000000 +0100
+++ src/libFLAC/metadata_iterators.c	2007-10-12 15:04:37.000000000 +0200
@@ -61,6 +61,7 @@
 
 #include "FLAC/assert.h"
 #include "FLAC/stream_decoder.h"
+#include "share/alloc.h"
 
 #ifdef max
 #undef max
@@ -2101,6 +2102,9 @@ FLAC__Metadata_SimpleIteratorStatus read
 	if(read_cb(block->id, 1, id_bytes, handle) != id_bytes)
 		return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
 
+	if(block_length < id_bytes)
+		return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
+
 	block_length -= id_bytes;
 
 	if(block_length == 0) {
@@ -2128,7 +2132,7 @@ FLAC__Metadata_SimpleIteratorStatus read
 
 	if(block->num_points == 0)
 		block->points = 0;
-	else if(0 == (block->points = (FLAC__StreamMetadata_SeekPoint*)malloc(block->num_points * sizeof(FLAC__StreamMetadata_SeekPoint))))
+	else if(0 == (block->points = (FLAC__StreamMetadata_SeekPoint*)safe_malloc_mul_2op_(block->num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint))))
 		return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
 
 	for(i = 0; i < block->num_points; i++) {
@@ -2161,7 +2165,7 @@ FLAC__Metadata_SimpleIteratorStatus read
 		entry->entry = 0;
 	}
 	else {
-		if(0 == (entry->entry = (FLAC__byte*)malloc(entry->length+1)))
+		if(0 == (entry->entry = (FLAC__byte*)safe_malloc_add_2op_(entry->length, /*+*/1)))
 			return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
 
 		if(read_cb(entry->entry, 1, entry->length, handle) != entry->length)
@@ -2336,7 +2340,7 @@ FLAC__Metadata_SimpleIteratorStatus read
 	if(0 != *data)
 		free(*data);
 
-	if(0 == (*data = (FLAC__byte*)malloc(*length+1)))
+	if(0 == (*data = (FLAC__byte*)safe_malloc_add_2op_(*length, /*+*/1)))
 		return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
 
 	if(*length > 0) {
@@ -3155,7 +3159,7 @@ FLAC__bool open_tempfile_(const char *fi
 {
 	static const char *tempfile_suffix = ".metadata_edit";
 	if(0 == tempfile_path_prefix) {
-		if(0 == (*tempfilename = (char*)malloc(strlen(filename) + strlen(tempfile_suffix) + 1))) {
+		if(0 == (*tempfilename = (char*)safe_malloc_add_3op_(strlen(filename), /*+*/strlen(tempfile_suffix), /*+*/1))) {
 			*status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
 			return false;
 		}
@@ -3169,7 +3173,7 @@ FLAC__bool open_tempfile_(const char *fi
 		else
 			p++;
 
-		if(0 == (*tempfilename = (char*)malloc(strlen(tempfile_path_prefix) + 1 + strlen(p) + strlen(tempfile_suffix) + 1))) {
+		if(0 == (*tempfilename = (char*)safe_malloc_add_4op_(strlen(tempfile_path_prefix), /*+*/strlen(p), /*+*/strlen(tempfile_suffix), /*+*/2))) {
 			*status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
 			return false;
 		}
--- src/libFLAC/metadata_object.c-dist	2007-02-22 02:37:33.000000000 +0100
+++ src/libFLAC/metadata_object.c	2007-10-12 15:04:37.000000000 +0200
@@ -39,6 +39,7 @@
 #include "private/metadata.h"
 
 #include "FLAC/assert.h"
+#include "share/alloc.h"
 
 
 /****************************************************************************
@@ -53,14 +54,14 @@
  *  from != NULL && bytes > 0
  *       to <- copy of from
  *  else ASSERT
- * malloc error leaved 'to' unchanged
+ * malloc error leaves 'to' unchanged
  */
 static FLAC__bool copy_bytes_(FLAC__byte **to, const FLAC__byte *from, unsigned bytes)
 {
 	FLAC__ASSERT(0 != to);
 	if(bytes > 0 && 0 != from) {
 		FLAC__byte *x;
-		if(0 == (x = (FLAC__byte*)malloc(bytes)))
+		if(0 == (x = (FLAC__byte*)safe_malloc_(bytes)))
 			return false;
 		memcpy(x, from, bytes);
 		*to = x;
@@ -94,7 +95,7 @@ static FLAC__bool free_copy_bytes_(FLAC_
 /* realloc() failure leaves entry unchanged */
 static FLAC__bool ensure_null_terminated_(FLAC__byte **entry, unsigned length)
 {
-	FLAC__byte *x = (FLAC__byte*)realloc(*entry, length+1);
+	FLAC__byte *x = (FLAC__byte*)safe_realloc_add_2op_(*entry, length, /*+*/1);
 	if(0 != x) {
 		x[length] = '\0';
 		*entry = x;
@@ -132,7 +133,7 @@ static FLAC__bool copy_vcentry_(FLAC__St
 	else {
 		FLAC__byte *x;
 		FLAC__ASSERT(from->length > 0);
-		if(0 == (x = (FLAC__byte*)malloc(from->length+1)))
+		if(0 == (x = (FLAC__byte*)safe_malloc_add_2op_(from->length, /*+*/1)))
 			return false;
 		memcpy(x, from->entry, from->length);
 		x[from->length] = '\0';
@@ -150,7 +151,7 @@ static FLAC__bool copy_track_(FLAC__Stre
 	else {
 		FLAC__StreamMetadata_CueSheet_Index *x;
 		FLAC__ASSERT(from->num_indices > 0);
-		if(0 == (x = (FLAC__StreamMetadata_CueSheet_Index*)malloc(from->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index))))
+		if(0 == (x = (FLAC__StreamMetadata_CueSheet_Index*)safe_malloc_mul_2op_(from->num_indices, /*times*/sizeof(FLAC__StreamMetadata_CueSheet_Index))))
 			return false;
 		memcpy(x, from->indices, from->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index));
 		to->indices = x;
@@ -172,7 +173,7 @@ static FLAC__StreamMetadata_SeekPoint *s
 
 	FLAC__ASSERT(num_points > 0);
 
-	object_array = (FLAC__StreamMetadata_SeekPoint*)malloc(num_points * sizeof(FLAC__StreamMetadata_SeekPoint));
+	object_array = (FLAC__StreamMetadata_SeekPoint*)safe_malloc_mul_2op_(num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint));
 
 	if(0 != object_array) {
 		unsigned i;
@@ -205,7 +206,7 @@ static FLAC__StreamMetadata_VorbisCommen
 {
 	FLAC__ASSERT(num_comments > 0);
 
-	return (FLAC__StreamMetadata_VorbisComment_Entry*)calloc(num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry));
+	return (FLAC__StreamMetadata_VorbisComment_Entry*)safe_calloc_(num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry));
 }
 
 static void vorbiscomment_entry_array_delete_(FLAC__StreamMetadata_VorbisComment_Entry *object_array, unsigned num_comments)
@@ -344,14 +345,14 @@ static FLAC__StreamMetadata_CueSheet_Ind
 {
 	FLAC__ASSERT(num_indices > 0);
 
-	return (FLAC__StreamMetadata_CueSheet_Index*)calloc(num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index));
+	return (FLAC__StreamMetadata_CueSheet_Index*)safe_calloc_(num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index));
 }
 
 static FLAC__StreamMetadata_CueSheet_Track *cuesheet_track_array_new_(unsigned num_tracks)
 {
 	FLAC__ASSERT(num_tracks > 0);
 
-	return (FLAC__StreamMetadata_CueSheet_Track*)calloc(num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track));
+	return (FLAC__StreamMetadata_CueSheet_Track*)safe_calloc_(num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track));
 }
 
 static void cuesheet_track_array_delete_(FLAC__StreamMetadata_CueSheet_Track *object_array, unsigned num_tracks)
@@ -537,6 +538,10 @@ FLAC_API FLAC__StreamMetadata *FLAC__met
 			case FLAC__METADATA_TYPE_PADDING:
 				break;
 			case FLAC__METADATA_TYPE_APPLICATION:
+				if(to->length < FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8) { /* underflow check */
+					FLAC__metadata_object_delete(to);
+					return 0;
+				}
 				memcpy(&to->data.application.id, &object->data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8);
 				if(!copy_bytes_(&to->data.application.data, object->data.application.data, object->length - FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8)) {
 					FLAC__metadata_object_delete(to);
@@ -545,6 +550,10 @@ FLAC_API FLAC__StreamMetadata *FLAC__met
 				break;
 			case FLAC__METADATA_TYPE_SEEKTABLE:
 				to->data.seek_table.num_points = object->data.seek_table.num_points;
+				if(to->data.seek_table.num_points > SIZE_MAX / sizeof(FLAC__StreamMetadata_SeekPoint)) { /* overflow check */
+					FLAC__metadata_object_delete(to);
+					return 0;
+				}
 				if(!copy_bytes_((FLAC__byte**)&to->data.seek_table.points, (FLAC__byte*)object->data.seek_table.points, object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint))) {
 					FLAC__metadata_object_delete(to);
 					return 0;
@@ -930,8 +939,12 @@ FLAC_API FLAC__bool FLAC__metadata_objec
 			return false;
 	}
 	else {
-		const unsigned old_size = object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint);
-		const unsigned new_size = new_num_points * sizeof(FLAC__StreamMetadata_SeekPoint);
+		const size_t old_size = object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint);
+		const size_t new_size = new_num_points * sizeof(FLAC__StreamMetadata_SeekPoint);
+
+		/* overflow check */
+		if((size_t)new_num_points > SIZE_MAX / sizeof(FLAC__StreamMetadata_SeekPoint))
+			return false;
 
 		FLAC__ASSERT(object->data.seek_table.num_points > 0);
 
@@ -1157,8 +1170,12 @@ FLAC_API FLAC__bool FLAC__metadata_objec
 			return false;
 	}
 	else {
-		const unsigned old_size = object->data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry);
-		const unsigned new_size = new_num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry);
+		const size_t old_size = object->data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry);
+		const size_t new_size = new_num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry);
+
+		/* overflow check */
+		if((size_t)new_num_comments > SIZE_MAX / sizeof(FLAC__StreamMetadata_VorbisComment_Entry))
+			return false;
 
 		FLAC__ASSERT(object->data.vorbis_comment.num_comments > 0);
 
@@ -1306,7 +1323,7 @@ FLAC_API FLAC__bool FLAC__metadata_objec
 		const size_t nn = strlen(field_name);
 		const size_t nv = strlen(field_value);
 		entry->length = nn + 1 /*=*/ + nv;
-		if(0 == (entry->entry = (FLAC__byte*)malloc(entry->length+1)))
+		if(0 == (entry->entry = (FLAC__byte*)safe_malloc_add_4op_(nn, /*+*/1, /*+*/nv, /*+*/1)))
 			return false;
 		memcpy(entry->entry, field_name, nn);
 		entry->entry[nn] = '=';
@@ -1333,9 +1350,9 @@ FLAC_API FLAC__bool FLAC__metadata_objec
 		FLAC__ASSERT(0 != eq);
 		if(0 == eq)
 			return false; /* double protection */
-		if(0 == (*field_name = (char*)malloc(nn+1)))
+		if(0 == (*field_name = (char*)safe_malloc_add_2op_(nn, /*+*/1)))
 			return false;
-		if(0 == (*field_value = (char*)malloc(nv+1))) {
+		if(0 == (*field_value = (char*)safe_malloc_add_2op_(nv, /*+*/1))) {
 			free(*field_name);
 			return false;
 		}
@@ -1465,8 +1482,12 @@ FLAC_API FLAC__bool FLAC__metadata_objec
 			return false;
 	}
 	else {
-		const unsigned old_size = track->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index);
-		const unsigned new_size = new_num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index);
+		const size_t old_size = track->num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index);
+		const size_t new_size = new_num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index);
+
+		/* overflow check */
+		if((size_t)new_num_indices > SIZE_MAX / sizeof(FLAC__StreamMetadata_CueSheet_Index))
+			return false;
 
 		FLAC__ASSERT(track->num_indices > 0);
 
@@ -1549,8 +1570,12 @@ FLAC_API FLAC__bool FLAC__metadata_objec
 			return false;
 	}
 	else {
-		const unsigned old_size = object->data.cue_sheet.num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track);
-		const unsigned new_size = new_num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track);
+		const size_t old_size = object->data.cue_sheet.num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track);
+		const size_t new_size = new_num_tracks * sizeof(FLAC__StreamMetadata_CueSheet_Track);
+
+		/* overflow check */
+		if((size_t)new_num_tracks > SIZE_MAX / sizeof(FLAC__StreamMetadata_CueSheet_Track))
+			return false;
 
 		FLAC__ASSERT(object->data.cue_sheet.num_tracks > 0);
 
@@ -1707,6 +1732,8 @@ FLAC_API FLAC__bool FLAC__metadata_objec
 
 	/* do the copy first so that if we fail we leave the object untouched */
 	if(copy) {
+		if(new_length >= SIZE_MAX) /* overflow check */
+			return false;
 		if(!copy_bytes_((FLAC__byte**)(&object->data.picture.mime_type), (FLAC__byte*)mime_type, new_length+1))
 			return false;
 	}
@@ -1737,6 +1764,8 @@ FLAC_API FLAC__bool FLAC__metadata_objec
 
 	/* do the copy first so that if we fail we leave the object untouched */
 	if(copy) {
+		if(new_length >= SIZE_MAX) /* overflow check */
+			return false;
 		if(!copy_bytes_(&object->data.picture.description, description, new_length+1))
 			return false;
 	}
--- src/libFLAC/stream_encoder.c-dist	2007-06-20 03:23:02.000000000 +0200
+++ src/libFLAC/stream_encoder.c	2007-10-12 15:04:37.000000000 +0200
@@ -54,6 +54,7 @@
 #endif
 #include "FLAC/assert.h"
 #include "FLAC/stream_decoder.h"
+#include "share/alloc.h"
 #include "protected/stream_encoder.h"
 #include "private/bitwriter.h"
 #include "private/bitmath.h"
@@ -989,7 +990,7 @@ static FLAC__StreamEncoderInitStatus ini
 		 */
 		encoder->private_->verify.input_fifo.size = encoder->protected_->blocksize+OVERREAD_;
 		for(i = 0; i < encoder->protected_->channels; i++) {
-			if(0 == (encoder->private_->verify.input_fifo.data[i] = (FLAC__int32*)malloc(sizeof(FLAC__int32) * encoder->private_->verify.input_fifo.size))) {
+			if(0 == (encoder->private_->verify.input_fifo.data[i] = (FLAC__int32*)safe_malloc_mul_2op_(sizeof(FLAC__int32), /*times*/encoder->private_->verify.input_fifo.size))) {
 				encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
 				return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR;
 			}
@@ -1727,7 +1728,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder
 	}
 	if(num_blocks) {
 		FLAC__StreamMetadata **m;
-		if(0 == (m = (FLAC__StreamMetadata**)malloc(sizeof(m[0]) * num_blocks)))
+		if(0 == (m = (FLAC__StreamMetadata**)safe_malloc_mul_2op_(sizeof(m[0]), /*times*/num_blocks)))
 			return false;
 		memcpy(m, metadata, sizeof(m[0]) * num_blocks);
 		encoder->protected_->metadata = m;
--- src/libFLAC/stream_decoder.c-dist	2007-07-23 18:14:31.000000000 +0200
+++ src/libFLAC/stream_decoder.c	2007-10-12 15:04:37.000000000 +0200
@@ -53,6 +53,7 @@
 #endif
 #endif
 #include "FLAC/assert.h"
+#include "share/alloc.h"
 #include "protected/stream_decoder.h"
 #include "private/bitreader.h"
 #include "private/bitmath.h"
@@ -181,7 +182,7 @@ typedef struct FLAC__StreamDecoderPrivat
 	FLAC__StreamMetadata seek_table;
 	FLAC__bool metadata_filter[128]; /* MAGIC number 128 == total number of metadata block types == 1 << 7 */
 	FLAC__byte *metadata_filter_ids;
-	unsigned metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */
+	size_t metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */
 	FLAC__Frame frame;
 	FLAC__bool cached; /* true if there is a byte in lookahead */
 	FLAC__CPUInfo cpuinfo;
@@ -784,7 +785,7 @@ FLAC_API FLAC__bool FLAC__stream_decoder
 	FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
 
 	if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) {
-		if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2))) {
+		if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) {
 			decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
 			return false;
 		}
@@ -843,7 +844,7 @@ FLAC_API FLAC__bool FLAC__stream_decoder
 	FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids);
 
 	if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) {
-		if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2))) {
+		if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) {
 			decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
 			return false;
 		}
@@ -1323,7 +1324,7 @@ FLAC__bool allocate_output_(FLAC__Stream
 		 * (at negative indices) for alignment purposes; we use 4
 		 * to keep the data well-aligned.
 		 */
-		tmp = (FLAC__int32*)malloc(sizeof(FLAC__int32)*(size+4));
+		tmp = (FLAC__int32*)safe_malloc_muladd2_(sizeof(FLAC__int32), /*times (*/size, /*+*/4/*)*/);
 		if(tmp == 0) {
 			decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
 			return false;
@@ -1348,7 +1349,7 @@ FLAC__bool allocate_output_(FLAC__Stream
 
 FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id)
 {
-	unsigned i;
+	size_t i;
 
 	FLAC__ASSERT(0 != decoder);
 	FLAC__ASSERT(0 != decoder->private_);
@@ -1469,6 +1470,11 @@ FLAC__bool read_metadata_(FLAC__StreamDe
 			if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8))
 				return false; /* read_callback_ sets the state for us */
 
+			if(real_length < FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) { /* underflow check */
+				decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;/*@@@@@@ maybe wrong error? need to resync?*/
+				return false;
+			}
+
 			real_length -= FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8;
 
 			if(decoder->private_->metadata_filter_ids_count > 0 && has_id_filtered_(decoder, block.data.application.id))
@@ -1531,7 +1537,7 @@ FLAC__bool read_metadata_(FLAC__StreamDe
 			if(!decoder->private_->is_seeking && decoder->private_->metadata_callback)
 				decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data);
 
-			/* now we have to free any malloc'ed data in the block */
+			/* now we have to free any malloc()ed data in the block */
 			switch(type) {
 				case FLAC__METADATA_TYPE_PADDING:
 					break;
@@ -1671,7 +1677,7 @@ FLAC__bool read_metadata_seektable_(FLAC
 	decoder->private_->seek_table.data.seek_table.num_points = length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
 
 	/* use realloc since we may pass through here several times (e.g. after seeking) */
-	if(0 == (decoder->private_->seek_table.data.seek_table.points = (FLAC__StreamMetadata_SeekPoint*)realloc(decoder->private_->seek_table.data.seek_table.points, decoder->private_->seek_table.data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint)))) {
+	if(0 == (decoder->private_->seek_table.data.seek_table.points = (FLAC__StreamMetadata_SeekPoint*)safe_realloc_mul_2op_(decoder->private_->seek_table.data.seek_table.points, decoder->private_->seek_table.data.seek_table.num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint)))) {
 		decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
 		return false;
 	}
@@ -1710,7 +1716,7 @@ FLAC__bool read_metadata_vorbiscomment_(
 	if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length))
 		return false; /* read_callback_ sets the state for us */
 	if(obj->vendor_string.length > 0) {
-		if(0 == (obj->vendor_string.entry = (FLAC__byte*)malloc(obj->vendor_string.length+1))) {
+		if(0 == (obj->vendor_string.entry = (FLAC__byte*)safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) {
 			decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
 			return false;
 		}
@@ -1728,7 +1734,7 @@ FLAC__bool read_metadata_vorbiscomment_(
 
 	/* read comments */
 	if(obj->num_comments > 0) {
-		if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)malloc(obj->num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) {
+		if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)safe_malloc_mul_2op_(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) {
 			decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
 			return false;
 		}
@@ -1737,7 +1743,7 @@ FLAC__bool read_metadata_vorbiscomment_(
 			if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length))
 				return false; /* read_callback_ sets the state for us */
 			if(obj->comments[i].length > 0) {
-				if(0 == (obj->comments[i].entry = (FLAC__byte*)malloc(obj->comments[i].length+1))) {
+				if(0 == (obj->comments[i].entry = (FLAC__byte*)safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) {
 					decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
 					return false;
 				}
@@ -1783,7 +1789,7 @@ FLAC__bool read_metadata_cuesheet_(FLAC_
 	obj->num_tracks = x;
 
 	if(obj->num_tracks > 0) {
-		if(0 == (obj->tracks = (FLAC__StreamMetadata_CueSheet_Track*)calloc(obj->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) {
+		if(0 == (obj->tracks = (FLAC__StreamMetadata_CueSheet_Track*)safe_calloc_(obj->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) {
 			decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
 			return false;
 		}
@@ -1816,7 +1822,7 @@ FLAC__bool read_metadata_cuesheet_(FLAC_
 			track->num_indices = (FLAC__byte)x;
 
 			if(track->num_indices > 0) {
-				if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)calloc(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) {
+				if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)safe_calloc_(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) {
 					decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
 					return false;
 				}
@@ -1853,7 +1859,7 @@ FLAC__bool read_metadata_picture_(FLAC__
 	/* read MIME type */
 	if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN))
 		return false; /* read_callback_ sets the state for us */
-	if(0 == (obj->mime_type = (char*)malloc(x+1))) {
+	if(0 == (obj->mime_type = (char*)safe_malloc_add_2op_(x, /*+*/1))) {
 		decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
 		return false;
 	}
@@ -1866,7 +1872,7 @@ FLAC__bool read_metadata_picture_(FLAC__
 	/* read description */
 	if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN))
 		return false; /* read_callback_ sets the state for us */
-	if(0 == (obj->description = (FLAC__byte*)malloc(x+1))) {
+	if(0 == (obj->description = (FLAC__byte*)safe_malloc_add_2op_(x, /*+*/1))) {
 		decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
 		return false;
 	}
@@ -1895,7 +1901,7 @@ FLAC__bool read_metadata_picture_(FLAC__
 	/* read data */
 	if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &(obj->data_length), FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN))
 		return false; /* read_callback_ sets the state for us */
-	if(0 == (obj->data = (FLAC__byte*)malloc(obj->data_length))) {
+	if(0 == (obj->data = (FLAC__byte*)safe_malloc_(obj->data_length))) {
 		decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
 		return false;
 	}
--- src/libFLAC/memory.c-dist	2007-06-14 08:10:00.000000000 +0200
+++ src/libFLAC/memory.c	2007-10-12 15:04:37.000000000 +0200
@@ -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,7 +45,7 @@ void *FLAC__memory_alloc_aligned(size_t 
 
 #ifdef FLAC__ALIGN_MALLOC_DATA
 	/* align on 32-byte (256-bit) boundary */
-	x = malloc(bytes+31);
+	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; */
@@ -64,7 +65,7 @@ void *FLAC__memory_alloc_aligned(size_t 
 		return 0;
 #endif
 #else
-	x = malloc(bytes);
+	x = safe_malloc_(bytes);
 	*aligned_address = x;
 #endif
 	return x;
@@ -83,7 +84,10 @@ FLAC__bool FLAC__memory_alloc_aligned_in
 	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((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+		return false;
+
+	pu = (FLAC__int32*)FLAC__memory_alloc_aligned(sizeof(*pu) * (size_t)elements, &u.pv);
 	if(0 == pu) {
 		return false;
 	}
@@ -109,7 +113,10 @@ FLAC__bool FLAC__memory_alloc_aligned_ui
 	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((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+		return false;
+
+	pu = (FLAC__uint32*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
 	if(0 == pu) {
 		return false;
 	}
@@ -135,7 +142,10 @@ FLAC__bool FLAC__memory_alloc_aligned_ui
 	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((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+		return false;
+
+	pu = (FLAC__uint64*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
 	if(0 == pu) {
 		return false;
 	}
@@ -161,7 +171,10 @@ FLAC__bool FLAC__memory_alloc_aligned_un
 	FLAC__ASSERT(0 != aligned_pointer);
 	FLAC__ASSERT(unaligned_pointer != aligned_pointer);
 
-	pu = (unsigned*)FLAC__memory_alloc_aligned(sizeof(unsigned) * elements, &u.pv);
+	if((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+		return false;
+
+	pu = (unsigned*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
 	if(0 == pu) {
 		return false;
 	}
@@ -189,7 +202,10 @@ FLAC__bool FLAC__memory_alloc_aligned_re
 	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((size_t)elements > SIZE_MAX / sizeof(*pu)) /* overflow check */
+		return false;
+
+	pu = (FLAC__real*)FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv);
 	if(0 == pu) {
 		return false;
 	}
--- src/libFLAC/include/private/md5.h-dist	2007-03-23 05:48:36.000000000 +0100
+++ src/libFLAC/include/private/md5.h	2007-10-12 15:04:37.000000000 +0200
@@ -33,7 +33,7 @@ typedef struct {
 	FLAC__uint32 buf[4];
 	FLAC__uint32 bytes[2];
 	FLAC__byte *internal_buf;
-	unsigned capacity;
+	size_t capacity;
 } FLAC__MD5Context;
 
 void FLAC__MD5Init(FLAC__MD5Context *context);
--- src/libFLAC/bitwriter.c-dist	2007-07-23 18:14:31.000000000 +0200
+++ src/libFLAC/bitwriter.c	2007-10-12 15:04:37.000000000 +0200
@@ -48,6 +48,7 @@
 #include "private/bitwriter.h"
 #include "private/crc.h"
 #include "FLAC/assert.h"
+#include "share/alloc.h"
 
 /* Things should be fastest when this matches the machine word size */
 /* WATCHOUT: if you change this you must also change the following #defines down to SWAP_BE_WORD_TO_HOST below to match */
@@ -139,7 +140,7 @@ static FLAC__bool bitwriter_grow_(FLAC__
 	FLAC__ASSERT(new_capacity > bw->capacity);
 	FLAC__ASSERT(new_capacity >= bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD));
 
-	new_buffer = (bwword*)realloc(bw->buffer, sizeof(bwword)*new_capacity);
+	new_buffer = (bwword*)safe_realloc_mul_2op_(bw->buffer, sizeof(bwword), /*times*/new_capacity);
 	if(new_buffer == 0)
 		return false;
 	bw->buffer = new_buffer;
--- src/libFLAC/ogg_helper.c-dist	2007-02-02 07:58:22.000000000 +0100
+++ src/libFLAC/ogg_helper.c	2007-10-12 15:04:37.000000000 +0200
@@ -36,6 +36,7 @@
 #include <stdlib.h> /* for malloc() */
 #include <string.h> /* for memcmp(), memcpy() */
 #include "FLAC/assert.h"
+#include "share/alloc.h"
 #include "private/ogg_helper.h"
 #include "protected/stream_encoder.h"
 
@@ -112,7 +113,7 @@ FLAC__bool simple_ogg_page__get_at(FLAC_
 	}
 
 	/* allocate space for the page header */
-	if(0 == (page->header = (unsigned char *)malloc(OGG_MAX_HEADER_LEN))) {
+	if(0 == (page->header = (unsigned char *)safe_malloc_(OGG_MAX_HEADER_LEN))) {
 		encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
 		return false;
 	}
@@ -154,7 +155,7 @@ FLAC__bool simple_ogg_page__get_at(FLAC_
 	}
 
 	/* allocate space for the page body */
-	if(0 == (page->body = (unsigned char *)malloc(page->body_len))) {
+	if(0 == (page->body = (unsigned char *)safe_malloc_(page->body_len))) {
 		encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
 		return false;
 	}
--- src/plugin_common/charset.c-dist	2007-02-02 07:58:23.000000000 +0100
+++ src/plugin_common/charset.c	2007-10-12 15:04:37.000000000 +0200
@@ -83,6 +83,8 @@ char* FLAC_plugin__charset_convert_strin
 	/* Due to a GLIBC bug, round outbuf_size up to a multiple of 4 */
 	/* + 1 for nul in case len == 1 */
 	outsize = ((length + 3) & ~3) + 1;
+	if(outsize < length) /* overflow check */
+		return NULL;
 	out = (char*)malloc(outsize);
 	outleft = outsize - 1;
 	outptr = out;
@@ -95,6 +97,10 @@ retry:
 		{
 			case E2BIG:
 				used = outptr - out;
+				if((outsize - 1) * 2 + 1 <= outsize) { /* overflow check */
+					free(out);
+					return NULL;
+				}
 				outsize = (outsize - 1) * 2 + 1;
 				out = realloc(out, outsize);
 				outptr = out + used;
--- src/plugin_common/tags.c-dist	2007-03-12 06:08:21.000000000 +0100
+++ src/plugin_common/tags.c	2007-10-12 15:04:38.000000000 +0200
@@ -27,15 +27,16 @@
 #include "tags.h"
 #include "FLAC/assert.h"
 #include "FLAC/metadata.h"
+#include "share/alloc.h"
 
 #ifndef FLaC__INLINE
 #define FLaC__INLINE
 #endif
 
 
-static FLaC__INLINE unsigned local__wide_strlen(const FLAC__uint16 *s)
+static FLaC__INLINE size_t local__wide_strlen(const FLAC__uint16 *s)
 {
-	unsigned n = 0;
+	size_t n = 0;
 	while(*s++)
 		n++;
 	return n;
@@ -47,7 +48,7 @@ static FLaC__INLINE unsigned local__wide
  * and a more clear explanation at the end of this section:
  *   http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
  */
-static FLaC__INLINE unsigned local__utf8len(const FLAC__byte *utf8)
+static FLaC__INLINE size_t local__utf8len(const FLAC__byte *utf8)
 {
 	FLAC__ASSERT(0 != utf8);
 	if ((utf8[0] & 0x80) == 0) {
@@ -89,9 +90,9 @@ static FLaC__INLINE unsigned local__utf8
 }
 
 
-static FLaC__INLINE unsigned local__utf8_to_ucs2(const FLAC__byte *utf8, FLAC__uint16 *ucs2)
+static FLaC__INLINE size_t local__utf8_to_ucs2(const FLAC__byte *utf8, FLAC__uint16 *ucs2)
 {
-	const unsigned len = local__utf8len(utf8);
+	const size_t len = local__utf8len(utf8);
 
 	FLAC__ASSERT(0 != ucs2);
 
@@ -110,7 +111,7 @@ static FLaC__INLINE unsigned local__utf8
 static FLAC__uint16 *local__convert_utf8_to_ucs2(const char *src, unsigned length)
 {
 	FLAC__uint16 *out;
-	unsigned chars = 0;
+	size_t chars = 0;
 
 	FLAC__ASSERT(0 != src);
 
@@ -127,7 +128,7 @@ static FLAC__uint16 *local__convert_utf8
 	}
 
 	/* allocate */
-	out = (FLAC__uint16*)malloc(chars * sizeof(FLAC__uint16));
+	out = (FLAC__uint16*)safe_malloc_mul_2op_(chars, /*times*/sizeof(FLAC__uint16));
 	if (0 == out) {
 		FLAC__ASSERT(0);
 		return 0;
@@ -144,7 +145,7 @@ static FLAC__uint16 *local__convert_utf8
 	return out;
 }
 
-static FLaC__INLINE unsigned local__ucs2len(FLAC__uint16 ucs2)
+static FLaC__INLINE size_t local__ucs2len(FLAC__uint16 ucs2)
 {
 	if (ucs2 < 0x0080)
 		return 1;
@@ -154,7 +155,7 @@ static FLaC__INLINE unsigned local__ucs2
 		return 3;
 }
 
-static FLaC__INLINE unsigned local__ucs2_to_utf8(FLAC__uint16 ucs2, FLAC__byte *utf8)
+static FLaC__INLINE size_t local__ucs2_to_utf8(FLAC__uint16 ucs2, FLAC__byte *utf8)
 {
 	if (ucs2 < 0x080) {
 		utf8[0] = (FLAC__byte)ucs2;
@@ -176,19 +177,23 @@ static FLaC__INLINE unsigned local__ucs2
 static char *local__convert_ucs2_to_utf8(const FLAC__uint16 *src, unsigned length)
 {
 	char *out;
-	unsigned len = 0;
+	size_t len = 0, n;
 
 	FLAC__ASSERT(0 != src);
 
 	/* calculate length */
 	{
 		unsigned i;
-		for (i = 0; i < length; i++)
-			len += local__ucs2len(src[i]);
+		for (i = 0; i < length; i++) {
+			n = local__ucs2len(src[i]);
+			if(len + n < len) /* overflow check */
+				return 0;
+			len += n;
+		}
 	}
 
 	/* allocate */
-	out = (char*)malloc(len * sizeof(char));
+	out = (char*)safe_malloc_mul_2op_(len, /*times*/sizeof(char));
 	if (0 == out)
 		return 0;
 
@@ -311,7 +316,7 @@ FLAC__bool FLAC_plugin__tags_add_tag_utf
 		const size_t value_len = strlen(value);
 		const size_t separator_len = strlen(separator);
 		FLAC__byte *new_entry;
-		if(0 == (new_entry = (FLAC__byte*)realloc(entry->entry, entry->length + value_len + separator_len + 1)))
+		if(0 == (new_entry = (FLAC__byte*)safe_realloc_add_4op_(entry->entry, entry->length, /*+*/value_len, /*+*/separator_len, /*+*/1)))
 			return false;
 		memcpy(new_entry+entry->length, separator, separator_len);
 		entry->length += separator_len;
--- src/libFLAC++/metadata.cpp-dist	2007-02-22 02:37:33.000000000 +0100
+++ src/libFLAC++/metadata.cpp	2007-10-12 15:04:37.000000000 +0200
@@ -29,6 +29,8 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#define __STDC_LIMIT_MACROS 1 /* otherwise SIZE_MAX is not defined for c++ */
+#include "share/alloc.h"
 #include "FLAC++/metadata.h"
 #include "FLAC/assert.h"
 #include <stdlib.h> // for malloc(), free()
@@ -574,7 +576,7 @@
 
 			clear_entry();
 
-			if(0 == (entry_.entry = (FLAC__byte*)malloc(field_length+1))) {
+			if(0 == (entry_.entry = (FLAC__byte*)safe_malloc_add_2op_(field_length, /*+*/1))) {
 				is_valid_ = false;
 			}
 			else {
@@ -623,7 +625,7 @@
 
 			clear_field_value();
 
-			if(0 == (field_value_ = (char *)malloc(field_value_length+1))) {
+			if(0 == (field_value_ = (char *)safe_malloc_add_2op_(field_value_length, /*+*/1))) {
 				is_valid_ = false;
 			}
 			else {
@@ -713,7 +715,7 @@
 		{
 			clear_entry();
 
-			if(0 == (entry_.entry = (FLAC__byte*)malloc(field_name_length_ + 1 + field_value_length_ + 1))) {
+			if(0 == (entry_.entry = (FLAC__byte*)safe_malloc_add_4op_(field_name_length_, /*+*/1, /*+*/field_value_length_, /*+*/1))) {
 				is_valid_ = false;
 			}
 			else {
@@ -739,7 +741,7 @@
 				p = (const char *)entry_.entry + entry_.length;
 
 			field_name_length_ = (unsigned)(p - (const char *)entry_.entry);
-			if(0 == (field_name_ = (char *)malloc(field_name_length_ + 1))) { // +1 for the trailing \0
+			if(0 == (field_name_ = (char *)safe_malloc_add_2op_(field_name_length_, /*+*/1))) { // +1 for the trailing \0
 				is_valid_ = false;
 				return;
 			}
@@ -748,14 +750,14 @@
 
 			if(entry_.length - field_name_length_ == 0) {
 				field_value_length_ = 0;
-				if(0 == (field_value_ = (char *)malloc(0))) {
+				if(0 == (field_value_ = (char *)safe_malloc_(0))) {
 					is_valid_ = false;
 					return;
 				}
 			}
 			else {
 				field_value_length_ = entry_.length - field_name_length_ - 1;
-				if(0 == (field_value_ = (char *)malloc(field_value_length_ + 1))) { // +1 for the trailing \0
+				if(0 == (field_value_ = (char *)safe_malloc_add_2op_(field_value_length_, /*+*/1))) { // +1 for the trailing \0
 					is_valid_ = false;
 					return;
 				}
--- /dev/null	2007-10-03 18:59:38.000000000 +0200
+++ include/share/alloc.h	2007-09-12 07:32:21.000000000 +0200
@@ -0,0 +1,212 @@
+/* alloc - Convenience routines for safely allocating memory
+ * Copyright (C) 2007  Josh Coalson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef FLAC__SHARE__ALLOC_H
+#define FLAC__SHARE__ALLOC_H
+
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+/* WATCHOUT: for c++ you may have to #define __STDC_LIMIT_MACROS 1 real early
+ * before #including this file,  otherwise SIZE_MAX might not be defined
+ */
+
+#include <limits.h> /* for SIZE_MAX */
+#if !defined _MSC_VER && !defined __MINGW32__ && !defined __EMX__
+#include <stdint.h> /* for SIZE_MAX in case limits.h didn't get it */
+#endif
+#include <stdlib.h> /* for size_t, malloc(), etc */
+
+#ifndef SIZE_MAX
+# ifndef SIZE_T_MAX
+#  ifdef _MSC_VER
+#   define SIZE_T_MAX UINT_MAX
+#  else
+#   error
+#  endif
+# endif
+# define SIZE_MAX SIZE_T_MAX
+#endif
+
+#ifndef FLaC__INLINE
+#define FLaC__INLINE
+#endif
+
+/* avoid malloc()ing 0 bytes, see:
+ * https://www.securecoding.cert.org/confluence/display/seccode/MEM04-A.+Do+not+make+assumptions+about+the+result+of+allocating+0+bytes?focusedCommentId=5407003
+*/
+static FLaC__INLINE void *safe_malloc_(size_t size)
+{
+	/* malloc(0) is undefined; FLAC src convention is to always allocate */
+	if(!size)
+		size++;
+	return malloc(size);
+}
+
+static FLaC__INLINE void *safe_calloc_(size_t nmemb, size_t size)
+{
+	if(!nmemb || !size)
+		return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
+	return calloc(nmemb, size);
+}
+
+/*@@@@ there's probably a better way to prevent overflows when allocating untrusted sums but this works for now */
+
+static FLaC__INLINE void *safe_malloc_add_2op_(size_t size1, size_t size2)
+{
+	size2 += size1;
+	if(size2 < size1)
+		return 0;
+	return safe_malloc_(size2);
+}
+
+static FLaC__INLINE void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3)
+{
+	size2 += size1;
+	if(size2 < size1)
+		return 0;
+	size3 += size2;
+	if(size3 < size2)
+		return 0;
+	return safe_malloc_(size3);
+}
+
+static FLaC__INLINE void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4)
+{
+	size2 += size1;
+	if(size2 < size1)
+		return 0;
+	size3 += size2;
+	if(size3 < size2)
+		return 0;
+	size4 += size3;
+	if(size4 < size3)
+		return 0;
+	return safe_malloc_(size4);
+}
+
+static FLaC__INLINE void *safe_malloc_mul_2op_(size_t size1, size_t size2)
+#if 0
+needs support for cases where sizeof(size_t) != 4
+{
+	/* could be faster #ifdef'ing off SIZEOF_SIZE_T */
+	if(sizeof(size_t) == 4) {
+		if ((double)size1 * (double)size2 < 4294967296.0)
+			return malloc(size1*size2);
+	}
+	return 0;
+}
+#else
+/* better? */
+{
+	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);
+}
+#endif
+
+static FLaC__INLINE void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3)
+{
+	if(!size1 || !size2 || !size3)
+		return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
+	if(size1 > SIZE_MAX / size2)
+		return 0;
+	size1 *= size2;
+	if(size1 > SIZE_MAX / size3)
+		return 0;
+	return malloc(size1*size3);
+}
+
+/* size1*size2 + size3 */
+static FLaC__INLINE void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3)
+{
+	if(!size1 || !size2)
+		return safe_malloc_(size3);
+	if(size1 > SIZE_MAX / size2)
+		return 0;
+	return safe_malloc_add_2op_(size1*size2, size3);
+}
+
+/* size1 * (size2 + size3) */
+static FLaC__INLINE void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3)
+{
+	if(!size1 || (!size2 && !size3))
+		return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */
+	size2 += size3;
+	if(size2 < size3)
+		return 0;
+	return safe_malloc_mul_2op_(size1, size2);
+}
+
+static FLaC__INLINE void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2)
+{
+	size2 += size1;
+	if(size2 < size1)
+		return 0;
+	return realloc(ptr, size2);
+}
+
+static FLaC__INLINE void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3)
+{
+	size2 += size1;
+	if(size2 < size1)
+		return 0;
+	size3 += size2;
+	if(size3 < size2)
+		return 0;
+	return realloc(ptr, size3);
+}
+
+static FLaC__INLINE void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4)
+{
+	size2 += size1;
+	if(size2 < size1)
+		return 0;
+	size3 += size2;
+	if(size3 < size2)
+		return 0;
+	size4 += size3;
+	if(size4 < size3)
+		return 0;
+	return realloc(ptr, size4);
+}
+
+static FLaC__INLINE void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2)
+{
+	if(!size1 || !size2)
+		return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */
+	if(size1 > SIZE_MAX / size2)
+		return 0;
+	return realloc(ptr, size1*size2);
+}
+
+/* size1 * (size2 + size3) */
+static FLaC__INLINE void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3)
+{
+	if(!size1 || (!size2 && !size3))
+		return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */
+	size2 += size3;
+	if(size2 < size3)
+		return 0;
+	return safe_realloc_mul_2op_(ptr, size1, size2);
+}
+
+#endif