diff options
author | Robert Shih <robertshih@google.com> | 2015-01-05 17:35:54 -0800 |
---|---|---|
committer | Robert Shih <robertshih@google.com> | 2015-01-06 15:13:52 -0800 |
commit | 31e4f3166a91a2ebb34f643787122a638d9f1471 (patch) | |
tree | 0bdb8de4408e53205807126df684051da7c31fa8 /libFLAC/stream_decoder.c | |
parent | 457fe12432caac0de0e430bb976dab681b3ae1a2 (diff) | |
download | android_external_flac-31e4f3166a91a2ebb34f643787122a638d9f1471.tar.gz android_external_flac-31e4f3166a91a2ebb34f643787122a638d9f1471.tar.bz2 android_external_flac-31e4f3166a91a2ebb34f643787122a638d9f1471.zip |
libFLAC: merge master from Xiph
remote: https://git.xiph.org/flac.git
commit: 775eb93
Bug: 18872897
Bug: 18910747
Change-Id: I6e450e44c96b97c3323e428b9e6d420422f24a4e
Diffstat (limited to 'libFLAC/stream_decoder.c')
-rw-r--r-- | libFLAC/stream_decoder.c | 327 |
1 files changed, 166 insertions, 161 deletions
diff --git a/libFLAC/stream_decoder.c b/libFLAC/stream_decoder.c index 916fde6..d13b23b 100644 --- a/libFLAC/stream_decoder.c +++ b/libFLAC/stream_decoder.c @@ -1,5 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,29 +30,16 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include <config.h> #endif -#if defined _MSC_VER || defined __MINGW32__ -#include <io.h> /* for _setmode() */ -#include <fcntl.h> /* for _O_BINARY */ -#endif -#if defined __CYGWIN__ || defined __EMX__ -#include <io.h> /* for setmode(), O_BINARY */ -#include <fcntl.h> /* for _O_BINARY */ -#endif #include <stdio.h> #include <stdlib.h> /* for malloc() */ #include <string.h> /* for memset/memcpy() */ #include <sys/stat.h> /* for stat() */ #include <sys/types.h> /* 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" @@ -64,18 +52,7 @@ #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 */ @@ -94,7 +71,7 @@ FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC = * ***********************************************************************/ -static FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' }; +static const FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' }; /*********************************************************************** * @@ -110,7 +87,7 @@ static FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder); static FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder); static FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length); static FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length); -static FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj); +static FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj, unsigned length); static FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj); static FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_Picture *obj); static FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder); @@ -165,9 +142,6 @@ typedef struct FLAC__StreamDecoderPrivate { void (*local_lpc_restore_signal_64bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit): */ void (*local_lpc_restore_signal_16bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); - /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit), AND order <= 8: */ - void (*local_lpc_restore_signal_16bit_order8)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); - FLAC__bool (*local_bitreader_read_rice_signed_block)(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter); void *client_data; FILE *file; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */ FLAC__BitReader *input; @@ -193,9 +167,7 @@ typedef struct FLAC__StreamDecoderPrivate { FLAC__bool do_md5_checking; /* initially gets protected_->md5_checking but is turned off after a seek or if the metadata has a zero MD5 */ FLAC__bool internal_reset_hack; /* used only during init() so we can call reset to set up the decoder without rewinding the input */ FLAC__bool is_seeking; -#ifndef FLAC__NO_MD5 FLAC__MD5Context md5context; -#endif FLAC__byte computed_md5sum[16]; /* this is the sum we computed from the decoded data */ /* (the rest of these are only used for seeking) */ FLAC__Frame last_frame; /* holds the info of the last frame we seeked to */ @@ -283,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); @@ -310,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_); @@ -343,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); @@ -404,7 +378,7 @@ static FLAC__StreamDecoderInitStatus init_stream_internal_( #if FLAC__HAS_OGG decoder->private_->is_ogg = is_ogg; if(is_ogg && !FLAC__ogg_decoder_aspect_init(&decoder->protected_->ogg_decoder_aspect)) - return decoder->protected_->state = FLAC__STREAM_DECODER_OGG_ERROR; + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE; #endif /* @@ -415,42 +389,44 @@ static FLAC__StreamDecoderInitStatus init_stream_internal_( decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal; decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide; decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal; - decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal; - decoder->private_->local_bitreader_read_rice_signed_block = FLAC__bitreader_read_rice_signed_block; /* now override with asm where appropriate */ #ifndef FLAC__NO_ASM if(decoder->private_->cpuinfo.use_asm) { #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_64bit = FLAC__lpc_restore_signal_wide_asm_ia32; /* OPT_IA32: was really necessary for GCC < 4.9 */ + if(decoder->private_->cpuinfo.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; - decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32_mmx; } else { 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; - decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32; } #endif -#elif defined FLAC__CPU_PPC - FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_PPC); - if(decoder->private_->cpuinfo.data.ppc.altivec) { - decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ppc_altivec_16; - decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8; +#ifdef FLAC__HAS_X86INTRIN +# if defined FLAC__SSE2_SUPPORTED && !defined FLAC__HAS_NASM /* OPT_SSE: not better than MMX asm */ + if(decoder->private_->cpuinfo.ia32.sse2) { + decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_16_intrin_sse2; + } +# endif +# if defined FLAC__SSE4_1_SUPPORTED + if(decoder->private_->cpuinfo.ia32.sse41) { + decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_intrin_sse41; } +# endif +#endif +#elif defined FLAC__CPU_X86_64 + FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_X86_64); + /* No useful SSE optimizations yet */ #endif } #endif /* from here on, errors are fatal */ - if(!FLAC__bitreader_init(decoder->private_->input, decoder->private_->cpuinfo, read_callback_, decoder)) { + if(!FLAC__bitreader_init(decoder->private_->input, read_callback_, decoder)) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR; } @@ -551,10 +527,10 @@ static FLAC__StreamDecoderInitStatus init_FILE_internal_( FLAC__ASSERT(0 != file); if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) - return decoder->protected_->state = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED; + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED; if(0 == write_callback || 0 == error_callback) - return decoder->protected_->state = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS; + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS; /* * To make sure that our file does not go unclosed after an error, we @@ -625,12 +601,12 @@ static FLAC__StreamDecoderInitStatus init_file_internal_( * in FLAC__stream_decoder_init_FILE() before the FILE* is assigned. */ if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) - return decoder->protected_->state = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED; + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED; if(0 == write_callback || 0 == error_callback) - return decoder->protected_->state = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS; + return decoder->protected_->initstate = 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; @@ -674,12 +650,10 @@ FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder) if(decoder->protected_->state == FLAC__STREAM_DECODER_UNINITIALIZED) return true; -#ifndef FLAC__NO_MD5 - /* see the comment in FLAC__seekable_stream_decoder_reset() as to why we + /* see the comment in FLAC__stream_decoder_reset() as to why we * always call FLAC__MD5Final() */ FLAC__MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context); -#endif if(decoder->private_->has_seek_table && 0 != decoder->private_->seek_table.data.seek_table.points) { free(decoder->private_->seek_table.data.seek_table.points); @@ -789,7 +763,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*)safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/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; } @@ -848,7 +822,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*)safe_realloc_mul_2op_(decoder->private_->metadata_filter_ids, decoder->private_->metadata_filter_ids_capacity, /*times*/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; } @@ -1025,7 +999,6 @@ FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder) */ decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size = 0; -#ifndef FLAC__NO_MD5 /* We initialize the FLAC__MD5Context even though we may never use it. This * is because md5 checking may be turned on to start and then turned off if * a seek occurs. So we init the context here and finalize it in @@ -1033,7 +1006,6 @@ FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder) * properly. */ FLAC__MD5Init(&decoder->private_->md5context); -#endif decoder->private_->first_frame_offset = 0; decoder->private_->unparseable_frame_count = 0; @@ -1294,7 +1266,7 @@ FILE *get_binary_stdin_(void) */ #if defined _MSC_VER || defined __MINGW32__ _setmode(_fileno(stdin), _O_BINARY); -#elif defined __CYGWIN__ +#elif defined __CYGWIN__ /* almost certainly not needed for any modern Cygwin, but let's be safe... */ setmode(_fileno(stdin), _O_BINARY); #elif defined __EMX__ @@ -1309,6 +1281,9 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigne unsigned i; FLAC__int32 *tmp; + /* Make sure size is some sensible minimum value. Plumb through predictor_order maybe? */ + size = size < FLAC__MAX_LPC_ORDER ? FLAC__MAX_LPC_ORDER : size ; + if(size <= decoder->private_->output_capacity && channels <= decoder->private_->output_channels) return true; @@ -1332,7 +1307,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*)safe_malloc_muladd2_(sizeof(FLAC__int32), /*times (*/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; @@ -1340,9 +1315,6 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigne memset(tmp, 0, sizeof(FLAC__int32)*4); decoder->private_->output[i] = tmp + 4; - /* WATCHOUT: - * minimum of quadword alignment for PPC vector optimizations is REQUIRED: - */ if(!FLAC__memory_alloc_aligned_int32_array(size, &decoder->private_->residual_unaligned[i], &decoder->private_->residual[i])) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; @@ -1392,6 +1364,10 @@ FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder) id = 0; continue; } + + if(id >= 3) + return false; + if(x == ID3V2_TAG_[id]) { id++; i = 0; @@ -1413,7 +1389,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; @@ -1470,6 +1446,7 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) unsigned real_length = length; FLAC__StreamMetadata block; + memset(&block, 0, sizeof(block)); block.is_last = is_last; block.type = (FLAC__MetadataType)type; block.length = length; @@ -1494,36 +1471,37 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) return false; /* read_callback_ sets the state for us */ } else { + FLAC__bool ok = true; switch(type) { case FLAC__METADATA_TYPE_PADDING: /* skip the padding bytes */ if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, real_length)) - return false; /* read_callback_ sets the state for us */ + ok = false; /* read_callback_ sets the state for us */ break; 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; + ok = false; } - if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.data, real_length)) - return false; /* read_callback_ sets the state for us */ + else if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.data, real_length)) + ok = false; /* read_callback_ sets the state for us */ } else block.data.application.data = 0; break; case FLAC__METADATA_TYPE_VORBIS_COMMENT: - if(!read_metadata_vorbiscomment_(decoder, &block.data.vorbis_comment)) - return false; + if(!read_metadata_vorbiscomment_(decoder, &block.data.vorbis_comment, real_length)) + ok = false; break; case FLAC__METADATA_TYPE_CUESHEET: if(!read_metadata_cuesheet_(decoder, &block.data.cue_sheet)) - return false; + ok = false; break; case FLAC__METADATA_TYPE_PICTURE: if(!read_metadata_picture_(decoder, &block.data.picture)) - return false; + ok = false; break; case FLAC__METADATA_TYPE_STREAMINFO: case FLAC__METADATA_TYPE_SEEKTABLE: @@ -1531,18 +1509,18 @@ 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; + ok = false; } - if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.unknown.data, real_length)) - return false; /* read_callback_ sets the state for us */ + else if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.unknown.data, real_length)) + ok = false; /* read_callback_ sets the state for us */ } else block.data.unknown.data = 0; break; } - if(!decoder->private_->is_seeking && decoder->private_->metadata_callback) + if(ok && !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 */ @@ -1587,6 +1565,9 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) free(block.data.unknown.data); break; } + + if(!ok) /* anything that unsets "ok" should also make sure decoder->protected_->state is updated */ + return false; } } @@ -1685,7 +1666,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*)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)))) { + 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; } @@ -1713,58 +1694,98 @@ FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_ return true; } -FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj) +FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj, unsigned length) { FLAC__uint32 i; FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); /* read vendor string */ - FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); - 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*)safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->vendor_string.entry, obj->vendor_string.length)) + if (length >= 8) { + length -= 8; /* vendor string length + num comments entries alone take 8 bytes */ + FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); + if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length)) return false; /* read_callback_ sets the state for us */ - obj->vendor_string.entry[obj->vendor_string.length] = '\0'; - } - else - obj->vendor_string.entry = 0; + if (obj->vendor_string.length > 0) { + if (length < obj->vendor_string.length) { + obj->vendor_string.length = 0; + obj->vendor_string.entry = 0; + goto skip; + } + else + length -= obj->vendor_string.length; + 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; + } + if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->vendor_string.entry, obj->vendor_string.length)) + return false; /* read_callback_ sets the state for us */ + obj->vendor_string.entry[obj->vendor_string.length] = '\0'; + } + else + obj->vendor_string.entry = 0; - /* read num comments */ - FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN == 32); - if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->num_comments)) - return false; /* read_callback_ sets the state for us */ + /* read num comments */ + FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN == 32); + if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->num_comments)) + return false; /* read_callback_ sets the state for us */ - /* read comments */ - if(obj->num_comments > 0) { - if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)safe_malloc_mul_2op_(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + /* read comments */ + if (obj->num_comments > 100000) { + /* Possibly malicious file. */ + obj->num_comments = 0; return false; } - for(i = 0; i < obj->num_comments; i++) { - FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); - 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*)safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; + if (obj->num_comments > 0) { + 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; + } + for (i = 0; i < obj->num_comments; i++) { + /* Initialize here just to make sure. */ + obj->comments[i].length = 0; + obj->comments[i].entry = 0; + + FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); + if (length < 4) { + obj->num_comments = i; + goto skip; } - if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->comments[i].entry, obj->comments[i].length)) + else + length -= 4; + if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length)) return false; /* read_callback_ sets the state for us */ - obj->comments[i].entry[obj->comments[i].length] = '\0'; + if (obj->comments[i].length > 0) { + if (length < obj->comments[i].length) { + obj->num_comments = i; + goto skip; + } + else + length -= obj->comments[i].length; + 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; + } + memset (obj->comments[i].entry, 0, obj->comments[i].length) ; + if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->comments[i].entry, obj->comments[i].length)) { + obj->num_comments = i; + goto skip; + } + obj->comments[i].entry[obj->comments[i].length] = '\0'; + } + else + obj->comments[i].entry = 0; } - else - obj->comments[i].entry = 0; } + else + obj->comments = 0; } - else { - obj->comments = 0; + + skip: + if (length > 0) { + /* This will only happen on files with invalid data in comments */ + if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length)) + return false; /* read_callback_ sets the state for us */ } return true; @@ -1797,7 +1818,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*)safe_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; } @@ -1830,18 +1851,18 @@ 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*)safe_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; } for(j = 0; j < track->num_indices; j++) { - FLAC__StreamMetadata_CueSheet_Index *index = &track->indices[j]; - if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &index->offset, FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN)) + FLAC__StreamMetadata_CueSheet_Index *indx = &track->indices[j]; + if(!FLAC__bitreader_read_raw_uint64(decoder->private_->input, &indx->offset, FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN)) return false; /* read_callback_ sets the state for us */ if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN)) return false; /* read_callback_ sets the state for us */ - index->number = (FLAC__byte)x; + indx->number = (FLAC__byte)x; if(!FLAC__bitreader_skip_bits_no_crc(decoder->private_->input, FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN)) return false; /* read_callback_ sets the state for us */ @@ -1867,7 +1888,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*)safe_malloc_add_2op_(x, /*+*/1))) { + if(0 == (obj->mime_type = safe_malloc_add_2op_(x, /*+*/1))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1880,7 +1901,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*)safe_malloc_add_2op_(x, /*+*/1))) { + if(0 == (obj->description = safe_malloc_add_2op_(x, /*+*/1))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1909,7 +1930,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*)safe_malloc_(obj->data_length))) { + if(0 == (obj->data = safe_malloc_(obj->data_length))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; } @@ -1983,7 +2004,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; @@ -2679,12 +2700,8 @@ FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, un if( (FLAC__uint64)order * ((((FLAC__uint64)1)<<bps)-1) * ((1<<subframe->qlp_coeff_precision)-1) < (((FLAC__uint64)-1) << 32) ) */ if(bps + subframe->qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32) - if(bps <= 16 && subframe->qlp_coeff_precision <= 16) { - if(order <= 8) - decoder->private_->local_lpc_restore_signal_16bit_order8(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); - else - decoder->private_->local_lpc_restore_signal_16bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); - } + if(bps <= 16 && subframe->qlp_coeff_precision <= 16) + decoder->private_->local_lpc_restore_signal_16bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); else decoder->private_->local_lpc_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); else @@ -2743,7 +2760,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; } @@ -2756,7 +2773,7 @@ FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigne if(rice_parameter < pesc) { partitioned_rice_contents->raw_bits[partition] = 0; u = (partition_order == 0 || partition > 0)? partition_samples : partition_samples - predictor_order; - if(!decoder->private_->local_bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter)) + if(!FLAC__bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter)) return false; /* read_callback_ sets the state for us */ sample += u; } @@ -2959,12 +2976,10 @@ FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder */ if(!decoder->private_->has_stream_info) decoder->private_->do_md5_checking = false; -#ifndef FLAC__NO_MD5 if(decoder->private_->do_md5_checking) { if(!FLAC__MD5Accumulate(&decoder->private_->md5context, buffer, frame->header.channels, frame->header.blocksize, (frame->header.bits_per_sample+7) / 8)) return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } -#endif return decoder->private_->write_callback(decoder, frame, buffer, decoder->private_->client_data); } } @@ -3100,12 +3115,7 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s return false; } #ifndef FLAC__INTEGER_ONLY_LIBRARY -#if defined _MSC_VER || defined __MINGW32__ - /* with VC++ you have to spoon feed it the casting */ - pos = (FLAC__int64)lower_bound + (FLAC__int64)((FLAC__double)(FLAC__int64)(target_sample - lower_bound_sample) / (FLAC__double)(FLAC__int64)(upper_bound_sample - lower_bound_sample) * (FLAC__double)(FLAC__int64)(upper_bound - lower_bound)) - approx_bytes_per_frame; -#else pos = (FLAC__int64)lower_bound + (FLAC__int64)((FLAC__double)(target_sample - lower_bound_sample) / (FLAC__double)(upper_bound_sample - lower_bound_sample) * (FLAC__double)(upper_bound - lower_bound)) - approx_bytes_per_frame; -#endif #else /* a little less accurate: */ if(upper_bound - lower_bound < 0xffffffff) @@ -3157,11 +3167,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; @@ -3201,7 +3211,7 @@ FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint 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. @@ -3229,12 +3239,7 @@ FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint } else { #ifndef FLAC__INTEGER_ONLY_LIBRARY -#if defined _MSC_VER || defined __MINGW32__ - /* with MSVC you have to spoon feed it the casting */ - pos = (FLAC__uint64)((FLAC__double)(FLAC__int64)(target_sample - left_sample) / (FLAC__double)(FLAC__int64)(right_sample - left_sample) * (FLAC__double)(FLAC__int64)(right_pos - left_pos)); -#else pos = (FLAC__uint64)((FLAC__double)(target_sample - left_sample) / (FLAC__double)(right_sample - left_sample) * (FLAC__double)(right_pos - left_pos)); -#endif #else /* a little less accurate: */ if ((target_sample-left_sample <= 0xffffffff) && (right_pos-left_pos <= 0xffffffff)) @@ -3351,7 +3356,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; @@ -3359,7 +3364,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) @@ -3374,12 +3379,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; |