fix bugs exposed by latest tests
diff --git a/src/libFLAC/metadata.c b/src/libFLAC/metadata.c
index 20ddd17..cba325b 100644
--- a/src/libFLAC/metadata.c
+++ b/src/libFLAC/metadata.c
@@ -92,7 +92,7 @@
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, long 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, long fixup_is_last_flag_offset, FLAC__bool backup);
static FLAC__bool copy_n_bytes_from_file_(FILE *file, FILE *tempfile, unsigned bytes/*@@@ 4G limit*/, FLAC__MetaData_SimpleIteratorStatus *status);
static FLAC__bool copy_remaining_bytes_from_file_(FILE *file, FILE *tempfile, FLAC__MetaData_SimpleIteratorStatus *status);
@@ -516,7 +516,7 @@
else if(iterator->length < extra_padding_bytes_required)
use_padding = false;
else {
- padding_leftover = iterator->length - extra_padding_bytes_required;
+ padding_leftover = 4 + iterator->length - extra_padding_bytes_required; /*@@@ MAGIC NUMBER 4 = metadata block header length */
padding_is_last = iterator->is_last;
block->is_last = false;
}
@@ -534,7 +534,9 @@
return ret;
}
else {
- ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover, padding_is_last);
+ /*@@@ MAGIC NUMBER 4 = metadata block header length */
+ FLAC__ASSERT(padding_leftover >= 4);
+ ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover - 4, padding_is_last);
/*@@@@fprintf(stderr,"Z:544:offset/length/depth=%ld/%u/%u target=%ld ftell=%ld\n",iterator->offset[iterator->depth],iterator->length,iterator->depth,debug_target_offset,ftell(iterator->file));*/
FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset);
FLAC__ASSERT(ftell(iterator->file) == debug_target_offset + 4);
@@ -571,8 +573,7 @@
return false;
}
- if(iterator->is_last)
- block->is_last = true;
+ block->is_last = iterator->is_last;
if(use_padding) {
/* first see if we can even use padding */
@@ -589,15 +590,14 @@
use_padding = false;
}
else {
- /*@@@ MAGIC NUMBER 4 = metadata block header length, appears 2 times here: */
if(iterator->length == block->length) {
padding_leftover = 0;
block->is_last = iterator->is_last;
}
- else if(iterator->length < 4 + block->length)
+ else if(iterator->length < 4 + block->length) /*@@@ MAGIC NUMBER 4 = metadata block header length */
use_padding = false;
else {
- padding_leftover = iterator->length - 4 - block->length;
+ padding_leftover = iterator->length - block->length;
padding_is_last = iterator->is_last;
block->is_last = false;
}
@@ -618,7 +618,9 @@
return ret;
}
else {
- ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover, padding_is_last);
+ /*@@@ MAGIC NUMBER 4 = metadata block header length */
+ FLAC__ASSERT(padding_leftover >= 4);
+ ret = write_metadata_block_stationary_with_padding_(iterator, block, padding_leftover - 4, padding_is_last);
/*@@@@fprintf(stderr,"Z:628:offset/length/depth=%ld/%u/%u target=%ld ftell=%ld\n",iterator->offset[iterator->depth],iterator->length,iterator->depth,debug_target_offset,ftell(iterator->file));*/
FLAC__ASSERT(iterator->offset[iterator->depth] == debug_target_offset);
FLAC__ASSERT(ftell(iterator->file) == debug_target_offset + 4);
@@ -657,6 +659,8 @@
return false;
}
FLAC__metadata_object_delete(padding);
+ if(!FLAC__metadata_simple_iterator_prev(iterator))
+ return false;
/*@@@@fprintf(stderr,"Z:667:offset/length/depth=%ld/%u/%u target=%ld ftell=%ld\n",iterator->offset[iterator->depth],iterator->length,iterator->depth,debug_target_offset,ftell(iterator->file));*/
FLAC__ASSERT(iterator->offset[iterator->depth] + 4 + (long)iterator->length == debug_target_offset);
FLAC__ASSERT(ftell(iterator->file) + (long)iterator->length == debug_target_offset);
@@ -742,7 +746,9 @@
{
FLAC__ASSERT(0 != chain);
FLAC__ASSERT(0 != node);
+ FLAC__ASSERT(0 != node->data);
+ node->next = node->prev = 0;
node->data->is_last = true;
if(0 != chain->tail)
chain->tail->data->is_last = false;
@@ -750,6 +756,7 @@
if(0 == chain->head)
chain->head = node;
else {
+ FLAC__ASSERT(0 != chain->tail);
chain->tail->next = node;
node->prev = chain->tail;
}
@@ -773,6 +780,9 @@
else
node->next->prev = node->prev;
+ if(0 != chain->tail)
+ chain->tail->data->is_last = true;
+
chain->nodes--;
chain->current_length -= (4 + node->data->length); /*@@@ MAGIC NUMBER 4 = metadata block header bytes */
}
@@ -786,12 +796,14 @@
static void iterator_insert_node_(FLAC__MetaData_Iterator *iterator, FLAC__MetaData_Node *node)
{
FLAC__ASSERT(0 != node);
+ FLAC__ASSERT(0 != node->data);
FLAC__ASSERT(0 != iterator);
FLAC__ASSERT(0 != iterator->current);
FLAC__ASSERT(0 != iterator->chain);
FLAC__ASSERT(0 != iterator->chain->head);
FLAC__ASSERT(0 != iterator->chain->tail);
+ node->data->is_last = false;
node->prev = iterator->current->prev;
if(0 == node->prev)
iterator->chain->head = node;
@@ -808,6 +820,7 @@
static void iterator_insert_node_after_(FLAC__MetaData_Iterator *iterator, FLAC__MetaData_Node *node)
{
FLAC__ASSERT(0 != node);
+ FLAC__ASSERT(0 != node->data);
FLAC__ASSERT(0 != iterator);
FLAC__ASSERT(0 != iterator->current);
FLAC__ASSERT(0 != iterator->chain);
@@ -982,8 +995,6 @@
node = node->next;
}
}
- if(0 != chain->tail)
- chain->tail->data->is_last = true;
}
void FLAC__metadata_chain_sort_padding(FLAC__MetaData_Chain *chain)
@@ -1009,8 +1020,6 @@
node = node->next;
}
}
- if(0 != chain->tail)
- chain->tail->data->is_last = true;
FLAC__metadata_chain_merge_padding(chain);
}
@@ -2038,10 +2047,29 @@
{
FILE *tempfile;
char *tempfilename;
- long fixup_is_last_flag_offset;
+ int fixup_is_last_code = 0; /* 0 => no need to change any is_last flags */
+ long fixup_is_last_flag_offset = -1;
FLAC__ASSERT(0 != block || append == false);
+ if(iterator->is_last) {
+ if(append) {
+ fixup_is_last_code = 1; /* 1 => clear the is_last flag at the following offset */
+ fixup_is_last_flag_offset = iterator->offset[iterator->depth];
+ }
+ else if(0 == block) {
+ simple_iterator_push_(iterator);
+ if(!FLAC__metadata_simple_iterator_prev(iterator)) {
+ (void)simple_iterator_pop_(iterator);
+ return false;
+ }
+ fixup_is_last_code = -1; /* -1 => set the is_last the flag at the following offset */
+ fixup_is_last_flag_offset = iterator->offset[iterator->depth];
+ if(!simple_iterator_pop_(iterator))
+ return false;
+ }
+ }
+
if(!simple_iterator_copy_file_prefix_(iterator, &tempfile, &tempfilename, append))
return false;
@@ -2057,11 +2085,7 @@
}
}
- if(append && iterator->is_last)
- fixup_is_last_flag_offset = iterator->offset[iterator->depth]; /*@@@ MAGIC NUMBER; we know the is_last flag is here */
- else
- fixup_is_last_flag_offset = -1;
- if(!simple_iterator_copy_file_postfix_(iterator, &tempfile, &tempfilename, fixup_is_last_flag_offset, block==0))
+ if(!simple_iterator_copy_file_postfix_(iterator, &tempfile, &tempfilename, fixup_is_last_code, fixup_is_last_flag_offset, block==0))
return false;
if(append)
@@ -2228,7 +2252,7 @@
return true;
}
-FLAC__bool simple_iterator_copy_file_postfix_(FLAC__MetaData_SimpleIterator *iterator, FILE **tempfile, char **tempfilename, long 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, long fixup_is_last_flag_offset, FLAC__bool backup)
{
long save_offset = iterator->offset[iterator->depth]; /*@@@ 2G limit */
FLAC__ASSERT(0 != *tempfile);
@@ -2244,8 +2268,13 @@
return false;
}
- if(fixup_is_last_flag_offset >= 0) {
- /* this means a block was appended to the end so we have to clear the is_last flag of the previous block */
+ if(fixup_is_last_code != 0) {
+ /*
+ * if code == 1, it means a block was appended to the end so
+ * we have to clear the is_last flag of the previous block
+ * if code == -1, it means the last block was deleted so
+ * we have to set the is_last flag of the previous block
+ */
/*@@@ MAGIC NUMBERs here; we know the is_last flag is the high bit of the byte at this location */
FLAC__byte x;
if(0 != fseek(*tempfile, fixup_is_last_flag_offset, SEEK_SET)) {
@@ -2258,8 +2287,14 @@
iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
return false;
}
- FLAC__ASSERT(x & 0x80);
- x &= 0x7f;
+ if(fixup_is_last_code > 0) {
+ FLAC__ASSERT(x & 0x80);
+ x &= 0x7f;
+ }
+ else {
+ FLAC__ASSERT(!(x & 0x80));
+ x |= 0x80;
+ }
if(0 != fseek(*tempfile, fixup_is_last_flag_offset, SEEK_SET)) {
cleanup_tempfile_(tempfile, tempfilename);
iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR;
diff --git a/src/libFLAC/seekable_stream_decoder.c b/src/libFLAC/seekable_stream_decoder.c
index 7a29db5..64c43c0 100644
--- a/src/libFLAC/seekable_stream_decoder.c
+++ b/src/libFLAC/seekable_stream_decoder.c
@@ -152,6 +152,8 @@
decoder->private_->error_callback = 0;
decoder->private_->client_data = 0;
+ decoder->protected_->md5_checking = false;
+
return decoder;
}
diff --git a/src/libFLAC/stream_decoder.c b/src/libFLAC/stream_decoder.c
index 6f51602..0d269cd 100644
--- a/src/libFLAC/stream_decoder.c
+++ b/src/libFLAC/stream_decoder.c
@@ -171,6 +171,18 @@
decoder->private_->error_callback = 0;
decoder->private_->client_data = 0;
+ memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter));
+ decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO] = true;
+ decoder->private_->metadata_filter_ids_capacity = 16;
+ if(0 == (decoder->private_->metadata_filter_ids = malloc((FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) * decoder->private_->metadata_filter_ids_capacity))) {
+ FLAC__bitbuffer_delete(decoder->private_->input);
+ free(decoder->private_);
+ free(decoder->protected_);
+ free(decoder);
+ return 0;
+ }
+ decoder->private_->metadata_filter_ids_count = 0;
+
return decoder;
}
@@ -221,16 +233,6 @@
decoder->private_->samples_decoded = 0;
decoder->private_->has_stream_info = false;
decoder->private_->has_seek_table = false;
-
- memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter));
- decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO] = true;
- decoder->private_->metadata_filter_ids_capacity = 16;
- if(0 == (decoder->private_->metadata_filter_ids = malloc((FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) * decoder->private_->metadata_filter_ids_capacity))) {
- decoder->private_->metadata_filter_ids_capacity = 0;
- return decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
- }
- decoder->private_->metadata_filter_ids_count = 0;
-
decoder->private_->cached = false;
/*