From ec53bd293c02a605f3977fb29104d95cff40574e Mon Sep 17 00:00:00 2001 From: conrad Date: Sun, 7 Dec 2008 12:35:03 +0000 Subject: [PATCH] liboggz: handle allocation failure due to out of memory throughout, for Mozilla bug 468280 Adds new error return OGGZ_ERR_OUT_OF_MEMORY git-svn-id: http://svn.annodex.net/liboggz/trunk@3816 8158c8cd-e7e1-0310-9fa4-c5954c97daef --- include/oggz/oggz_constants.h | 3 +++ include/oggz/oggz_table.h | 1 + include/oggz/oggz_write.h | 1 + src/liboggz/oggz.c | 18 ++++++++++++- src/liboggz/oggz_auto.c | 14 ++++++++-- src/liboggz/oggz_comments.c | 50 +++-------------------------------- src/liboggz/oggz_dlist.c | 44 +++++++++++++++++++++++------- src/liboggz/oggz_dlist.h | 4 +-- src/liboggz/oggz_read.c | 2 ++ src/liboggz/oggz_table.c | 4 +++ src/liboggz/oggz_vector.c | 46 +++----------------------------- src/liboggz/oggz_write.c | 9 ++++++- 12 files changed, 92 insertions(+), 104 deletions(-) diff --git a/include/oggz/oggz_constants.h b/include/oggz/oggz_constants.h index 5aa176e..da553c6 100644 --- a/include/oggz/oggz_constants.h +++ b/include/oggz/oggz_constants.h @@ -173,6 +173,9 @@ enum OggzError { /** Hole (sequence number gap) detected in input data */ OGGZ_ERR_HOLE_IN_DATA = -17, + /** Out of memory */ + OGGZ_ERR_OUT_OF_MEMORY = -18, + /** The requested serialno does not exist in this OGGZ */ OGGZ_ERR_BAD_SERIALNO = -20, diff --git a/include/oggz/oggz_table.h b/include/oggz/oggz_table.h index 2c68be7..1accd8c 100644 --- a/include/oggz/oggz_table.h +++ b/include/oggz/oggz_table.h @@ -48,6 +48,7 @@ typedef void OggzTable; /** * Instantiate a new OggzTable * \returns A new OggzTable + * \retval NULL Could not allocate memory for table */ OggzTable * oggz_table_new (void); diff --git a/include/oggz/oggz_write.h b/include/oggz/oggz_write.h index a12f5c7..13ac71e 100644 --- a/include/oggz/oggz_write.h +++ b/include/oggz/oggz_write.h @@ -177,6 +177,7 @@ int oggz_write_set_hungry_callback (OGGZ * oggz, * 32 bits, ie. within the range (-(2^31), (2^31)-1) * \retval OGGZ_ERR_BAD_OGGZ \a oggz does not refer to an existing OGGZ * \retval OGGZ_ERR_INVALID Operation not suitable for this OGGZ + * \retval OGGZ_ERR_OUT_OF_MEMORY Unable to allocate memory to queue packet * * \note If \a op->b_o_s is initialized to \a -1 before calling * oggz_write_feed(), Oggz will fill it in with the appropriate diff --git a/src/liboggz/oggz.c b/src/liboggz/oggz.c index e3c5ca7..c383b84 100644 --- a/src/liboggz/oggz.c +++ b/src/liboggz/oggz.c @@ -92,6 +92,10 @@ oggz_new (int flags) oggz->cb_next = 0; oggz->streams = oggz_vector_new (); + if (oggz->streams == NULL) { + goto err_oggz_new; + } + oggz->all_at_eos = 0; oggz->metric = NULL; @@ -102,14 +106,26 @@ oggz_new (int flags) oggz->order_user_data = NULL; oggz->packet_buffer = oggz_dlist_new (); + if (oggz->packet_buffer == NULL) { + goto err_streams_new; + } if (OGGZ_CONFIG_WRITE && (oggz->flags & OGGZ_WRITE)) { - oggz_write_init (oggz); + if (oggz_write_init (oggz) == NULL) + goto err_packet_buffer_new; } else if (OGGZ_CONFIG_READ) { oggz_read_init (oggz); } return oggz; + +err_packet_buffer_new: + oggz_free (oggz->packet_buffer); +err_streams_new: + oggz_free (oggz->streams); +err_oggz_new: + oggz_free (oggz); + return NULL; } OGGZ * diff --git a/src/liboggz/oggz_auto.c b/src/liboggz/oggz_auto.c index c5d96d8..0427395 100644 --- a/src/liboggz/oggz_auto.c +++ b/src/liboggz/oggz_auto.c @@ -458,6 +458,7 @@ auto_calc_speex(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) { if (stream->calculate_data == NULL) { stream->calculate_data = malloc(sizeof(auto_calc_speex_info_t)); + if (stream->calculate_data == NULL) return -1; info = stream->calculate_data; info->encountered_first_data_packet = 0; info->packet_size = @@ -511,6 +512,8 @@ auto_calc_celt (ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) { if (stream->calculate_data == NULL) { stream->calculate_data = malloc(sizeof(auto_calc_celt_info_t)); + if (stream->calculate_data == NULL) return -1; + info = stream->calculate_data; info->encountered_first_data_packet = 0; @@ -576,6 +579,7 @@ auto_calc_theora(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) { { if (info == NULL) { stream->calculate_data = malloc(sizeof(auto_calc_theora_info_t)); + if (stream->calculate_data == NULL) return -1; info = stream->calculate_data; } info->encountered_first_data_packet = 0; @@ -699,6 +703,8 @@ auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) { short_size = 1 << (op->packet[28] & 0xF); stream->calculate_data = malloc(sizeof(auto_calc_vorbis_info_t)); + if (stream->calculate_data == NULL) return -1; + info = (auto_calc_vorbis_info_t *)stream->calculate_data; info->nln_increments[3] = long_size >> 1; info->nln_increments[2] = 3 * (long_size >> 2) - (short_size >> 2); @@ -841,9 +847,11 @@ auto_calc_vorbis(ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) { /* * store mode size information in our info struct */ - stream->calculate_data = realloc(stream->calculate_data, + info = realloc(stream->calculate_data, sizeof(auto_calc_vorbis_info_t) + (size - 1) * sizeof(int)); - info = (auto_calc_vorbis_info_t *)(stream->calculate_data); + if (info == NULL) return -1; + + stream->calculate_data = info; i = -1; while ((1 << (++i)) < size); @@ -969,6 +977,8 @@ auto_calc_flac (ogg_int64_t now, oggz_stream_t *stream, ogg_packet *op) if (stream->calculate_data == NULL) { stream->calculate_data = malloc(sizeof(auto_calc_flac_info_t)); + if (stream->calculate_data == NULL) return -1; + info = (auto_calc_flac_info_t *)stream->calculate_data; info->previous_gp = 0; info->encountered_first_data_packet = 0; diff --git a/src/liboggz/oggz_comments.c b/src/liboggz/oggz_comments.c index d0df5cf..be6bd7a 100644 --- a/src/liboggz/oggz_comments.c +++ b/src/liboggz/oggz_comments.c @@ -57,6 +57,8 @@ oggz_strdup (const char * s) char * ret; if (s == NULL) return NULL; ret = oggz_malloc (strlen(s) + 1); + if (ret == NULL) return NULL; + return strcpy (ret, s); } @@ -89,11 +91,6 @@ oggz_index_len (const char * s, char c, int len) return NULL; } -#if 0 -static void comment_init(char **comments, int* length, char *vendor_string); -static void comment_add(char **comments, int* length, char *tag, char *val); -#endif - /* Comments will be stored in the Vorbis style. It is describled in the "Structure" section of @@ -130,47 +127,6 @@ The comment header is decoded as follows: buf[base+1]=(char)(((val)>>8)&0xff); \ buf[base+2]=(char)((val)&0xff); -#if 0 -static void -comment_init(char **comments, int* length, char *vendor_string) -{ - int vendor_length=strlen(vendor_string); - int user_comment_list_length=0; - int len=4+vendor_length+4; - char *p=(char*)oggz_malloc(len); - if(p==NULL){ - } - writeint(p, 0, vendor_length); - memcpy(p+4, vendor_string, vendor_length); - writeint(p, 4+vendor_length, user_comment_list_length); - *length=len; - *comments=p; -} - -static void -comment_add(char **comments, int* length, char *tag, char *val) -{ - char* p=*comments; - int vendor_length=readint(p, 0); - int user_comment_list_length=readint(p, 4+vendor_length); - int tag_len=(tag?strlen(tag):0); - int val_len=strlen(val); - int len=(*length)+4+tag_len+val_len; - - p=(char*)oggz_realloc(p, len); - if(p==NULL){ - } - - writeint(p, *length, tag_len+val_len); /* length of comment */ - if(tag) memcpy(p+*length+4, tag, tag_len); /* comment */ - memcpy(p+*length+4+tag_len, val, val_len); /* comment */ - writeint(p, 4+vendor_length, user_comment_list_length+1); - - *comments=p; - *length=len; -} -#endif - static int oggz_comment_validate_byname (const char * name, const char * value) { @@ -200,6 +156,8 @@ oggz_comment_new (const char * name, const char * value) if (!oggz_comment_validate_byname (name, value)) return NULL; comment = oggz_malloc (sizeof (OggzComment)); + if (comment == NULL) return NULL; + comment->name = oggz_strdup (name); comment->value = oggz_strdup (value); diff --git a/src/liboggz/oggz_dlist.c b/src/liboggz/oggz_dlist.c index 67bb7ce..5aa9b9a 100644 --- a/src/liboggz/oggz_dlist.c +++ b/src/liboggz/oggz_dlist.c @@ -49,11 +49,25 @@ struct _OggzDList { OggzDList * oggz_dlist_new (void) { - OggzDList *dlist = malloc(sizeof(OggzDList)); - - OggzDListElem * dummy_front = malloc(sizeof(OggzDListElem)); - OggzDListElem * dummy_back = malloc(sizeof(OggzDListElem)); + OggzDList *dlist; + OggzDListElem *dummy_front, *dummy_back; + dlist = malloc(sizeof(OggzDList)); + if (dlist == NULL) return NULL; + + dummy_front = malloc(sizeof(OggzDListElem)); + if (dummy_front == NULL) { + free (dlist); + return NULL; + } + + dummy_back = malloc(sizeof(OggzDListElem)); + if (dummy_back == NULL) { + free (dummy_front); + free (dlist); + return NULL; + } + dummy_front->next = dummy_back; dummy_front->prev = NULL; @@ -64,7 +78,6 @@ oggz_dlist_new (void) { dlist->tail = dummy_back; return dlist; - } void @@ -86,22 +99,34 @@ oggz_dlist_is_empty(OggzDList *dlist) { return (dlist->head->next == dlist->tail); } -void +int oggz_dlist_append(OggzDList *dlist, void *elem) { - OggzDListElem *new_elem = malloc(sizeof(OggzDListElem)); + OggzDListElem *new_elem; + + if (dlist == NULL) return -1; + + new_elem = malloc(sizeof(OggzDListElem)); + if (new_elem == NULL) return -1; new_elem->data = elem; new_elem->next = dlist->tail; new_elem->prev = dlist->tail->prev; new_elem->prev->next = new_elem; new_elem->next->prev = new_elem; + + return 0; } -void +int oggz_dlist_prepend(OggzDList *dlist, void *elem) { - OggzDListElem *new_elem = malloc(sizeof(OggzDListElem)); + OggzDListElem *new_elem; + + if (dlist == NULL) return -1; + + new_elem = malloc(sizeof(OggzDListElem)); + if (new_elem == NULL) return -1; new_elem->data = elem; new_elem->prev = dlist->head; @@ -109,6 +134,7 @@ oggz_dlist_prepend(OggzDList *dlist, void *elem) { new_elem->prev->next = new_elem; new_elem->next->prev = new_elem; + return 0; } void diff --git a/src/liboggz/oggz_dlist.h b/src/liboggz/oggz_dlist.h index 80de504..8913e73 100644 --- a/src/liboggz/oggz_dlist.h +++ b/src/liboggz/oggz_dlist.h @@ -49,10 +49,10 @@ oggz_dlist_delete(OggzDList *dlist); int oggz_dlist_is_empty(OggzDList *dlist); -void +int oggz_dlist_append(OggzDList *dlist, void *elem); -void +int oggz_dlist_prepend(OggzDList *dlist, void *elem); void diff --git a/src/liboggz/oggz_read.c b/src/liboggz/oggz_read.c index 80f6336..94c17e1 100644 --- a/src/liboggz/oggz_read.c +++ b/src/liboggz/oggz_read.c @@ -227,6 +227,8 @@ oggz_read_new_pbuffer_entry(OGGZ *oggz, ogg_packet *packet, OggzReader *reader) { OggzBufferedPacket *p = malloc(sizeof(OggzBufferedPacket)); + if (p == NULL) return NULL; + memcpy(&(p->packet), packet, sizeof(ogg_packet)); p->packet.packet = malloc(packet->bytes); memcpy(p->packet.packet, packet->packet, packet->bytes); diff --git a/src/liboggz/oggz_table.c b/src/liboggz/oggz_table.c index 0c37461..7a64c02 100644 --- a/src/liboggz/oggz_table.c +++ b/src/liboggz/oggz_table.c @@ -49,6 +49,8 @@ oggz_table_new (void) OggzTable * table; table = oggz_malloc (sizeof (OggzTable)); + if (table == NULL) return NULL; + table->keys = oggz_vector_new (); table->data = oggz_vector_new (); @@ -70,6 +72,8 @@ oggz_table_lookup (OggzTable * table, long key) { int i, size; + if (table == NULL) return NULL; + size = oggz_vector_size (table->keys); for (i = 0; i < size; i++) { if (oggz_vector_nth_l (table->keys, i) == key) { diff --git a/src/liboggz/oggz_vector.c b/src/liboggz/oggz_vector.c index 18c8600..8f43fed 100644 --- a/src/liboggz/oggz_vector.c +++ b/src/liboggz/oggz_vector.c @@ -78,6 +78,7 @@ oggz_vector_new (void) OggzVector * vector; vector = oggz_malloc (sizeof (OggzVector)); + if (vector == NULL) return NULL; vector->max_elements = 0; vector->nr_elements = 0; @@ -266,7 +267,6 @@ oggz_vector_grow (OggzVector * vector) if (new_elements == NULL) { vector->nr_elements--; - vector->data = NULL; return NULL; } @@ -359,8 +359,7 @@ oggz_vector_remove_nth (OggzVector * vector, int n) oggz_realloc (vector->data, (size_t)new_max_elements * sizeof (oggz_data_t)); - if (new_elements == NULL) - { + if (new_elements == NULL) { vector->data = NULL; return NULL; } @@ -405,52 +404,13 @@ void * oggz_vector_pop (OggzVector * vector) { void * data; -#if 0 - void * new_elements; - int new_max_elements; -#endif - if (!vector || vector->data == NULL) return NULL; + if (vector == NULL || vector->data == NULL) return NULL; data = vector->data[0].p; -#if 0 - vector->nr_elements--; - - if (vector->nr_elements == 0) { - oggz_vector_clear (vector); - } else { -#if 0 - memmove (vector->data, &vector->data[1], - vector->nr_elements * sizeof (void *)); -#else - { - int i; - for (i = 0; i < vector->nr_elements; i++) { - vector->data[i].p = vector->data[i+1].p; - } - } -#endif - if (vector->nr_elements < vector->max_elements/2) { - new_max_elements = vector->max_elements/2; - - new_elements = - oggz_realloc (vector->data, - (size_t)new_max_elements * sizeof (oggz_data_t)); - - if (new_elements != NULL) { - vector->max_elements = new_max_elements; - vector->data = new_elements; - } - } - - } -#else - oggz_vector_remove_nth (vector, 0); -#endif - return data; } diff --git a/src/liboggz/oggz_write.c b/src/liboggz/oggz_write.c index 0b0fab5..21d1d14 100644 --- a/src/liboggz/oggz_write.c +++ b/src/liboggz/oggz_write.c @@ -91,6 +91,7 @@ oggz_write_init (OGGZ * oggz) writer->next_zpacket = NULL; writer->packet_queue = oggz_vector_new (); + if (writer->packet_queue == NULL) return NULL; #ifdef ZPACKET_CMP /* XXX: comparison function should only kick in when a metric is set */ @@ -205,7 +206,7 @@ oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush, oggz_stream_t * stream; oggz_writer_packet_t * packet; ogg_packet * new_op; - unsigned char * new_buf; + unsigned char * new_buf = NULL; int b_o_s, e_o_s, bos_auto; int strict, prefix, suffix; @@ -306,12 +307,18 @@ oggz_write_feed (OGGZ * oggz, ogg_packet * op, long serialno, int flush, /* Now set up the packet and add it to the queue */ if (guard == NULL) { new_buf = oggz_malloc ((size_t)op->bytes); + if (new_buf == NULL) return OGGZ_ERR_OUT_OF_MEMORY; + memcpy (new_buf, op->packet, (size_t)op->bytes); } else { new_buf = op->packet; } packet = oggz_malloc (sizeof (oggz_writer_packet_t)); + if (packet == NULL) { + if (guard == NULL && new_buf != NULL) free (new_buf); + return OGGZ_ERR_OUT_OF_MEMORY; + } new_op = &packet->op; new_op->packet = new_buf; -- GitLab