[xiph-commits] r3854 - libfishsound/trunk/src/libfishsound

conrad at svn.annodex.net conrad at svn.annodex.net
Fri Feb 20 23:31:28 PST 2009


Author: conrad
Date: 2009-02-20 23:31:28 -0800 (Fri, 20 Feb 2009)
New Revision: 3854

Modified:
   libfishsound/trunk/src/libfishsound/flac.c
Log:
libfishsound flac: chase malloc/realloc failures, and check
libflac encode/decode status for memory allocation errors
For Mozilla bug 468293

Modified: libfishsound/trunk/src/libfishsound/flac.c
===================================================================
--- libfishsound/trunk/src/libfishsound/flac.c	2009-02-20 12:43:43 UTC (rev 3853)
+++ libfishsound/trunk/src/libfishsound/flac.c	2009-02-21 07:31:28 UTC (rev 3854)
@@ -141,6 +141,7 @@
   FishSound* fsound = (FishSound*)client_data;
   FishSoundFlacInfo* fi = (FishSoundFlacInfo *)fsound->codec_data;
   int i, j, channels, blocksize, offset;
+  float * ipcm;
 
   channels = frame->header.channels;
   blocksize = frame->header.blocksize;
@@ -158,7 +159,10 @@
 	FishSoundDecoded_FloatIlv dfi;
 	float* retpcm;
 
-	fi->ipcm = realloc(fi->ipcm, sizeof(float) * channels * blocksize);
+        if ((ipcm = realloc(fi->ipcm, sizeof(float) * channels * blocksize)) == NULL)
+          return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
+
+	fi->ipcm = ipcm;
 	retpcm = (float*) fi->ipcm;
 	for (i = 0; i < blocksize; i++) {
 	  offset = i * channels;
@@ -173,7 +177,9 @@
 	float *d; /* de-interleave dest */
 
         for (j = 0; j < channels; j++) {
-	  fi->pcm_out[j] = realloc(fi->pcm_out[j], sizeof(float) * blocksize);
+          if ((ipcm = realloc(fi->pcm_out[j], sizeof(float) * blocksize)) == NULL)
+            return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
+	  fi->pcm_out[j] = ipcm;
         }
 	for (i = 0; i < blocksize; i++)
 	  for (j = 0; j < channels; j++) {
@@ -296,12 +302,14 @@
 #endif
       return -1;
     }
-    fi->buffer = fs_malloc(sizeof(unsigned char)*bytes);
+    if ((fi->buffer = fs_malloc(sizeof(unsigned char)*bytes)) == NULL)
+      return FISH_SOUND_ERR_OUT_OF_MEMORY;
+
     memcpy(fi->buffer, buf+9, bytes-9);
     fi->bufferlength = bytes-9;
   }
   else if (fi->packetno <= fi->header_packets){
-    unsigned char* tmp = fs_malloc(sizeof(unsigned char)*(fi->bufferlength+bytes));
+    unsigned char* tmp;
 #ifdef DEBUG
     printf("fs_flac_decode: handling header (fi->header_packets = %d)\n",
            fi->header_packets);
@@ -322,23 +330,38 @@
       }
     }
 
+    if ((tmp = fs_malloc(sizeof(unsigned char)*(fi->bufferlength+bytes))) == NULL)
+      return FISH_SOUND_ERR_OUT_OF_MEMORY;
+
     memcpy(tmp, fi->buffer, fi->bufferlength);
     memcpy(tmp+fi->bufferlength, buf, bytes);
     fi->bufferlength += bytes;
     fs_free(fi->buffer);
     fi->buffer = tmp;
     if (fi->packetno == fi->header_packets) {
-      FLAC__stream_decoder_process_until_end_of_metadata(fi->fsd);
+      if (FLAC__stream_decoder_process_until_end_of_metadata(fi->fsd) == false) {
+        goto dec_err;
+      }
       fs_free(fi->buffer);
     }
   } else {
     fi->buffer = buf;
     fi->bufferlength = bytes;
-    FLAC__stream_decoder_process_single(fi->fsd);
+    if (FLAC__stream_decoder_process_single(fi->fsd) == false) {
+      goto dec_err;
+    }
   }
   fi->packetno++;
 
   return 0;
