From 8c93269e420735f41363e75f8ee4c4e7b3ec49a7 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 3 Nov 2012 05:37:18 +0100 Subject: [PATCH] asfdec: correctly parse payload extensions Signed-off-by: Michael Niedermayer --- libavformat/asfdec.c | 50 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index 4ad5c2dfd7..30e2a50b43 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -926,13 +926,16 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb) */ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){ ASFContext *asf = s->priv_data; + ASFStream *asfst; int rsize = 1; int num = avio_r8(pb); + int i; int64_t ts0, ts1 av_unused; asf->packet_segments--; asf->packet_key_frame = num >> 7; asf->stream_index = asf->asfid2avid[num & 0x7f]; + asfst = &asf->streams[num & 0x7f]; // sequence should be ignored! DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0); DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0); @@ -945,23 +948,48 @@ static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){ return AVERROR_INVALIDDATA; } if (asf->packet_replic_size >= 8) { + int64_t end = avio_tell(pb) + asf->packet_replic_size; asf->packet_obj_size = avio_rl32(pb); if(asf->packet_obj_size >= (1<<24) || asf->packet_obj_size <= 0){ av_log(s, AV_LOG_ERROR, "packet_obj_size invalid\n"); return AVERROR_INVALIDDATA; } asf->packet_frag_timestamp = avio_rl32(pb); // timestamp - if(asf->packet_replic_size >= 8+38+4){ - avio_skip(pb, 10); - ts0= avio_rl64(pb); - ts1= avio_rl64(pb); - avio_skip(pb, 12); - avio_rl32(pb); - avio_skip(pb, asf->packet_replic_size - 8 - 38 - 4); - if(ts0!= -1) asf->packet_frag_timestamp= ts0/10000; - else asf->packet_frag_timestamp= AV_NOPTS_VALUE; - }else - avio_skip(pb, asf->packet_replic_size - 8); + + for (i=0; ipayload_ext_ct; i++) { + ASFPayload *p = &asfst->payload[i]; + int size = p->size; + int64_t payend; + if(size == 0xFFFF) + size = avio_rl16(pb); + payend = avio_tell(pb) + size; + if (payend > end) { + av_log(s, AV_LOG_ERROR, "too long payload\n"); + break; + } + switch(p->type) { + case 0x50: +// duration = avio_rl16(pb); + break; + case 0x2A: + avio_skip(pb, 8); + ts0= avio_rl64(pb); + ts1= avio_rl64(pb); + if(ts0!= -1) asf->packet_frag_timestamp= ts0/10000; + else asf->packet_frag_timestamp= AV_NOPTS_VALUE; + break; + case 0x5B: + case 0xB7: + case 0xCC: + case 0xC0: + case 0xA0: + //unknown + break; + } + avio_seek(pb, payend, SEEK_SET); + } + + avio_seek(pb, end, SEEK_SET); rsize += asf->packet_replic_size; // FIXME - check validity } else if (asf->packet_replic_size==1){ // multipacket - frag_offset is beginning timestamp