X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2FlibFLAC%2Fmetadata_iterators.c;h=d2a229a1ebc9e689b995d8cff6b19b990a719367;hb=f25b2602dce3c09098e3092bfad983e3ec7fdb4f;hp=5449bee7a2e6bf1b40b617a2f1c3542c6475e108;hpb=7d273b4bdb638b3816562b7599875910e2c47271;p=platform%2Fupstream%2Fflac.git diff --git a/src/libFLAC/metadata_iterators.c b/src/libFLAC/metadata_iterators.c index 5449bee..d2a229a 100644 --- a/src/libFLAC/metadata_iterators.c +++ b/src/libFLAC/metadata_iterators.c @@ -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 @@ -38,35 +38,20 @@ #include #include -#if defined _MSC_VER || defined __MINGW32__ -#include /* for utime() */ -#include /* for chmod() */ -#include /* for off_t */ -#if _MSC_VER <= 1200 /* @@@ [2G limit] */ -#define fseeko fseek -#define ftello ftell -#endif -#else -#include /* some flavors of BSD (like OS X) require this to get time_t */ -#include /* for utime() */ -#include /* for chown(), unlink() */ -#endif #include /* for stat(), maybe chmod() */ #include "private/metadata.h" #include "FLAC/assert.h" #include "FLAC/stream_decoder.h" +#include "share/alloc.h" +#include "share/compat.h" +#include "share/macros.h" +#include "private/macros.h" +#include "private/memory.h" -#ifdef max -#undef max -#endif -#define max(a,b) ((a)>(b)?(a):(b)) -#ifdef min -#undef min -#endif -#define min(a,b) ((a)<(b)?(a):(b)) - +/* Alias the first (in share/alloc.h) to the second (in src/libFLAC/memory.c). */ +#define safe_malloc_mul_2op_ safe_malloc_mul_2op_p /**************************************************************************** * @@ -120,10 +105,10 @@ static unsigned seek_to_first_metadata_block_cb_(FLAC__IOHandle handle, FLAC__IO static unsigned seek_to_first_metadata_block_(FILE *f); static FLAC__bool simple_iterator_copy_file_prefix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, FLAC__bool append); -static FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, int fixup_is_last_code, off_t fixup_is_last_flag_offset, FLAC__bool backup); +static FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, int fixup_is_last_code, FLAC__off_t fixup_is_last_flag_offset, FLAC__bool backup); -static FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status); -static FLAC__bool copy_n_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status); +static FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, FLAC__off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status); +static FLAC__bool copy_n_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, FLAC__off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status); static FLAC__bool copy_remaining_bytes_from_file_(FILE *file, FILE *tempfile, FLAC__Metadata_SimpleIteratorStatus *status); static FLAC__bool copy_remaining_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Eof eof_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, FLAC__Metadata_SimpleIteratorStatus *status); @@ -344,8 +329,8 @@ struct FLAC__Metadata_SimpleIterator { FLAC__bool has_stats; FLAC__bool is_writable; FLAC__Metadata_SimpleIteratorStatus status; - off_t offset[SIMPLE_ITERATOR_MAX_PUSH_DEPTH]; - off_t first_offset; /* this is the offset to the STREAMINFO block */ + FLAC__off_t offset[SIMPLE_ITERATOR_MAX_PUSH_DEPTH]; + FLAC__off_t first_offset; /* this is the offset to the STREAMINFO block */ unsigned depth; /* this is the metadata block header of the current block we are pointing to: */ FLAC__bool is_last; @@ -370,9 +355,9 @@ FLAC_API const char * const FLAC__Metadata_SimpleIteratorStatusString[] = { }; -FLAC_API FLAC__Metadata_SimpleIterator *FLAC__metadata_simple_iterator_new() +FLAC_API FLAC__Metadata_SimpleIterator *FLAC__metadata_simple_iterator_new(void) { - FLAC__Metadata_SimpleIterator *iterator = (FLAC__Metadata_SimpleIterator*)calloc(1, sizeof(FLAC__Metadata_SimpleIterator)); + FLAC__Metadata_SimpleIterator *iterator = calloc(1, sizeof(FLAC__Metadata_SimpleIterator)); if(0 != iterator) { iterator->file = 0; @@ -541,7 +526,7 @@ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_next(FLAC__Metadata_SimpleIte FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator) { - off_t this_offset; + FLAC__off_t this_offset; FLAC__ASSERT(0 != iterator); FLAC__ASSERT(0 != iterator->file); @@ -558,7 +543,7 @@ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIte return false; /* we ignore any error from ftello() and catch it in fseeko() */ - while(ftello(iterator->file) + (off_t)iterator->length < iterator->offset[iterator->depth]) { + while(ftello(iterator->file) + (FLAC__off_t)iterator->length < iterator->offset[iterator->depth]) { if(0 != fseeko(iterator->file, iterator->length, SEEK_CUR)) { iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; return false; @@ -573,6 +558,24 @@ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIte return true; } +/*@@@@add to tests*/ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_last(const FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + + return iterator->is_last; +} + +/*@@@@add to tests*/ +FLAC_API off_t FLAC__metadata_simple_iterator_get_block_offset(const FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + + return iterator->offset[iterator->depth]; +} + FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator) { FLAC__ASSERT(0 != iterator); @@ -581,6 +584,43 @@ FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const return iterator->type; } +/*@@@@add to tests*/ +FLAC_API unsigned FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator) +{ + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + + return iterator->length; +} + +/*@@@@add to tests*/ +FLAC_API FLAC__bool FLAC__metadata_simple_iterator_get_application_id(FLAC__Metadata_SimpleIterator *iterator, FLAC__byte *id) +{ + const unsigned id_bytes = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8; + + FLAC__ASSERT(0 != iterator); + FLAC__ASSERT(0 != iterator->file); + FLAC__ASSERT(0 != id); + + if(iterator->type != FLAC__METADATA_TYPE_APPLICATION) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT; + return false; + } + + if(fread(id, 1, id_bytes, iterator->file) != id_bytes) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + return false; + } + + /* back up */ + if(0 != fseeko(iterator->file, -((int)id_bytes), SEEK_CUR)) { + iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; + return false; + } + + return true; +} + FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator) { FLAC__StreamMetadata *block = FLAC__metadata_object_new(iterator->type); @@ -612,7 +652,7 @@ FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Me FLAC_API FLAC__bool FLAC__metadata_simple_iterator_set_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding) { - FLAC__ASSERT_DECLARATION(off_t debug_target_offset = iterator->offset[iterator->depth];) + FLAC__ASSERT_DECLARATION(FLAC__off_t debug_target_offset = iterator->offset[iterator->depth];) FLAC__bool ret; FLAC__ASSERT(0 != iterator); @@ -639,13 +679,13 @@ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_set_block(FLAC__Metadata_Simp if(use_padding && iterator->length >= FLAC__STREAM_METADATA_HEADER_LENGTH + block->length) { ret = write_metadata_block_stationary_with_padding_(iterator, block, iterator->length - FLAC__STREAM_METADATA_HEADER_LENGTH - block->length, block->is_last); FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); - FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); + FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); return ret; } else { ret = rewrite_whole_file_(iterator, block, /*append=*/false); FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); - FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); + FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); return ret; } } @@ -688,21 +728,21 @@ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_set_block(FLAC__Metadata_Simp if(padding_leftover == 0) { ret = write_metadata_block_stationary_(iterator, block); FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); - FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); + FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); return ret; } else { FLAC__ASSERT(padding_leftover >= FLAC__STREAM_METADATA_HEADER_LENGTH); ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover - FLAC__STREAM_METADATA_HEADER_LENGTH, padding_is_last); FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); - FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); + FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); return ret; } } else { ret = rewrite_whole_file_(iterator, block, /*append=*/false); FLAC__ASSERT(!ret || iterator->offset[iterator->depth] == debug_target_offset); - FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); + FLAC__ASSERT(!ret || ftello(iterator->file) == debug_target_offset + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); return ret; } } @@ -713,7 +753,7 @@ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_insert_block_after(FLAC__Meta unsigned padding_leftover = 0; FLAC__bool padding_is_last = false; - FLAC__ASSERT_DECLARATION(off_t debug_target_offset = iterator->offset[iterator->depth] + FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length;) + FLAC__ASSERT_DECLARATION(FLAC__off_t debug_target_offset = iterator->offset[iterator->depth] + FLAC__STREAM_METADATA_HEADER_LENGTH + iterator->length;) FLAC__bool ret; FLAC__ASSERT(0 != iterator); @@ -768,28 +808,28 @@ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_insert_block_after(FLAC__Meta if(padding_leftover == 0) { ret = write_metadata_block_stationary_(iterator, block); FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset); - FLAC__ASSERT(ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); + FLAC__ASSERT(ftello(iterator->file) == debug_target_offset + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); return ret; } else { FLAC__ASSERT(padding_leftover >= FLAC__STREAM_METADATA_HEADER_LENGTH); ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover - FLAC__STREAM_METADATA_HEADER_LENGTH, padding_is_last); FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset); - FLAC__ASSERT(ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); + FLAC__ASSERT(ftello(iterator->file) == debug_target_offset + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); return ret; } } else { ret = rewrite_whole_file_(iterator, block, /*append=*/true); FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset); - FLAC__ASSERT(ftello(iterator->file) == debug_target_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); + FLAC__ASSERT(ftello(iterator->file) == debug_target_offset + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH); return ret; } } FLAC_API FLAC__bool FLAC__metadata_simple_iterator_delete_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool use_padding) { - FLAC__ASSERT_DECLARATION(off_t debug_target_offset = iterator->offset[iterator->depth];) + FLAC__ASSERT_DECLARATION(FLAC__off_t debug_target_offset = iterator->offset[iterator->depth];) FLAC__bool ret; if(iterator->type == FLAC__METADATA_TYPE_STREAMINFO) { @@ -811,14 +851,14 @@ FLAC_API FLAC__bool FLAC__metadata_simple_iterator_delete_block(FLAC__Metadata_S FLAC__metadata_object_delete(padding); if(!FLAC__metadata_simple_iterator_prev(iterator)) return false; - FLAC__ASSERT(iterator->offset[iterator->depth] + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length == debug_target_offset); - FLAC__ASSERT(ftello(iterator->file) + (off_t)iterator->length == debug_target_offset); + FLAC__ASSERT(iterator->offset[iterator->depth] + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (FLAC__off_t)iterator->length == debug_target_offset); + FLAC__ASSERT(ftello(iterator->file) + (FLAC__off_t)iterator->length == debug_target_offset); return true; } else { ret = rewrite_whole_file_(iterator, 0, /*append=*/false); - FLAC__ASSERT(iterator->offset[iterator->depth] + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length == debug_target_offset); - FLAC__ASSERT(ftello(iterator->file) + (off_t)iterator->length == debug_target_offset); + FLAC__ASSERT(iterator->offset[iterator->depth] + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (FLAC__off_t)iterator->length == debug_target_offset); + FLAC__ASSERT(ftello(iterator->file) + (FLAC__off_t)iterator->length == debug_target_offset); return ret; } } @@ -844,13 +884,13 @@ struct FLAC__Metadata_Chain { FLAC__Metadata_Node *tail; unsigned nodes; FLAC__Metadata_ChainStatus status; - off_t first_offset, last_offset; + FLAC__off_t first_offset, last_offset; /* * This is the length of the chain initially read from the FLAC file. * it is used to compare against the current length to decide whether * or not the whole file has to be rewritten. */ - off_t initial_length; + FLAC__off_t initial_length; /* @@@ hacky, these are currently only needed by ogg reader */ FLAC__IOHandle handle; FLAC__IOCallback_Read read_cb; @@ -881,9 +921,9 @@ FLAC_API const char * const FLAC__Metadata_ChainStatusString[] = { }; -static FLAC__Metadata_Node *node_new_() +static FLAC__Metadata_Node *node_new_(void) { - return (FLAC__Metadata_Node*)calloc(1, sizeof(FLAC__Metadata_Node)); + return calloc(1, sizeof(FLAC__Metadata_Node)); } static void node_delete_(FLAC__Metadata_Node *node) @@ -974,10 +1014,10 @@ static void chain_delete_node_(FLAC__Metadata_Chain *chain, FLAC__Metadata_Node node_delete_(node); } -static off_t chain_calculate_length_(FLAC__Metadata_Chain *chain) +static FLAC__off_t chain_calculate_length_(FLAC__Metadata_Chain *chain) { const FLAC__Metadata_Node *node; - off_t length = 0; + FLAC__off_t length = 0; for(node = chain->head; node; node = node->next) length += (FLAC__STREAM_METADATA_HEADER_LENGTH + node->data->length); return length; @@ -1056,20 +1096,20 @@ static FLAC__bool chain_merge_adjacent_padding_(FLAC__Metadata_Chain *chain, FLA /* WATCHOUT: Make sure to also update the logic in * FLAC__metadata_chain_check_if_tempfile_needed() if the logic here changes. */ -static off_t chain_prepare_for_write_(FLAC__Metadata_Chain *chain, FLAC__bool use_padding) +static FLAC__off_t chain_prepare_for_write_(FLAC__Metadata_Chain *chain, FLAC__bool use_padding) { - off_t current_length = chain_calculate_length_(chain); + FLAC__off_t current_length = chain_calculate_length_(chain); if(use_padding) { /* if the metadata shrank and the last block is padding, we just extend the last padding block */ if(current_length < chain->initial_length && chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) { - const off_t delta = chain->initial_length - current_length; + const FLAC__off_t delta = chain->initial_length - current_length; chain->tail->data->length += delta; current_length += delta; FLAC__ASSERT(current_length == chain->initial_length); } /* if the metadata shrank more than 4 bytes then there's room to add another padding block */ - else if(current_length + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH <= chain->initial_length) { + else if(current_length + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH <= chain->initial_length) { FLAC__StreamMetadata *padding; FLAC__Metadata_Node *node; if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING))) { @@ -1089,16 +1129,16 @@ static off_t chain_prepare_for_write_(FLAC__Metadata_Chain *chain, FLAC__bool us } /* if the metadata grew but the last block is padding, try cutting the padding to restore the original length so we don't have to rewrite the whole file */ else if(current_length > chain->initial_length) { - const off_t delta = current_length - chain->initial_length; + const FLAC__off_t delta = current_length - chain->initial_length; if(chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) { /* if the delta is exactly the size of the last padding block, remove the padding block */ - if((off_t)chain->tail->data->length + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH == delta) { + if((FLAC__off_t)chain->tail->data->length + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH == delta) { chain_delete_node_(chain, chain->tail); current_length = chain_calculate_length_(chain); FLAC__ASSERT(current_length == chain->initial_length); } /* if there is at least 'delta' bytes of padding, trim the padding down */ - else if((off_t)chain->tail->data->length >= delta) { + else if((FLAC__off_t)chain->tail->data->length >= delta) { chain->tail->data->length -= delta; current_length -= delta; FLAC__ASSERT(current_length == chain->initial_length); @@ -1141,7 +1181,7 @@ static FLAC__bool chain_read_cb_(FLAC__Metadata_Chain *chain, FLAC__IOHandle han chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR; return false; } - chain->first_offset = (off_t)pos; + chain->first_offset = (FLAC__off_t)pos; } { @@ -1157,6 +1197,7 @@ static FLAC__bool chain_read_cb_(FLAC__Metadata_Chain *chain, FLAC__IOHandle han } if(!read_metadata_block_header_cb_(handle, read_cb, &is_last, &type, &length)) { + node_delete_(node); chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR; return false; } @@ -1186,7 +1227,7 @@ static FLAC__bool chain_read_cb_(FLAC__Metadata_Chain *chain, FLAC__IOHandle han chain->status = FLAC__METADATA_CHAIN_STATUS_READ_ERROR; return false; } - chain->last_offset = (off_t)pos; + chain->last_offset = (FLAC__off_t)pos; } chain->initial_length = chain_calculate_length_(chain); @@ -1194,7 +1235,7 @@ static FLAC__bool chain_read_cb_(FLAC__Metadata_Chain *chain, FLAC__IOHandle han return true; } -FLAC__StreamDecoderReadStatus chain_read_ogg_read_cb_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) +static FLAC__StreamDecoderReadStatus chain_read_ogg_read_cb_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) { FLAC__Metadata_Chain *chain = (FLAC__Metadata_Chain*)client_data; (void)decoder; @@ -1218,10 +1259,11 @@ static FLAC__StreamDecoderWriteStatus chain_read_ogg_write_cb_(const FLAC__Strea static void chain_read_ogg_metadata_cb_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) { FLAC__Metadata_Chain *chain = (FLAC__Metadata_Chain*)client_data; + FLAC__Metadata_Node *node; (void)decoder; - FLAC__Metadata_Node *node = node_new_(); + node = node_new_(); if(0 == node) { chain->status = FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR; return; @@ -1350,38 +1392,34 @@ static FLAC__bool chain_rewrite_file_(FLAC__Metadata_Chain *chain, const char *t } if(!open_tempfile_(chain->filename, tempfile_path_prefix, &tempfile, &tempfilename, &status)) { chain->status = get_equivalent_status_(status); - cleanup_tempfile_(&tempfile, &tempfilename); - return false; + goto err; } if(!copy_n_bytes_from_file_(f, tempfile, chain->first_offset, &status)) { chain->status = get_equivalent_status_(status); - cleanup_tempfile_(&tempfile, &tempfilename); - return false; + goto err; } /* write the metadata */ for(node = chain->head; node; node = node->next) { if(!write_metadata_block_header_(tempfile, &status, node->data)) { chain->status = get_equivalent_status_(status); - return false; + goto err; } if(!write_metadata_block_data_(tempfile, &status, node->data)) { chain->status = get_equivalent_status_(status); - return false; + goto err; } } /*FLAC__ASSERT(fflush(), ftello() == chain->last_offset);*/ /* copy the file postfix (everything after the metadata) */ if(0 != fseeko(f, chain->last_offset, SEEK_SET)) { - cleanup_tempfile_(&tempfile, &tempfilename); chain->status = FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR; - return false; + goto err; } if(!copy_remaining_bytes_from_file_(f, tempfile, &status)) { - cleanup_tempfile_(&tempfile, &tempfilename); chain->status = get_equivalent_status_(status); - return false; + goto err; } /* move the tempfile on top of the original */ @@ -1390,6 +1428,11 @@ static FLAC__bool chain_rewrite_file_(FLAC__Metadata_Chain *chain, const char *t return false; return true; + +err: + (void)fclose(f); + cleanup_tempfile_(&tempfile, &tempfilename); + return false; } /* assumes 'handle' is already at beginning of file */ @@ -1434,9 +1477,9 @@ static FLAC__bool chain_rewrite_file_cb_(FLAC__Metadata_Chain *chain, FLAC__IOHa return true; } -FLAC_API FLAC__Metadata_Chain *FLAC__metadata_chain_new() +FLAC_API FLAC__Metadata_Chain *FLAC__metadata_chain_new(void) { - FLAC__Metadata_Chain *chain = (FLAC__Metadata_Chain*)calloc(1, sizeof(FLAC__Metadata_Chain)); + FLAC__Metadata_Chain *chain = calloc(1, sizeof(FLAC__Metadata_Chain)); if(0 != chain) chain_init_(chain); @@ -1502,6 +1545,7 @@ FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const return chain_read_(chain, filename, /*is_ogg=*/false); } +/*@@@@add to tests*/ FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg(FLAC__Metadata_Chain *chain, const char *filename) { return chain_read_(chain, filename, /*is_ogg=*/true); @@ -1542,6 +1586,7 @@ FLAC_API FLAC__bool FLAC__metadata_chain_read_with_callbacks(FLAC__Metadata_Chai return chain_read_with_callbacks_(chain, handle, callbacks, /*is_ogg=*/false); } +/*@@@@add to tests*/ FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks) { return chain_read_with_callbacks_(chain, handle, callbacks, /*is_ogg=*/true); @@ -1553,7 +1598,7 @@ FLAC_API FLAC__bool FLAC__metadata_chain_check_if_tempfile_needed(FLAC__Metadata * but doesn't actually alter the chain. Make sure to update the logic * here if chain_prepare_for_write_() changes. */ - const off_t current_length = chain_calculate_length_(chain); + const FLAC__off_t current_length = chain_calculate_length_(chain); FLAC__ASSERT(0 != chain); @@ -1562,17 +1607,17 @@ FLAC_API FLAC__bool FLAC__metadata_chain_check_if_tempfile_needed(FLAC__Metadata if(current_length < chain->initial_length && chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) return false; /* if the metadata shrank more than 4 bytes then there's room to add another padding block */ - else if(current_length + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH <= chain->initial_length) + else if(current_length + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH <= chain->initial_length) return false; /* if the metadata grew but the last block is padding, try cutting the padding to restore the original length so we don't have to rewrite the whole file */ else if(current_length > chain->initial_length) { - const off_t delta = current_length - chain->initial_length; + const FLAC__off_t delta = current_length - chain->initial_length; if(chain->tail->data->type == FLAC__METADATA_TYPE_PADDING) { /* if the delta is exactly the size of the last padding block, remove the padding block */ - if((off_t)chain->tail->data->length + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH == delta) + if((FLAC__off_t)chain->tail->data->length + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH == delta) return false; /* if there is at least 'delta' bytes of padding, trim the padding down */ - else if((off_t)chain->tail->data->length >= delta) + else if((FLAC__off_t)chain->tail->data->length >= delta) return false; } } @@ -1585,7 +1630,7 @@ FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC { struct stat stats; const char *tempfile_path_prefix = 0; - off_t current_length; + FLAC__off_t current_length; FLAC__ASSERT(0 != chain); @@ -1634,7 +1679,7 @@ FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks) { - off_t current_length; + FLAC__off_t current_length; FLAC__ASSERT(0 != chain); @@ -1671,7 +1716,7 @@ FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks(FLAC__Metadata_Cha FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks_and_tempfile(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks, FLAC__IOHandle temp_handle, FLAC__IOCallbacks temp_callbacks) { - off_t current_length; + FLAC__off_t current_length; FLAC__ASSERT(0 != chain); @@ -1767,9 +1812,9 @@ FLAC_API void FLAC__metadata_chain_sort_padding(FLAC__Metadata_Chain *chain) } -FLAC_API FLAC__Metadata_Iterator *FLAC__metadata_iterator_new() +FLAC_API FLAC__Metadata_Iterator *FLAC__metadata_iterator_new(void) { - FLAC__Metadata_Iterator *iterator = (FLAC__Metadata_Iterator*)calloc(1, sizeof(FLAC__Metadata_Iterator)); + FLAC__Metadata_Iterator *iterator = calloc(1, sizeof(FLAC__Metadata_Iterator)); /* calloc() implies: iterator->current = 0; @@ -2096,13 +2141,16 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_application_cb_(FLA 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) { block->data = 0; } else { - if(0 == (block->data = (FLAC__byte*)malloc(block_length))) + if(0 == (block->data = malloc(block_length))) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; if(read_cb(block->data, 1, block_length, handle) != block_length) @@ -2123,7 +2171,7 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_seektable_cb_(FLAC_ 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 = safe_malloc_mul_2op_p(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++) { @@ -2156,7 +2204,7 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_entr entry->entry = 0; } else { - if(0 == (entry->entry = (FLAC__byte*)malloc(entry->length+1))) + if(0 == (entry->entry = 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) @@ -2187,7 +2235,7 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_cb_( if(block->num_comments == 0) { block->comments = 0; } - else if(0 == (block->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)calloc(block->num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) + else if(0 == (block->comments = calloc(block->num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; for(i = 0; i < block->num_comments; i++) { @@ -2242,7 +2290,7 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_track_cb_( if(track->num_indices == 0) { track->indices = 0; } - else if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)calloc(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) + else if(0 == (track->indices = calloc(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; for(i = 0; i < track->num_indices; i++) { @@ -2302,7 +2350,7 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_cb_(FLAC__ if(block->num_tracks == 0) { block->tracks = 0; } - else if(0 == (block->tracks = (FLAC__StreamMetadata_CueSheet_Track*)calloc(block->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) + else if(0 == (block->tracks = calloc(block->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; for(i = 0; i < block->num_tracks; i++) { @@ -2313,7 +2361,7 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_cb_(FLAC__ return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; } -FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_picture_cstring_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__byte **data, FLAC__uint32 *length, FLAC__uint32 length_len) +static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_picture_cstring_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__byte **data, FLAC__uint32 *length, FLAC__uint32 length_len) { FLAC__byte buffer[sizeof(FLAC__uint32)]; @@ -2331,7 +2379,7 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_picture_cstring_cb_ if(0 != *data) free(*data); - if(0 == (*data = (FLAC__byte*)malloc(*length+1))) + if(0 == (*data = safe_malloc_add_2op_(*length, /*+*/1))) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; if(*length > 0) { @@ -2405,7 +2453,7 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_unknown_cb_(FLAC__I block->data = 0; } else { - if(0 == (block->data = (FLAC__byte*)malloc(block_length))) + if(0 == (block->data = malloc(block_length))) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; if(read_cb(block->data, 1, block_length, handle) != block_length) @@ -2569,7 +2617,7 @@ FLAC__bool write_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, F const unsigned num_comments_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN / 8; FLAC__byte buffer[4]; /* magic number is asserted below */ - FLAC__ASSERT(max(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN, FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN) / 8 == sizeof(buffer)); + FLAC__ASSERT(flac_max(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN, FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN) / 8 == sizeof(buffer)); pack_uint32_little_endian_(block->vendor_string.length, buffer, entry_length_len); if(write_cb(buffer, 1, entry_length_len, handle) != entry_length_len) @@ -2834,10 +2882,10 @@ FLAC__bool write_metadata_block_stationary_with_padding_(FLAC__Metadata_SimpleIt FLAC__bool rewrite_whole_file_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool append) { - FILE *tempfile; - char *tempfilename; + FILE *tempfile = NULL; + char *tempfilename = NULL; int fixup_is_last_code = 0; /* 0 => no need to change any is_last flags */ - off_t fixup_is_last_flag_offset = -1; + FLAC__off_t fixup_is_last_flag_offset = -1; FLAC__ASSERT(0 != block || append == false); @@ -2965,7 +3013,7 @@ unsigned seek_to_first_metadata_block_(FILE *f) FLAC__bool simple_iterator_copy_file_prefix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, FLAC__bool append) { - const off_t offset_end = append? iterator->offset[iterator->depth] + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length : iterator->offset[iterator->depth]; + const FLAC__off_t offset_end = append? iterator->offset[iterator->depth] + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (FLAC__off_t)iterator->length : iterator->offset[iterator->depth]; if(0 != fseeko(iterator->file, 0, SEEK_SET)) { iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; @@ -2983,12 +3031,12 @@ FLAC__bool simple_iterator_copy_file_prefix_(FLAC__Metadata_SimpleIterator *iter return true; } -FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, int fixup_is_last_code, off_t fixup_is_last_flag_offset, FLAC__bool backup) +FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, int fixup_is_last_code, FLAC__off_t fixup_is_last_flag_offset, FLAC__bool backup) { - off_t save_offset = iterator->offset[iterator->depth]; + FLAC__off_t save_offset = iterator->offset[iterator->depth]; FLAC__ASSERT(0 != *tempfile); - if(0 != fseeko(iterator->file, save_offset + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length, SEEK_SET)) { + if(0 != fseeko(iterator->file, save_offset + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (FLAC__off_t)iterator->length, SEEK_SET)) { cleanup_tempfile_(tempfile, tempfilename); iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; return false; @@ -3048,7 +3096,7 @@ FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *ite if(!simple_iterator_prime_input_(iterator, !iterator->is_writable)) return false; if(backup) { - while(iterator->offset[iterator->depth] + (off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (off_t)iterator->length < save_offset) + while(iterator->offset[iterator->depth] + (FLAC__off_t)FLAC__STREAM_METADATA_HEADER_LENGTH + (FLAC__off_t)iterator->length < save_offset) if(!FLAC__metadata_simple_iterator_next(iterator)) return false; return true; @@ -3062,14 +3110,14 @@ FLAC__bool simple_iterator_copy_file_postfix_(FLAC__Metadata_SimpleIterator *ite } } -FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status) +FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, FLAC__off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status) { FLAC__byte buffer[8192]; size_t n; FLAC__ASSERT(bytes >= 0); while(bytes > 0) { - n = min(sizeof(buffer), (size_t)bytes); + n = flac_min(sizeof(buffer), (size_t)bytes); if(fread(buffer, 1, n, file) != n) { *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; return false; @@ -3084,14 +3132,14 @@ FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, off_t bytes, FLAC return true; } -FLAC__bool copy_n_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status) +FLAC__bool copy_n_bytes_from_file_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOHandle temp_handle, FLAC__IOCallback_Write temp_write_cb, FLAC__off_t bytes, FLAC__Metadata_SimpleIteratorStatus *status) { FLAC__byte buffer[8192]; size_t n; FLAC__ASSERT(bytes >= 0); while(bytes > 0) { - n = min(sizeof(buffer), (size_t)bytes); + n = flac_min(sizeof(buffer), (size_t)bytes); if(read_cb(buffer, 1, n, handle) != n) { *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; return false; @@ -3150,7 +3198,7 @@ FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix { 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 = safe_malloc_add_3op_(strlen(filename), /*+*/strlen(tempfile_suffix), /*+*/1))) { *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; return false; } @@ -3164,7 +3212,7 @@ FLAC__bool open_tempfile_(const char *filename, const char *tempfile_path_prefix else p++; - if(0 == (*tempfilename = (char*)malloc(strlen(tempfile_path_prefix) + 1 + strlen(p) + strlen(tempfile_suffix) + 1))) { + if(0 == (*tempfilename = 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; } @@ -3194,7 +3242,7 @@ FLAC__bool transport_tempfile_(const char *filename, FILE **tempfile, char **tem (void)fclose(*tempfile); *tempfile = 0; -#if defined _MSC_VER || defined __MINGW32__ || defined __EMX__ +#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ || defined __EMX__ /* on some flavors of windows, rename() will fail if the destination already exists */ if(unlink(filename) < 0) { cleanup_tempfile_(tempfile, tempfilename); @@ -3247,15 +3295,15 @@ void set_file_stats_(const char *filename, struct stat *stats) srctime.modtime = stats->st_mtime; (void)chmod(filename, stats->st_mode); (void)utime(filename, &srctime); -#if !defined _MSC_VER && !defined __MINGW32__ && !defined __EMX__ - (void)chown(filename, stats->st_uid, -1); - (void)chown(filename, -1, stats->st_gid); +#if !defined _MSC_VER && !defined __BORLANDC__ && !defined __MINGW32__ + FLAC_CHECK_RETURN(chown(filename, stats->st_uid, -1)); + FLAC_CHECK_RETURN(chown(filename, -1, stats->st_gid)); #endif } int fseek_wrapper_(FLAC__IOHandle handle, FLAC__int64 offset, int whence) { - return fseeko((FILE*)handle, (off_t)offset, whence); + return fseeko((FILE*)handle, (FLAC__off_t)offset, whence); } FLAC__int64 ftell_wrapper_(FLAC__IOHandle handle)