X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2FlibFLAC%2Fstream_decoder.c;h=29e4469a13fd5339fbb51208e1a26ea86fd60be1;hb=7dc5e3a8ff3f1b348580f48cccf4d2fd24d6384e;hp=587023174c86e9456b4c978e5c2acac445d05eee;hpb=b47ab0d25059cd053e1da1fbc79011b92642524e;p=platform%2Fupstream%2Fflac.git diff --git a/src/libFLAC/stream_decoder.c b/src/libFLAC/stream_decoder.c index 5870231..29e4469 100644 --- a/src/libFLAC/stream_decoder.c +++ b/src/libFLAC/stream_decoder.c @@ -1,5 +1,5 @@ /* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson + * Copyright (C) 2000,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 @@ -33,26 +33,14 @@ # include #endif -#if defined _MSC_VER || defined __MINGW32__ -#include /* for _setmode() */ -#include /* for _O_BINARY */ -#endif -#if defined __CYGWIN__ || defined __EMX__ -#include /* for setmode(), O_BINARY */ -#include /* for _O_BINARY */ -#endif #include #include /* for malloc() */ #include /* for memset/memcpy() */ #include /* for stat() */ #include /* for off_t */ -#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ -#if _MSC_VER <= 1600 || defined __BORLANDC__ /* @@@ [2G limit] */ -#define fseeko fseek -#define ftello ftell -#endif -#endif +#include "share/compat.h" #include "FLAC/assert.h" +#include "share/alloc.h" #include "protected/stream_decoder.h" #include "private/bitreader.h" #include "private/bitmath.h" @@ -63,28 +51,15 @@ #include "private/lpc.h" #include "private/md5.h" #include "private/memory.h" - -#ifdef max -#undef max -#endif -#define max(a,b) ((a)>(b)?(a):(b)) - -/* adjust for compilers that can't understand using LLU suffix for uint64_t literals */ -#ifdef _MSC_VER -#define FLAC__U64L(x) x -#else -#define FLAC__U64L(x) x##LLU -#endif +#include "private/macros.h" /* technically this should be in an "export.c" but this is convenient enough */ -FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC = -#if FLAC__HAS_OGG - 1 +#ifdef FLAC_API_SUPPORTS_OGG_FLAC +FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC = FLAC__HAS_OGG ; #else - 0 +FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC = 0 ; #endif -; /*********************************************************************** @@ -181,7 +156,7 @@ typedef struct FLAC__StreamDecoderPrivate { FLAC__StreamMetadata seek_table; 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 */ + size_t metadata_filter_ids_count, metadata_filter_ids_capacity; /* units for both are IDs, not bytes */ FLAC__Frame frame; FLAC__bool cached; /* true if there is a byte in lookahead */ FLAC__CPUInfo cpuinfo; @@ -280,18 +255,18 @@ FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void) FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ - decoder = (FLAC__StreamDecoder*)calloc(1, sizeof(FLAC__StreamDecoder)); + decoder = calloc(1, sizeof(FLAC__StreamDecoder)); if(decoder == 0) { return 0; } - decoder->protected_ = (FLAC__StreamDecoderProtected*)calloc(1, sizeof(FLAC__StreamDecoderProtected)); + decoder->protected_ = calloc(1, sizeof(FLAC__StreamDecoderProtected)); if(decoder->protected_ == 0) { free(decoder); return 0; } - decoder->private_ = (FLAC__StreamDecoderPrivate*)calloc(1, sizeof(FLAC__StreamDecoderPrivate)); + decoder->private_ = calloc(1, sizeof(FLAC__StreamDecoderPrivate)); if(decoder->private_ == 0) { free(decoder->protected_); free(decoder); @@ -307,7 +282,7 @@ FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void) } decoder->private_->metadata_filter_ids_capacity = 16; - if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)malloc((FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) * decoder->private_->metadata_filter_ids_capacity))) { + if(0 == (decoder->private_->metadata_filter_ids = malloc((FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) * decoder->private_->metadata_filter_ids_capacity))) { FLAC__bitreader_delete(decoder->private_->input); free(decoder->private_); free(decoder->protected_); @@ -340,7 +315,9 @@ FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder) { unsigned i; - FLAC__ASSERT(0 != decoder); + if (decoder == NULL) + return ; + FLAC__ASSERT(0 != decoder->protected_); FLAC__ASSERT(0 != decoder->private_); FLAC__ASSERT(0 != decoder->private_->input); @@ -420,8 +397,10 @@ static FLAC__StreamDecoderInitStatus init_stream_internal_( #ifdef FLAC__CPU_IA32 FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32); #ifdef FLAC__HAS_NASM +#if 1 /*@@@@@@ OPT: not clearly faster, needs more testing */ if(decoder->private_->cpuinfo.data.ia32.bswap) decoder->private_->local_bitreader_read_rice_signed_block = FLAC__bitreader_read_rice_signed_block_asm_ia32_bswap; +#endif if(decoder->private_->cpuinfo.data.ia32.mmx) { decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32; decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32_mmx; @@ -625,7 +604,7 @@ static FLAC__StreamDecoderInitStatus init_file_internal_( if(0 == write_callback || 0 == error_callback) return decoder->protected_->state = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS; - file = filename? fopen(filename, "rb") : stdin; + file = filename? flac_fopen(filename, "rb") : stdin; if(0 == file) return FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE; @@ -782,7 +761,7 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__ FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids); if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) { - if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2))) { + if(0 == (decoder->private_->metadata_filter_ids = safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -841,7 +820,7 @@ FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__S FLAC__ASSERT(0 != decoder->private_->metadata_filter_ids); if(decoder->private_->metadata_filter_ids_count == decoder->private_->metadata_filter_ids_capacity) { - if(0 == (decoder->private_->metadata_filter_ids = (FLAC__byte*)realloc(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity * 2))) { + if(0 == (decoder->private_->metadata_filter_ids = safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/2))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1285,9 +1264,11 @@ FILE *get_binary_stdin_(void) */ #if defined _MSC_VER || defined __MINGW32__ _setmode(_fileno(stdin), _O_BINARY); -#elif defined __CYGWIN__ || defined __EMX__ +#elif defined __CYGWIN__ /* almost certainly not needed for any modern Cygwin, but let's be safe... */ setmode(_fileno(stdin), _O_BINARY); +#elif defined __EMX__ + setmode(fileno(stdin), O_BINARY); #endif return stdin; @@ -1321,7 +1302,7 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigne * (at negative indices) for alignment purposes; we use 4 * to keep the data well-aligned. */ - tmp = (FLAC__int32*)malloc(sizeof(FLAC__int32)*(size+4)); + tmp = safe_malloc_muladd2_(sizeof(FLAC__int32), /*times (*/size, /*+*/4/*)*/); if(tmp == 0) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; @@ -1346,7 +1327,7 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigne FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id) { - unsigned i; + size_t i; FLAC__ASSERT(0 != decoder); FLAC__ASSERT(0 != decoder->private_); @@ -1402,7 +1383,7 @@ FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder) decoder->private_->lookahead = (FLAC__byte)x; decoder->private_->cached = true; } - else if(x >> 2 == 0x3e) { /* MAGIC NUMBER for the last 6 sync bits */ + else if(x >> 1 == 0x7c) { /* MAGIC NUMBER for the last 6 sync bits and reserved 7th bit */ decoder->private_->header_warmup[1] = (FLAC__byte)x; decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME; return true; @@ -1467,6 +1448,11 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8)) return false; /* read_callback_ sets the state for us */ + if(real_length < FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) { /* underflow check */ + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;/*@@@@@@ maybe wrong error? need to resync?*/ + return false; + } + real_length -= FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8; if(decoder->private_->metadata_filter_ids_count > 0 && has_id_filtered_(decoder, block.data.application.id)) @@ -1487,7 +1473,7 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) case FLAC__METADATA_TYPE_APPLICATION: /* remember, we read the ID already */ if(real_length > 0) { - if(0 == (block.data.application.data = (FLAC__byte*)malloc(real_length))) { + if(0 == (block.data.application.data = malloc(real_length))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1515,7 +1501,7 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) break; default: if(real_length > 0) { - if(0 == (block.data.unknown.data = (FLAC__byte*)malloc(real_length))) { + if(0 == (block.data.unknown.data = malloc(real_length))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1529,7 +1515,7 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) if(!decoder->private_->is_seeking && decoder->private_->metadata_callback) decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data); - /* now we have to free any malloc'ed data in the block */ + /* now we have to free any malloc()ed data in the block */ switch(type) { case FLAC__METADATA_TYPE_PADDING: break; @@ -1669,7 +1655,7 @@ FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_ decoder->private_->seek_table.data.seek_table.num_points = length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH; /* use realloc since we may pass through here several times (e.g. after seeking) */ - if(0 == (decoder->private_->seek_table.data.seek_table.points = (FLAC__StreamMetadata_SeekPoint*)realloc(decoder->private_->seek_table.data.seek_table.points, decoder->private_->seek_table.data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint)))) { + if(0 == (decoder->private_->seek_table.data.seek_table.points = safe_realloc_mul_2op_(decoder->private_->seek_table.data.seek_table.points, decoder->private_->seek_table.data.seek_table.num_points, /*times*/sizeof(FLAC__StreamMetadata_SeekPoint)))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1708,7 +1694,7 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length)) return false; /* read_callback_ sets the state for us */ if(obj->vendor_string.length > 0) { - if(0 == (obj->vendor_string.entry = (FLAC__byte*)malloc(obj->vendor_string.length+1))) { + if(0 == (obj->vendor_string.entry = safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1726,7 +1712,7 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre /* read comments */ if(obj->num_comments > 0) { - if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)malloc(obj->num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) { + if(0 == (obj->comments = safe_malloc_mul_2op_p(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1735,7 +1721,7 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length)) return false; /* read_callback_ sets the state for us */ if(obj->comments[i].length > 0) { - if(0 == (obj->comments[i].entry = (FLAC__byte*)malloc(obj->comments[i].length+1))) { + if(0 == (obj->comments[i].entry = safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1781,7 +1767,7 @@ FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMet obj->num_tracks = x; if(obj->num_tracks > 0) { - if(0 == (obj->tracks = (FLAC__StreamMetadata_CueSheet_Track*)calloc(obj->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) { + if(0 == (obj->tracks = safe_calloc_(obj->num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track)))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1814,7 +1800,7 @@ FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMet track->num_indices = (FLAC__byte)x; if(track->num_indices > 0) { - if(0 == (track->indices = (FLAC__StreamMetadata_CueSheet_Index*)calloc(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) { + if(0 == (track->indices = safe_calloc_(track->num_indices, sizeof(FLAC__StreamMetadata_CueSheet_Index)))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1851,7 +1837,7 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta /* read MIME type */ if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN)) return false; /* read_callback_ sets the state for us */ - if(0 == (obj->mime_type = (char*)malloc(x+1))) { + if(0 == (obj->mime_type = safe_malloc_add_2op_(x, /*+*/1))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1864,7 +1850,7 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta /* read description */ if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN)) return false; /* read_callback_ sets the state for us */ - if(0 == (obj->description = (FLAC__byte*)malloc(x+1))) { + if(0 == (obj->description = safe_malloc_add_2op_(x, /*+*/1))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1893,7 +1879,7 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta /* read data */ if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &(obj->data_length), FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN)) return false; /* read_callback_ sets the state for us */ - if(0 == (obj->data = (FLAC__byte*)malloc(obj->data_length))) { + if(0 == (obj->data = safe_malloc_(obj->data_length))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1967,7 +1953,7 @@ FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder) decoder->private_->lookahead = (FLAC__byte)x; decoder->private_->cached = true; } - else if(x >> 2 == 0x3e) { /* MAGIC NUMBER for the last 6 sync bits */ + else if(x >> 1 == 0x7c) { /* MAGIC NUMBER for the last 6 sync bits and reserved 7th bit */ decoder->private_->header_warmup[1] = (FLAC__byte)x; decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME; return true; @@ -2041,6 +2027,8 @@ FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FL } if(!read_zero_padding_(decoder)) return false; + if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption (i.e. "zero bits" were not all zeroes) */ + return true; /* * Read the frame CRC-16 from the footer and check @@ -2076,7 +2064,7 @@ FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FL decoder->private_->output[0][i] = (mid + side) >> 1; decoder->private_->output[1][i] = (mid - side) >> 1; #else - //@@@@@@ OPT: try without 'side' temp variable + /* OPT: without 'side' temp variable */ mid = (decoder->private_->output[0][i] << 1) | (decoder->private_->output[1][i] & 1); /* i.e. if 'side' is odd... */ decoder->private_->output[0][i] = (mid + decoder->private_->output[1][i]) >> 1; decoder->private_->output[1][i] = (mid - decoder->private_->output[1][i]) >> 1; @@ -2725,7 +2713,7 @@ FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigne } } - if(!FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, max(6, partition_order))) { + if(!FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, flac_max(6u, partition_order))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -3007,32 +2995,55 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s upper_bound = stream_length; upper_bound_sample = total_samples > 0 ? total_samples : target_sample /*estimate it*/; - /*@@@@@@ add step to validate seek table before using? encoding to pipe leaves some flac files with incomplete seektables which screw us up */ - /* * Now we refine the bounds if we have a seektable with * suitable points. Note that according to the spec they * must be ordered by ascending sample number. + * + * Note: to protect against invalid seek tables we will ignore points + * that have frame_samples==0 or sample_number>=total_samples */ if(seek_table) { + FLAC__uint64 new_lower_bound = lower_bound; + FLAC__uint64 new_upper_bound = upper_bound; + FLAC__uint64 new_lower_bound_sample = lower_bound_sample; + FLAC__uint64 new_upper_bound_sample = upper_bound_sample; + /* find the closest seek point <= target_sample, if it exists */ for(i = (int)seek_table->num_points - 1; i >= 0; i--) { - if(seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && seek_table->points[i].sample_number <= target_sample) + if( + seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && + seek_table->points[i].frame_samples > 0 && /* defense against bad seekpoints */ + (total_samples <= 0 || seek_table->points[i].sample_number < total_samples) && /* defense against bad seekpoints */ + seek_table->points[i].sample_number <= target_sample + ) break; } if(i >= 0) { /* i.e. we found a suitable seek point... */ - lower_bound = first_frame_offset + seek_table->points[i].stream_offset; - lower_bound_sample = seek_table->points[i].sample_number; + new_lower_bound = first_frame_offset + seek_table->points[i].stream_offset; + new_lower_bound_sample = seek_table->points[i].sample_number; } /* find the closest seek point > target_sample, if it exists */ for(i = 0; i < (int)seek_table->num_points; i++) { - if(seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && seek_table->points[i].sample_number > target_sample) + if( + seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && + seek_table->points[i].frame_samples > 0 && /* defense against bad seekpoints */ + (total_samples <= 0 || seek_table->points[i].sample_number < total_samples) && /* defense against bad seekpoints */ + seek_table->points[i].sample_number > target_sample + ) break; } if(i < (int)seek_table->num_points) { /* i.e. we found a suitable seek point... */ - upper_bound = first_frame_offset + seek_table->points[i].stream_offset; - upper_bound_sample = seek_table->points[i].sample_number; + new_upper_bound = first_frame_offset + seek_table->points[i].stream_offset; + new_upper_bound_sample = seek_table->points[i].sample_number; + } + /* final protection against unsorted seek tables; keep original values if bogus */ + if(new_upper_bound >= new_lower_bound) { + lower_bound = new_lower_bound; + upper_bound = new_upper_bound; + lower_bound_sample = new_lower_bound_sample; + upper_bound_sample = new_upper_bound_sample; } } @@ -3114,11 +3125,11 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s } /* our last move backwards wasn't big enough, try again */ approx_bytes_per_frame = approx_bytes_per_frame? approx_bytes_per_frame * 2 : 16; - continue; + continue; } /* allow one seek over upper bound, so we can get a correct upper_bound_sample for streams with unknown total_samples */ first_seek = false; - + /* make sure we are not seeking in corrupted stream */ if (this_frame_sample < lower_bound_sample) { decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; @@ -3153,12 +3164,12 @@ FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint { FLAC__uint64 left_pos = 0, right_pos = stream_length; FLAC__uint64 left_sample = 0, right_sample = FLAC__stream_decoder_get_total_samples(decoder); - FLAC__uint64 this_frame_sample = 0; /* only initialized to avoid compiler warning */ + FLAC__uint64 this_frame_sample = (FLAC__uint64)0 - 1; FLAC__uint64 pos = 0; /* only initialized to avoid compiler warning */ FLAC__bool did_a_seek; unsigned iteration = 0; - /* In the first iterations, we will calculate the target byte position + /* In the first iterations, we will calculate the target byte position * by the distance from the target sample to left_sample and * right_sample (let's call it "proportional search"). After that, we * will switch to binary search. @@ -3202,9 +3213,7 @@ FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint /* @@@ TODO: might want to limit pos to some distance * before EOF, to make sure we land before the last frame, * thereby getting a this_frame_sample and so having a better - * estimate. @@@@@@DELETE:this would also mostly (or totally if we could - * be sure to land before the last frame) avoid the - * end-of-stream case we have to check later. + * estimate. */ } @@ -3245,7 +3254,7 @@ FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint } } /* our write callback will change the state when it gets to the target frame */ - else if(!decoder->private_->is_seeking/*@@@@@@ && decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM*/) { + else if(!decoder->private_->is_seeking) { break; } else { @@ -3310,7 +3319,7 @@ FLAC__StreamDecoderSeekStatus file_seek_callback_(const FLAC__StreamDecoder *dec if(decoder->private_->file == stdin) return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED; - else if(fseeko(decoder->private_->file, (off_t)absolute_byte_offset, SEEK_SET) < 0) + else if(fseeko(decoder->private_->file, (FLAC__off_t)absolute_byte_offset, SEEK_SET) < 0) return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; else return FLAC__STREAM_DECODER_SEEK_STATUS_OK; @@ -3318,7 +3327,7 @@ FLAC__StreamDecoderSeekStatus file_seek_callback_(const FLAC__StreamDecoder *dec FLAC__StreamDecoderTellStatus file_tell_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) { - off_t pos; + FLAC__off_t pos; (void)client_data; if(decoder->private_->file == stdin) @@ -3333,12 +3342,12 @@ FLAC__StreamDecoderTellStatus file_tell_callback_(const FLAC__StreamDecoder *dec FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) { - struct stat filestats; + struct flac_stat_s filestats; (void)client_data; if(decoder->private_->file == stdin) return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED; - else if(fstat(fileno(decoder->private_->file), &filestats) != 0) + else if(flac_fstat(fileno(decoder->private_->file), &filestats) != 0) return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR; else { *stream_length = (FLAC__uint64)filestats.st_size;