Merge commit '710b0e27025948b7511821c2f888ff2d74a59e14'
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 12 Sep 2013 09:38:55 +0000 (11:38 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 12 Sep 2013 09:39:18 +0000 (11:39 +0200)
* commit '710b0e27025948b7511821c2f888ff2d74a59e14':
  smacker: Avoid integer overflow when allocating packets

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavformat/smacker.c

diff --combined libavformat/smacker.c
@@@ -2,20 -2,20 +2,20 @@@
   * Smacker demuxer
   * Copyright (c) 2006 Konstantin Shishkov
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -110,7 -110,7 +110,7 @@@ static int smacker_read_header(AVFormat
      /* read and check header */
      smk->magic = avio_rl32(pb);
      if (smk->magic != MKTAG('S', 'M', 'K', '2') && smk->magic != MKTAG('S', 'M', 'K', '4'))
 -        return -1;
 +        return AVERROR_INVALIDDATA;
      smk->width = avio_rl32(pb);
      smk->height = avio_rl32(pb);
      smk->frames = avio_rl32(pb);
  
      if(smk->treesize >= UINT_MAX/4){ // smk->treesize + 16 must not overflow (this check is probably redundant)
          av_log(s, AV_LOG_ERROR, "treesize too large\n");
 -        return -1;
 +        return AVERROR_INVALIDDATA;
      }
  
  //FIXME remove extradata "rebuilding"
      /* setup data */
      if(smk->frames > 0xFFFFFF) {
          av_log(s, AV_LOG_ERROR, "Too many frames: %i\n", smk->frames);
 -        return -1;
 +        return AVERROR_INVALIDDATA;
      }
      smk->frm_size = av_malloc(smk->frames * 4);
      smk->frm_flags = av_malloc(smk->frames);
      /* init video codec */
      st = avformat_new_stream(s, NULL);
      if (!st)
 -        return -1;
 +        return AVERROR(ENOMEM);
      smk->videoindex = st->index;
      st->codec->width = smk->width;
      st->codec->height = smk->height;
          smk->indexes[i] = -1;
          if (smk->rates[i]) {
              ast[i] = avformat_new_stream(s, NULL);
 +            if (!ast[i])
 +                return AVERROR(ENOMEM);
              smk->indexes[i] = ast[i]->index;
              ast[i]->codec->codec_type = AVMEDIA_TYPE_AUDIO;
              if (smk->aflags[i] & SMK_AUD_BINKAUD) {
          av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16);
          av_free(smk->frm_size);
          av_free(smk->frm_flags);
 -        return -1;
 +        return AVERROR(ENOMEM);
      }
      ret = avio_read(pb, st->codec->extradata + 16, st->codec->extradata_size - 16);
      if(ret != st->codec->extradata_size - 16){
@@@ -248,7 -246,7 +248,7 @@@ static int smacker_read_packet(AVFormat
      int frame_size = 0;
      int palchange = 0;
  
 -    if (s->pb->eof_reached || smk->cur_frame >= smk->frames)
 +    if (url_feof(s->pb) || smk->cur_frame >= smk->frames)
          return AVERROR_EOF;
  
      /* if we demuxed all streams, pass another frame */
              memcpy(oldpal, pal, 768);
              size = avio_r8(s->pb);
              size = size * 4 - 1;
 +            if(size + 1 > frame_size)
 +                return AVERROR_INVALIDDATA;
              frame_size -= size;
              frame_size--;
              sz = 0;
                  uint8_t *tmpbuf;
  
                  size = avio_rl32(s->pb) - 4;
 -                if (!size || size > frame_size) {
 +                if (!size || size + 4L > frame_size) {
                      av_log(s, AV_LOG_ERROR, "Invalid audio part size\n");
                      return AVERROR_INVALIDDATA;
                  }
              }
              flags >>= 1;
          }
-         if (frame_size < 0)
+         if (frame_size < 0 || frame_size >= INT_MAX/2)
              return AVERROR_INVALIDDATA;
          if (av_new_packet(pkt, frame_size + 769))
              return AVERROR(ENOMEM);
@@@ -378,7 -374,7 +378,7 @@@ static int smacker_read_close(AVFormatC
  
  AVInputFormat ff_smacker_demuxer = {
      .name           = "smk",
 -    .long_name      = NULL_IF_CONFIG_SMALL("Smacker video"),
 +    .long_name      = NULL_IF_CONFIG_SMALL("Smacker"),
      .priv_data_size = sizeof(SmackerContext),
      .read_probe     = smacker_probe,
      .read_header    = smacker_read_header,