Mercurial > libavformat.hg
comparison aiff.c @ 5279:0a917464c1dc libavformat
Do not read data past the end of the SSND chunk in the AIFF demuxer.
Fixes Issue 1455.
author | jbr |
---|---|
date | Tue, 13 Oct 2009 00:19:34 +0000 |
parents | 6a23d76cc72c |
children | 63c52dca959b |
comparison
equal
deleted
inserted
replaced
5278:5a730ddcd8fa | 5279:0a917464c1dc |
---|---|
44 }; | 44 }; |
45 | 45 |
46 #define AIFF 0 | 46 #define AIFF 0 |
47 #define AIFF_C_VERSION1 0xA2805140 | 47 #define AIFF_C_VERSION1 0xA2805140 |
48 | 48 |
49 typedef struct { | |
50 int64_t data_end; | |
51 } AIFFInputContext; | |
52 | |
49 static enum CodecID aiff_codec_get_id(int bps) | 53 static enum CodecID aiff_codec_get_id(int bps) |
50 { | 54 { |
51 if (bps <= 8) | 55 if (bps <= 8) |
52 return CODEC_ID_PCM_S8; | 56 return CODEC_ID_PCM_S8; |
53 if (bps <= 16) | 57 if (bps <= 16) |
312 int64_t offset = 0; | 316 int64_t offset = 0; |
313 uint32_t tag; | 317 uint32_t tag; |
314 unsigned version = AIFF_C_VERSION1; | 318 unsigned version = AIFF_C_VERSION1; |
315 ByteIOContext *pb = s->pb; | 319 ByteIOContext *pb = s->pb; |
316 AVStream * st; | 320 AVStream * st; |
321 AIFFInputContext *aiff = s->priv_data; | |
317 | 322 |
318 /* check FORM header */ | 323 /* check FORM header */ |
319 filesize = get_tag(pb, &tag); | 324 filesize = get_tag(pb, &tag); |
320 if (filesize < 0 || tag != MKTAG('F', 'O', 'R', 'M')) | 325 if (filesize < 0 || tag != MKTAG('F', 'O', 'R', 'M')) |
321 return AVERROR_INVALIDDATA; | 326 return AVERROR_INVALIDDATA; |
364 break; | 369 break; |
365 case MKTAG('A', 'N', 'N', 'O'): /* Annotation chunk */ | 370 case MKTAG('A', 'N', 'N', 'O'): /* Annotation chunk */ |
366 get_meta(s, "comment" , size); | 371 get_meta(s, "comment" , size); |
367 break; | 372 break; |
368 case MKTAG('S', 'S', 'N', 'D'): /* Sampled sound chunk */ | 373 case MKTAG('S', 'S', 'N', 'D'): /* Sampled sound chunk */ |
374 aiff->data_end = url_ftell(pb) + size; | |
369 offset = get_be32(pb); /* Offset of sound data */ | 375 offset = get_be32(pb); /* Offset of sound data */ |
370 get_be32(pb); /* BlockSize... don't care */ | 376 get_be32(pb); /* BlockSize... don't care */ |
371 offset += url_ftell(pb); /* Compute absolute data offset */ | 377 offset += url_ftell(pb); /* Compute absolute data offset */ |
372 if (st->codec->block_align) /* Assume COMM already parsed */ | 378 if (st->codec->block_align) /* Assume COMM already parsed */ |
373 goto got_sound; | 379 goto got_sound; |
418 | 424 |
419 static int aiff_read_packet(AVFormatContext *s, | 425 static int aiff_read_packet(AVFormatContext *s, |
420 AVPacket *pkt) | 426 AVPacket *pkt) |
421 { | 427 { |
422 AVStream *st = s->streams[0]; | 428 AVStream *st = s->streams[0]; |
429 AIFFInputContext *aiff = s->priv_data; | |
430 int64_t max_size; | |
423 int res; | 431 int res; |
424 | 432 |
433 /* calculate size of remaining data */ | |
434 max_size = aiff->data_end - url_ftell(s->pb); | |
435 if (max_size <= 0) | |
436 return AVERROR_EOF; | |
437 | |
425 /* Now for that packet */ | 438 /* Now for that packet */ |
426 res = av_get_packet(s->pb, pkt, (MAX_SIZE / st->codec->block_align) * st->codec->block_align); | 439 max_size = FFMIN(max_size, (MAX_SIZE / st->codec->block_align) * st->codec->block_align); |
440 res = av_get_packet(s->pb, pkt, max_size); | |
427 if (res < 0) | 441 if (res < 0) |
428 return res; | 442 return res; |
429 | 443 |
430 /* Only one stream in an AIFF file */ | 444 /* Only one stream in an AIFF file */ |
431 pkt->stream_index = 0; | 445 pkt->stream_index = 0; |
434 | 448 |
435 #if CONFIG_AIFF_DEMUXER | 449 #if CONFIG_AIFF_DEMUXER |
436 AVInputFormat aiff_demuxer = { | 450 AVInputFormat aiff_demuxer = { |
437 "aiff", | 451 "aiff", |
438 NULL_IF_CONFIG_SMALL("Audio IFF"), | 452 NULL_IF_CONFIG_SMALL("Audio IFF"), |
439 0, | 453 sizeof(AIFFInputContext), |
440 aiff_probe, | 454 aiff_probe, |
441 aiff_read_header, | 455 aiff_read_header, |
442 aiff_read_packet, | 456 aiff_read_packet, |
443 NULL, | 457 NULL, |
444 pcm_read_seek, | 458 pcm_read_seek, |