From: Josh Coalson Date: Fri, 10 Jan 2003 05:37:13 +0000 (+0000) Subject: big fix to allow codec and metadata interface to handle unknown metadata block types... X-Git-Tag: 1.2.0~1167 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d060947ce9c8aafa194da5625e4ab9b58530820d;p=platform%2Fupstream%2Fflac.git big fix to allow codec and metadata interface to handle unknown metadata block types correctly --- diff --git a/src/libFLAC/metadata_iterators.c b/src/libFLAC/metadata_iterators.c index e92ebb4..70d56b7 100644 --- a/src/libFLAC/metadata_iterators.c +++ b/src/libFLAC/metadata_iterators.c @@ -73,6 +73,7 @@ static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comme static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_(FILE *file, FLAC__StreamMetadata_VorbisComment *block); static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_track_(FILE *file, FLAC__StreamMetadata_CueSheet_Track *track); static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_(FILE *file, FLAC__StreamMetadata_CueSheet *block); +static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_unknown_(FILE *file, FLAC__StreamMetadata_Unknown *block, unsigned block_length); static FLAC__bool write_metadata_block_header_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block); static FLAC__bool write_metadata_block_data_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block); @@ -82,6 +83,7 @@ static FLAC__Metadata_SimpleIteratorStatus write_metadata_block_data_application static FLAC__Metadata_SimpleIteratorStatus write_metadata_block_data_seektable_(FILE *file, const FLAC__StreamMetadata_SeekTable *block); static FLAC__Metadata_SimpleIteratorStatus write_metadata_block_data_vorbis_comment_(FILE *file, const FLAC__StreamMetadata_VorbisComment *block); static FLAC__Metadata_SimpleIteratorStatus write_metadata_block_data_cuesheet_(FILE *file, const FLAC__StreamMetadata_CueSheet *block); +static FLAC__Metadata_SimpleIteratorStatus write_metadata_block_data_unknown_(FILE *file, const FLAC__StreamMetadata_Unknown *block, unsigned block_length); static FLAC__bool write_metadata_block_stationary_(FLAC__Metadata_SimpleIterator *iterator, const FLAC__StreamMetadata *block); static FLAC__bool write_metadata_block_stationary_with_padding_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, unsigned padding_length, FLAC__bool padding_is_last); static FLAC__bool rewrite_whole_file_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool append); @@ -1350,11 +1352,10 @@ FLAC__bool read_metadata_block_header_(FLAC__Metadata_SimpleIterator *iterator) iterator->type = (FLAC__MetadataType)(raw_header[0] & 0x7f); iterator->length = unpack_uint32_(raw_header + 1, 3); - /* do some checking */ - if(iterator->type >= FLAC__METADATA_TYPE_UNDEFINED) { - iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA; - return false; - } + /* Note that we don't check: + * if(iterator->type >= FLAC__METADATA_TYPE_UNDEFINED) + * we just will read in an opaque block + */ return true; } @@ -1384,8 +1385,8 @@ FLAC__bool read_metadata_block_data_(FLAC__Metadata_SimpleIterator *iterator, FL iterator->status = read_metadata_block_data_cuesheet_(iterator->file, &block->data.cue_sheet); break; default: - FLAC__ASSERT(0); - iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR; + iterator->status = read_metadata_block_data_unknown_(iterator->file, &block->data.unknown, block->length); + break; } return (iterator->status == FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK); @@ -1662,6 +1663,24 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_(FILE *fil return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; } +FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_unknown_(FILE *file, FLAC__StreamMetadata_Unknown *block, unsigned block_length) +{ + FLAC__ASSERT(0 != file); + + if(block_length == 0) { + block->data = 0; + } + else { + if(0 == (block->data = (FLAC__byte*)malloc(block_length))) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; + + if(fread(block->data, 1, block_length, file) != block_length) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; + } + + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; +} + FLAC__bool write_metadata_block_header_(FILE *file, FLAC__Metadata_SimpleIteratorStatus *status, const FLAC__StreamMetadata *block) { FLAC__byte buffer[FLAC__STREAM_METADATA_HEADER_LENGTH]; @@ -1706,8 +1725,8 @@ FLAC__bool write_metadata_block_data_(FILE *file, FLAC__Metadata_SimpleIteratorS *status = write_metadata_block_data_cuesheet_(file, &block->data.cue_sheet); break; default: - FLAC__ASSERT(0); - *status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR; + *status = write_metadata_block_data_unknown_(file, &block->data.unknown, block->length); + break; } return (*status == FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK); } @@ -1927,6 +1946,16 @@ FLAC__Metadata_SimpleIteratorStatus write_metadata_block_data_cuesheet_(FILE *fi return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; } +FLAC__Metadata_SimpleIteratorStatus write_metadata_block_data_unknown_(FILE *file, const FLAC__StreamMetadata_Unknown *block, unsigned block_length) +{ + FLAC__ASSERT(0 != file); + + if(local__fwrite(block->data, 1, block_length, file) != block_length) + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR; + + return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK; +} + FLAC__bool write_metadata_block_stationary_(FLAC__Metadata_SimpleIterator *iterator, const FLAC__StreamMetadata *block) { if(0 != fseek(iterator->file, iterator->offset[iterator->depth], SEEK_SET)) { diff --git a/src/libFLAC/metadata_object.c b/src/libFLAC/metadata_object.c index c6de62b..8bf1dd5 100644 --- a/src/libFLAC/metadata_object.c +++ b/src/libFLAC/metadata_object.c @@ -332,11 +332,22 @@ FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_new(FLAC__MetadataType type object->length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH; break; case FLAC__METADATA_TYPE_PADDING: + /* calloc() took care of this for us: + object->length = 0; + */ break; case FLAC__METADATA_TYPE_APPLICATION: object->length = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8; + /* calloc() took care of this for us: + object->data.application.data = 0; + */ break; case FLAC__METADATA_TYPE_SEEKTABLE: + /* calloc() took care of this for us: + object->length = 0; + object->data.seek_table.num_points = 0; + object->data.seek_table.points = 0; + */ break; case FLAC__METADATA_TYPE_VORBIS_COMMENT: { @@ -352,10 +363,11 @@ FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_new(FLAC__MetadataType type cuesheet_calculate_length_(object); break; default: - /* double protection: */ - FLAC__ASSERT(0); - free(object); - return 0; + /* calloc() took care of this for us: + object->length = 0; + object->data.unknown.data = 0; + */ + break; } } @@ -430,10 +442,11 @@ FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMet } break; default: - /* double protection: */ - FLAC__ASSERT(0); - free(to); - return 0; + if(!copy_bytes_(&to->data.unknown.data, object->data.unknown.data, object->length)) { + FLAC__metadata_object_delete(to); + return 0; + } + break; } } @@ -477,7 +490,11 @@ void FLAC__metadata_object_delete_data(FLAC__StreamMetadata *object) } break; default: - FLAC__ASSERT(0); + if(0 != object->data.unknown.data) { + free(object->data.unknown.data); + object->data.unknown.data = 0; + } + break; } } @@ -626,6 +643,17 @@ static FLAC__bool compare_block_data_cuesheet_(const FLAC__StreamMetadata_CueShe return true; } +static FLAC__bool compare_block_data_unknown_(const FLAC__StreamMetadata_Unknown *block1, const FLAC__StreamMetadata_Unknown *block2, unsigned block_length) +{ + FLAC__ASSERT(0 != block1); + FLAC__ASSERT(0 != block2); + + if(0 != block1->data && 0 != block2->data) + return 0 == memcmp(block1->data, block2->data, block_length); + else + return block1->data == block2->data; +} + FLAC_API FLAC__bool FLAC__metadata_object_is_equal(const FLAC__StreamMetadata *block1, const FLAC__StreamMetadata *block2) { FLAC__ASSERT(0 != block1); @@ -654,8 +682,7 @@ FLAC_API FLAC__bool FLAC__metadata_object_is_equal(const FLAC__StreamMetadata *b case FLAC__METADATA_TYPE_CUESHEET: return compare_block_data_cuesheet_(&block1->data.cue_sheet, &block2->data.cue_sheet); default: - FLAC__ASSERT(0); - return false; + return compare_block_data_unknown_(&block1->data.unknown, &block2->data.unknown, block1->length); } } diff --git a/src/libFLAC/stream_decoder.c b/src/libFLAC/stream_decoder.c index 61a6d22..882bf96 100644 --- a/src/libFLAC/stream_decoder.c +++ b/src/libFLAC/stream_decoder.c @@ -100,7 +100,7 @@ typedef struct FLAC__StreamDecoderPrivate { FLAC__bool has_stream_info, has_seek_table; FLAC__StreamMetadata stream_info; FLAC__StreamMetadata seek_table; - FLAC__bool metadata_filter[FLAC__METADATA_TYPE_UNDEFINED]; + 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 */ FLAC__Frame frame; @@ -390,7 +390,10 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecode FLAC__ASSERT(0 != decoder); FLAC__ASSERT(0 != decoder->private_); FLAC__ASSERT(0 != decoder->protected_); - FLAC__ASSERT(type < FLAC__METADATA_TYPE_UNDEFINED); + FLAC__ASSERT(type < (1u << FLAC__STREAM_METADATA_TYPE_LEN)); + /* double protection */ + if(type >= (1u << FLAC__STREAM_METADATA_TYPE_LEN)) + return false; if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) return false; decoder->private_->metadata_filter[type] = true; @@ -444,7 +447,10 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder FLAC__ASSERT(0 != decoder); FLAC__ASSERT(0 != decoder->private_); FLAC__ASSERT(0 != decoder->protected_); - FLAC__ASSERT(type < FLAC__METADATA_TYPE_UNDEFINED); + FLAC__ASSERT(type < (1u << FLAC__STREAM_METADATA_TYPE_LEN)); + /* double protection */ + if(type >= (1u << FLAC__STREAM_METADATA_TYPE_LEN)) + return false; if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) return false; decoder->private_->metadata_filter[type] = false; @@ -904,8 +910,20 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) break; case FLAC__METADATA_TYPE_STREAMINFO: case FLAC__METADATA_TYPE_SEEKTABLE: + assert(0); + break; default: - FLAC__ASSERT(0); + if(real_length > 0) { + if(0 == (block.data.unknown.data = (FLAC__byte*)malloc(real_length))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.unknown.data, real_length, read_callback_, decoder)) + return false; /* the read_callback_ sets the state for us */ + } + else + block.data.unknown.data = 0; + break; } decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data); @@ -937,8 +955,11 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) break; case FLAC__METADATA_TYPE_STREAMINFO: case FLAC__METADATA_TYPE_SEEKTABLE: - default: FLAC__ASSERT(0); + default: + if(0 != block.data.unknown.data) + free(block.data.unknown.data); + break; } } } diff --git a/src/libFLAC/stream_encoder.c b/src/libFLAC/stream_encoder.c index bf8e60c..f8edc58 100644 --- a/src/libFLAC/stream_encoder.c +++ b/src/libFLAC/stream_encoder.c @@ -663,9 +663,7 @@ FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder metadata_has_seektable = false; metadata_has_vorbis_comment = false; for(i = 0; i < encoder->protected_->num_metadata_blocks; i++) { - if(encoder->protected_->metadata[i]->type >= FLAC__METADATA_TYPE_UNDEFINED) - return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_METADATA; - else if(encoder->protected_->metadata[i]->type == FLAC__METADATA_TYPE_STREAMINFO) + if(encoder->protected_->metadata[i]->type == FLAC__METADATA_TYPE_STREAMINFO) return encoder->protected_->state = FLAC__STREAM_ENCODER_INVALID_METADATA; else if(encoder->protected_->metadata[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) { if(metadata_has_seektable) /* only one is allowed */ diff --git a/src/libFLAC/stream_encoder_framing.c b/src/libFLAC/stream_encoder_framing.c index 6ff9631..f9e7ca6 100644 --- a/src/libFLAC/stream_encoder_framing.c +++ b/src/libFLAC/stream_encoder_framing.c @@ -162,7 +162,9 @@ FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__ } break; default: - FLAC__ASSERT(0); + if(!FLAC__bitbuffer_write_byte_block(bb, metadata->data.unknown.data, metadata->length)) + return false; + break; } FLAC__ASSERT(FLAC__bitbuffer_is_byte_aligned(bb)); diff --git a/src/metaflac/operations.c b/src/metaflac/operations.c index 592526f..50b9e39 100644 --- a/src/metaflac/operations.c +++ b/src/metaflac/operations.c @@ -623,7 +623,9 @@ void write_metadata(const char *filename, FLAC__StreamMetadata *block, unsigned } break; default: - PPR; printf("SKIPPING block of unknown type\n"); + PPR; printf(" data contents:\n"); + if(0 != block->data.unknown.data) + hexdump(filename, block->data.unknown.data, block->length, " "); break; } #undef PPR