big fix to allow codec and metadata interface to handle unknown metadata block types correctly
This commit is contained in:
parent
0eea34aad0
commit
d060947ce9
@ -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)) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user