src/libFLAC/stream_decoder.c : Fix buffer read overflow.
[platform/upstream/flac.git] / src / libFLAC / stream_decoder.c
index ec728ab..6bc6407 100644 (file)
@@ -1,5 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
- * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009  Josh Coalson
+ * Copyright (C) 2000-2009  Josh Coalson
+ * Copyright (C) 2011-2013  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #  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() */
@@ -78,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' };
 
 /***********************************************************************
  *
@@ -614,7 +607,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;
@@ -1372,6 +1365,10 @@ FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder)
                        id = 0;
                        continue;
                }
+
+               if(id >= 3)
+                       return false;
+
                if(x == ID3V2_TAG_[id]) {
                        id++;
                        i = 0;
@@ -1815,13 +1812,13 @@ FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMet
                                        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 */
@@ -3329,7 +3326,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;
@@ -3337,7 +3334,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)
@@ -3352,12 +3349,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;