+
+dec_err:
+    switch (FLAC__stream_decoder_get_state(fi->fsd)) {
+    case FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
+      return FISH_SOUND_ERR_OUT_OF_MEMORY;
+    default:
+      return FISH_SOUND_ERR_GENERIC;
+    }
 }
 #else /* !FS_DECODE */
 
@@ -372,7 +395,9 @@
         printf("fs_flac_enc_write_callback: generating FLAC header packet: "
                "%c%c%c%c\n", buffer[0], buffer[1], buffer[2], buffer[3]);
 #endif
-	fi->buffer = (unsigned char*)fs_malloc(sizeof(unsigned char)*(bytes+9));
+	if ((fi->buffer = (unsigned char*)fs_malloc(sizeof(unsigned char)*(bytes+9))) == NULL)
+          return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
+
 	fi->buffer[0] = 0x7f;
 	fi->buffer[1] = 0x46; /* 'F' */
 	fi->buffer[2] = 0x4c; /* 'L' */
@@ -390,7 +415,11 @@
         /* Make a temporary copy of the metadata header to pass to the user
          * callback.
          */
-	unsigned char* tmp = (unsigned char*)fs_malloc(sizeof(unsigned char)*(bytes+fi->bufferlength));
+	unsigned char* tmp;
+
+        if ((tmp = (unsigned char*)fs_malloc(sizeof(unsigned char)*(bytes+fi->bufferlength))) == NULL)
+          return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
+
 	memcpy (tmp, fi->buffer, fi->bufferlength);
 	memcpy (tmp+fi->bufferlength, buffer, bytes);
 	fs_free(fi->buffer);
@@ -481,7 +510,8 @@
     length += value_len + 1;
   }
 
-  entry = fs_malloc (length);
+  if ((entry = fs_malloc (length)) == NULL)
+    return NULL;
 
   /* We assume that comment->name, value are NUL terminated, as they were
    * produced by our own comments.c */
@@ -501,7 +531,7 @@
 fs_flac_encode_vorbiscomments (FishSound * fsound)
 {
   FishSoundFlacInfo * fi = fsound->codec_data;
-  FLAC__StreamMetadata * metadata;
+  FLAC__StreamMetadata * metadata = NULL;
   const FishSoundComment * comment;
   unsigned int i=0, length=0, total_length;
   FLAC__VCEntry * comments;
@@ -521,11 +551,13 @@
 
   if (length == 0) return NULL;
 
-  comments = (FLAC__VCEntry *)fs_malloc (sizeof(FLAC__VCEntry) * length);
+  if ((comments = (FLAC__VCEntry *)fs_malloc (sizeof(FLAC__VCEntry) * length)) == NULL)
+    goto encode_vc_oom;
   
   for (comment = fish_sound_comment_first (fsound); comment;
        comment = fish_sound_comment_next (fsound, comment)) {
-    comments[i].entry = fs_flac_encode_vcentry (comment);
+    if ((comments[i].entry = fs_flac_encode_vcentry (comment)) == NULL) {
+    }
     comments[i].length = strlen((char *)comments[i].entry);
 
     /* In the generated vorbiscomment data, each entry is preceded by a
@@ -534,7 +566,9 @@
     i++;
   }
 
-  metadata = (FLAC__StreamMetadata *) fs_malloc (sizeof (*metadata));
+  if ((metadata = (FLAC__StreamMetadata *) fs_malloc (sizeof (*metadata))) == NULL)
+    goto encode_vc_oom;
+
   metadata->type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
   metadata->is_last = true;
   metadata->length = total_length;
@@ -546,6 +580,21 @@
   fi->enc_vc_metadata = metadata;
 
   return metadata;
+
+encode_vc_oom:
+  if (metadata != NULL)
+    fs_free (metadata);
+
+  /* Unwind allocated comment entries */
+  for (i--; i >= 0; i--) {
+    if (comments[i].entry != NULL)
+      fs_free (comments[i].entry);
+  }
+
+  if (comments != NULL)
+    fs_free (comments);
+
+  return NULL;
 }
 
 static FishSound *
@@ -591,10 +640,18 @@
 }
 
 static long
