fix bug in code that skips id3v2 tags at the front of a file; false positives could...
[platform/upstream/flac.git] / src / libFLAC / stream_decoder.c
index 1cb233c..f1f5fc8 100644 (file)
 #include <sys/stat.h> /* for stat() */
 #include <sys/types.h> /* for off_t */
 #if defined _MSC_VER || defined __MINGW32__
-/*@@@ [2G limit] hacks for MSVC6 */
+#if _MSC_VER <= 1200 /* @@@ [2G limit] */
 #define fseeko fseek
 #define ftello ftell
 #endif
+#endif
 #include "FLAC/assert.h"
 #include "protected/stream_decoder.h"
 #include "private/bitbuffer.h"
@@ -63,8 +64,6 @@
 #include "private/md5.h"
 #include "private/memory.h"
 
-#undef OLD_STAT_WAY /*@@@@@@ old way of keeping the filename and using stat(); remove remnants once we know this works */
-
 #ifdef max
 #undef max
 #endif
@@ -101,6 +100,7 @@ static FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__
 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_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);
 static FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder);
 static FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FLAC__bool do_full_decode);
@@ -147,9 +147,6 @@ typedef struct FLAC__StreamDecoderPrivate {
        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[]);
        void *client_data;
        FILE *file; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */
-#ifdef OLD_STAT_WAY
-       char *filename; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */
-#endif
        FLAC__BitBuffer *input;
        FLAC__int32 *output[FLAC__MAX_CHANNELS];
        FLAC__int32 *residual[FLAC__MAX_CHANNELS]; /* WATCHOUT: these are the aligned pointers; the real pointers that should be free()'d are residual_unaligned[] below */
@@ -467,19 +464,6 @@ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_FILE(
 
        decoder->private_->file = file;
 
-#ifdef OLD_STAT_WAY
-       if(0 != decoder->private_->filename) {
-               free(decoder->private_->filename);
-               decoder->private_->filename = 0;
-       }
-       if(filename) {
-               if(0 == (decoder->private_->filename = strdup(filename))) {
-                       decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
-                       return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR;
-               }
-       }
-#endif
-
        return FLAC__stream_decoder_init_stream(
                decoder,
                file_read_callback_,
@@ -523,19 +507,6 @@ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file(
        if(0 == file)
                return FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE;
 
-#ifdef OLD_STAT_WAY
-       if(0 != decoder->private_->filename) {
-               free(decoder->private_->filename);
-               decoder->private_->filename = 0;
-       }
-       if(filename) {
-               if(0 == (decoder->private_->filename = strdup(filename))) {
-                       decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
-                       return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR;
-               }
-       }
-#endif
-
        return FLAC__stream_decoder_init_FILE(decoder, file, write_callback, metadata_callback, error_callback, client_data);
 }
 
@@ -587,13 +558,6 @@ FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder)
                decoder->private_->file = 0;
        }
 
-#ifdef OLD_STAT_WAY
-       if(0 != decoder->private_->filename) {
-               free(decoder->private_->filename);
-               decoder->private_->filename = 0;
-       }
-#endif
-
        if(decoder->private_->do_md5_checking) {
                if(memcmp(decoder->private_->stream_info.data.stream_info.md5sum, decoder->private_->computed_md5sum, 16))
                        md5_failed = true;
@@ -1096,9 +1060,6 @@ void set_defaults_(FLAC__StreamDecoder *decoder)
        decoder->private_->metadata_callback = 0;
        decoder->private_->error_callback = 0;
        decoder->private_->client_data = 0;
-#ifdef OLD_STAT_WAY
-       decoder->private_->filename = 0;
-#endif
 
        memset(decoder->private_->metadata_filter, 0, sizeof(decoder->private_->metadata_filter));
        decoder->private_->metadata_filter[FLAC__METADATA_TYPE_STREAMINFO] = true;
@@ -1223,6 +1184,7 @@ FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder)
                        }
                        continue;
                }
+               id = 0;
                if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
                        decoder->private_->header_warmup[0] = (FLAC__byte)x;
                        if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &x, 8, read_callback_, decoder))
