[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