ff_read_timestamp: check stream_index before using it as array index
[ffmpeg.git] / libavformat / icodec.c
index e539b02..37909aa 100644 (file)
@@ -49,7 +49,7 @@ static int probe(AVProbeData *p)
     return 0;
 }
 
-static int read_header(AVFormatContext *s, AVFormatParameters *ap)
+static int read_header(AVFormatContext *s)
 {
     IcoDemuxContext *ico = s->priv_data;
     AVIOContext *pb = s->pb;
@@ -64,6 +64,7 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
 
     for (i = 0; i < ico->nb_images; i++) {
         AVStream *st;
+        int tmp;
 
         if (avio_seek(pb, 6 + i * 16, SEEK_SET) < 0)
             break;
@@ -76,11 +77,10 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
         st->codec->width      = avio_r8(pb);
         st->codec->height     = avio_r8(pb);
         ico->images[i].nb_pal = avio_r8(pb);
+        if (ico->images[i].nb_pal == 255)
+            ico->images[i].nb_pal = 0;
 
-        avio_skip(pb, 3);
-        st->codec->bits_per_coded_sample = avio_rl16(pb);
-        if (st->codec->bits_per_coded_sample <= 8 && !ico->images[i].nb_pal)
-            ico->images[i].nb_pal = 1 << st->codec->bits_per_coded_sample;
+        avio_skip(pb, 5);
 
         ico->images[i].size   = avio_rl32(pb);
         ico->images[i].offset = avio_rl32(pb);
@@ -90,16 +90,20 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap)
 
         switch(avio_rl32(pb)) {
         case MKTAG(0x89, 'P', 'N', 'G'):
-            st->codec->codec_id = CODEC_ID_PNG;
+            st->codec->codec_id = AV_CODEC_ID_PNG;
             st->codec->width    = 0;
             st->codec->height   = 0;
             break;
         case 40:
-            st->codec->codec_id = CODEC_ID_BMP;
-            if (!st->codec->width || !st->codec->height) {
-                st->codec->width  = avio_rl32(pb);
-                st->codec->height = avio_rl32(pb) / 2;
-            }
+            if (ico->images[i].size < 40)
+                return AVERROR_INVALIDDATA;
+            st->codec->codec_id = AV_CODEC_ID_BMP;
+            tmp = avio_rl32(pb);
+            if (tmp)
+                st->codec->width = tmp;
+            tmp = avio_rl32(pb);
+            if (tmp)
+                st->codec->height = tmp / 2;
             break;
         default:
             av_log_ask_for_sample(s, "unsupported codec\n");
@@ -115,6 +119,7 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
     IcoDemuxContext *ico = s->priv_data;
     IcoImage *image;
     AVIOContext *pb = s->pb;
+    AVStream *st = s->streams[0];
     int ret;
 
     if (ico->current_image >= ico->nb_images)
@@ -125,7 +130,7 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
     if ((ret = avio_seek(pb, image->offset, SEEK_SET)) < 0)
         return ret;
 
-    if (s->streams[ico->current_image]->codec->codec_id == CODEC_ID_PNG) {
+    if (s->streams[ico->current_image]->codec->codec_id == AV_CODEC_ID_PNG) {
         if ((ret = av_get_packet(pb, pkt, image->size)) < 0)
             return ret;
     } else {
@@ -140,13 +145,23 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
         bytestream_put_le32(&buf, pkt->size);
         bytestream_put_le16(&buf, 0);
         bytestream_put_le16(&buf, 0);
-        bytestream_put_le32(&buf, 14 + 40 + image->nb_pal * 4);
+        bytestream_put_le32(&buf, 0);
 
         if ((ret = avio_read(pb, buf, image->size)) < 0)
             return ret;
 
+        st->codec->bits_per_coded_sample = AV_RL16(buf + 14);
+
+        if (AV_RL32(buf + 32))
+            image->nb_pal = AV_RL32(buf + 32);
+
+        if (st->codec->bits_per_coded_sample <= 8 && !image->nb_pal) {
+            image->nb_pal = 1 << st->codec->bits_per_coded_sample;
+            AV_WL32(buf + 32, image->nb_pal);
+        }
+
+        AV_WL32(buf - 4, 14 + 40 + image->nb_pal * 4);
         AV_WL32(buf + 8, AV_RL32(buf + 8) / 2);
-        AV_WL32(buf + 32, image->nb_pal);
     }
 
     pkt->stream_index = ico->current_image++;