@@ -1337,6 +1299,10 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
                                        if(!read_metadata_cuesheet_(decoder, &block.data.cue_sheet))
                                                return false;
                                        break;
+                               case FLAC__METADATA_TYPE_PICTURE:
+                                       if(!read_metadata_picture_(decoder, &block.data.picture))
+                                               return false;
+                                       break;
                                case FLAC__METADATA_TYPE_STREAMINFO:
                                case FLAC__METADATA_TYPE_SEEKTABLE:
                                        FLAC__ASSERT(0);
@@ -1383,6 +1349,14 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
                                        if(0 != block.data.cue_sheet.tracks)
                                                free(block.data.cue_sheet.tracks);
                                        break;
+                               case FLAC__METADATA_TYPE_PICTURE:
+                                       if(0 != block.data.picture.mime_type)
+                                               free(block.data.picture.mime_type);
+                                       if(0 != block.data.picture.description)
+                                               free(block.data.picture.description);
+                                       if(0 != block.data.picture.data)
+                                               free(block.data.picture.data);
+                                       break;
                                case FLAC__METADATA_TYPE_STREAMINFO:
                                case FLAC__METADATA_TYPE_SEEKTABLE:
                                        FLAC__ASSERT(0);
@@ -1657,6 +1631,73 @@ FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMet
        return true;
 }
 
+FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_Picture *obj)
+{
+       FLAC__uint32 len;
+
+       FLAC__ASSERT(FLAC__bitbuffer_is_consumed_byte_aligned(decoder->private_->input));
+
+       /* read type */
+       if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &obj->type, FLAC__STREAM_METADATA_PICTURE_TYPE_LEN, read_callback_, decoder))
+               return false; /* read_callback_ sets the state for us */
+
+       /* read MIME type */
+       if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &len, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN, read_callback_, decoder))
+               return false; /* read_callback_ sets the state for us */
+       if(0 == (obj->mime_type = (char*)malloc(len+1))) {
+               decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
+               return false;
+       }
+       if(len > 0) {
+               if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, (FLAC__byte*)obj->mime_type, len, read_callback_, decoder))
+                       return false; /* read_callback_ sets the state for us */
+       }
+       obj->mime_type[len] = '\0';
+
+       /* read description */
+       if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &len, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN, read_callback_, decoder))
+               return false; /* read_callback_ sets the state for us */
+       if(0 == (obj->description = (FLAC__byte*)malloc(len+1))) {
+               decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
+               return false;
+       }
+       if(len > 0) {
+               if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, obj->description, len, read_callback_, decoder))
+                       return false; /* read_callback_ sets the state for us */
+       }
+       obj->description[len] = '\0';
+
+       /* read width */
+       if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &obj->width, FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN, read_callback_, decoder))
+               return false; /* read_callback_ sets the state for us */
+
+       /* read height */
+       if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &obj->height, FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN, read_callback_, decoder))
+               return false; /* read_callback_ sets the state for us */
+
+       /* read depth */
+       if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &obj->depth, FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN, read_callback_, decoder))
+               return false; /* read_callback_ sets the state for us */
+
+       /* read colors */
+       if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &obj->colors, FLAC__STREAM_METADATA_PICTURE_COLORS_LEN, read_callback_, decoder))
+               return false; /* read_callback_ sets the state for us */
+
+       /* read data */
+       if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &(obj->data_length), FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN, read_callback_, decoder))
+               return false; /* read_callback_ sets the state for us */
+       if(0 == (obj->data = (FLAC__byte*)malloc(obj->data_length))) {
+               decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
+               return false;
+       }
+       if(obj->data_length > 0) {
+               if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, obj->data, obj->data_length, read_callback_, decoder))
+                       return false; /* read_callback_ sets the state for us */
+       }
+
+       return true;
+}
+
 FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder)
 {
        FLAC__uint32 x;
@@ -2892,9 +2933,6 @@ FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder
 
        if(decoder->private_->file == stdin)
                return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
-#ifdef OLD_STAT_WAY
-       else if(0 == decoder->private_->filename || fstat(fileno(decoder->private_->file), &filestats) != 0)
-#endif
        else if(fstat(fileno(decoder->private_->file), &filestats) != 0)
                return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
        else {