1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-26 19:01:44 +02:00

Merge commit 'aa3c77998404cc32233cb76e961ca27db8565459'

* commit 'aa3c77998404cc32233cb76e961ca27db8565459':
  lavf: sanity check size in av_get/append_packet().

Conflicts:
	libavformat/utils.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2013-03-16 15:12:21 +01:00
commit e066fb54cb

View File

@ -251,6 +251,9 @@ AVInputFormat *av_find_input_format(const char *short_name)
return NULL;
}
/* an arbitrarily chosen "sane" max packet size -- 50M */
#define SANE_CHUNK_SIZE (50000000)
int ffio_limit(AVIOContext *s, int size)
{
if(s->maxsize>=0){
@ -271,43 +274,77 @@ int ffio_limit(AVIOContext *s, int size)
return size;
}
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
/*
* Read the data in sane-sized chunks and append to pkt.
* Return the number of bytes read or an error.
*/
static int append_packet_chunked(AVIOContext *s, AVPacket *pkt, int size)
{
int ret;
int orig_size = size;
size= ffio_limit(s, size);
int64_t chunk_size = size;
int orig_pos = pkt->pos; // av_grow_packet might reset pos
int orig_size = pkt->size;
int ret = 0;
ret= av_new_packet(pkt, size);
do {
int prev_size = pkt->size;
int read_size;
if(ret<0)
return ret;
/*
* When the caller requests a lot of data, limit it to the amount left
* in file or SANE_CHUNK_SIZE when it is not known
*/
#if 0
if (size > SANE_CHUNK_SIZE) {
int64_t filesize = avio_size(s) - avio_tell(s);
chunk_size = FFMAX(filesize, SANE_CHUNK_SIZE);
}
read_size = FFMIN(size, chunk_size);
#else
read_size = size;
if (read_size > SANE_CHUNK_SIZE/10) {
read_size = ffio_limit(s, read_size);
// If filesize/maxsize is unknown, limit to SANE_CHUNK_SIZE
if (s->maxsize < 0)
read_size = FFMIN(read_size, SANE_CHUNK_SIZE);
}
#endif
pkt->pos= avio_tell(s);
ret = av_grow_packet(pkt, read_size);
if (ret < 0)
break;
ret= avio_read(s, pkt->data, size);
if(ret<=0)
av_free_packet(pkt);
else
av_shrink_packet(pkt, ret);
if (pkt->size < orig_size)
ret = avio_read(s, pkt->data + prev_size, read_size);
if (ret != read_size) {
av_shrink_packet(pkt, prev_size + FFMAX(ret, 0));
break;
}
size -= read_size;
} while (size > 0);
if (size > 0)
pkt->flags |= AV_PKT_FLAG_CORRUPT;
return ret;
pkt->pos = orig_pos;
if (!pkt->size)
av_free_packet(pkt);
return pkt->size > orig_size ? pkt->size - orig_size : ret;
}
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
{
av_init_packet(pkt);
pkt->data = NULL;
pkt->size = 0;
pkt->pos = avio_tell(s);
return append_packet_chunked(s, pkt, size);
}
int av_append_packet(AVIOContext *s, AVPacket *pkt, int size)
{
int ret;
int old_size;
if (!pkt->size)
return av_get_packet(s, pkt, size);
old_size = pkt->size;
ret = av_grow_packet(pkt, size);
if (ret < 0)
return ret;
ret = avio_read(s, pkt->data + old_size, size);
av_shrink_packet(pkt, old_size + FFMAX(ret, 0));
return ret;
return append_packet_chunked(s, pkt, size);
}