+fs_flac_encode_fatal (FishSoundFlacInfo *fi, long err)
+{
+  FLAC__stream_encoder_delete (fi->fse);
+  fi->fse = NULL;
+  return err;
+}
+
+static long
 fs_flac_encode_f (FishSound * fsound, float * pcm[], long frames)
 {
   FishSoundFlacInfo *fi = fsound->codec_data;
-  FLAC__int32 *buffer;
+  FLAC__int32 *buffer, *ipcm;
   float * p, norm = (1 << (BITS_PER_SAMPLE - 1));
   long i;
   int j, channels = fsound->info.channels;
@@ -603,7 +660,10 @@
   printf("fs_flac_encode_f: IN, frames = %ld\n", frames);
 #endif
 
-  fi->ipcm = realloc(fi->ipcm, sizeof(FLAC__int32) * channels * frames);
+  if ((ipcm = realloc(fi->ipcm, sizeof(FLAC__int32) * channels * frames)) == NULL)
+    return FISH_SOUND_ERR_OUT_OF_MEMORY;
+
+  fi->ipcm = ipcm;
   buffer = (FLAC__int32*) fi->ipcm;
   for (i = 0; i < frames; i++) {
     for (j = 0; j < channels; j++) {
@@ -617,7 +677,17 @@
 
   /* We could have used FLAC__stream_encoder_process() and a more direct
    * conversion loop above, rather than converting and interleaving. */
-  FLAC__stream_encoder_process_interleaved(fi->fse, buffer, frames);
+  if (FLAC__stream_encoder_process_interleaved(fi->fse, buffer, frames) == false) {
+    switch (FLAC__stream_encoder_get_state (fi->fse)) {
+    case FLAC__STREAM_ENCODER_OK:
+    case FLAC__STREAM_ENCODER_UNINITIALIZED:
+      break;
+    case FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR:
+      return fs_flac_encode_fatal (fi, FISH_SOUND_ERR_OUT_OF_MEMORY);
+    default:
+      return fs_flac_encode_fatal (fi, FISH_SOUND_ERR_GENERIC);
+    }
+  }
 
   fi->packetno++;
 
@@ -628,7 +698,7 @@
 fs_flac_encode_f_ilv (FishSound * fsound, float ** pcm, long frames)
 {
   FishSoundFlacInfo *fi = fsound->codec_data;
-  FLAC__int32 *buffer;
+  FLAC__int32 *buffer, *ipcm;
   float * p = (float*)pcm, norm = (1 << (BITS_PER_SAMPLE - 1));
   long i, length = frames * fsound->info.channels;
 
@@ -636,7 +706,10 @@
   printf("fs_flac_encode_f_ilv: IN, frames = %ld\n", frames);
 #endif
 
-  fi->ipcm = realloc(fi->ipcm, sizeof(FLAC__int32)*fsound->info.channels*frames);
+  if ((ipcm = realloc(fi->ipcm, sizeof(FLAC__int32)*fsound->info.channels*frames)) == NULL)
+    return FISH_SOUND_ERR_OUT_OF_MEMORY;
+
+  fi->ipcm = ipcm;
   buffer = (FLAC__int32*) fi->ipcm;
   for (i=0; i<length; i++)
     buffer[i] = p[i] * norm;
@@ -644,7 +717,17 @@
   if (fi->packetno == 0)
     fs_flac_enc_headers (fsound);
 
-  FLAC__stream_encoder_process_interleaved(fi->fse, buffer, frames);
+  if (FLAC__stream_encoder_process_interleaved(fi->fse, buffer, frames) == false) {
+    switch (FLAC__stream_encoder_get_state (fi->fse)) {
+    case FLAC__STREAM_ENCODER_OK:
+    case FLAC__STREAM_ENCODER_UNINITIALIZED:
+      break;
+    case FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR:
+      return fs_flac_encode_fatal (fi, FISH_SOUND_ERR_OUT_OF_MEMORY);
+    default:
+      return fs_flac_encode_fatal (fi, FISH_SOUND_ERR_GENERIC);
+    }
+  }
 
   fi->packetno++;
 



More information about the commits mailing list