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,