static void align_position(AVIOContext *pb, int64_t offset, uint64_t size)
{
- if (avio_tell(pb) != offset + size)
+ if (size < INT64_MAX - offset && avio_tell(pb) != offset + size)
avio_seek(pb, offset + size, SEEK_SET);
}
uint64_t size = avio_rl64(pb);
int ret;
+ if (size > INT64_MAX)
+ return AVERROR_INVALIDDATA;
+
if (asf->is_header)
asf->unknown_size = size;
asf->is_header = 0;
if ((ret = detect_unknown_subobject(s, asf->unknown_offset,
asf->unknown_size)) < 0)
return ret;
- } else
+ } else {
+ if (size < 24) {
+ av_log(s, AV_LOG_ERROR, "Too small size %"PRIu64" (< 24).\n", size);
+ return AVERROR_INVALIDDATA;
+ }
avio_skip(pb, size - 24);
+ }
return 0;
}
return 0;
}
-static int asf_read_value(AVFormatContext *s, const uint8_t *name, uint16_t name_len,
+static int asf_read_value(AVFormatContext *s, const uint8_t *name,
uint16_t val_len, int type, AVDictionary **met)
{
int ret;
}
static int asf_set_metadata(AVFormatContext *s, const uint8_t *name,
- uint16_t name_len, int type, AVDictionary **met)
+ int type, AVDictionary **met)
{
AVIOContext *pb = s->pb;
uint64_t value;
if (val_len) {
switch (type) {
case ASF_UNICODE:
- asf_read_value(s, name, name_len, val_len, type, met);
+ asf_read_value(s, name, val_len, type, met);
break;
case ASF_BYTE_ARRAY:
if (!strcmp(name, "WM/Picture")) // handle cover art
else if (!strcmp(name, "ID3")) // handle ID3 tag
get_id3_tag(s, val_len);
else
- asf_read_value(s, name, name_len, val_len, type, met);
+ asf_read_value(s, name, val_len, type, met);
break;
case ASF_GUID:
ff_get_guid(s->pb, &guid);
break;
default:
- if ((ret = asf_set_metadata(s, name, name_len, type, met)) < 0)
+ if ((ret = asf_set_metadata(s, name, type, met)) < 0)
return ret;
break;
}
uint64_t interval; // index entry time interval in 100 ns units, usually it's 1s
uint32_t pkt_num, nb_entries;
int32_t prev_pkt_num = -1;
- int i;
+ int i, ret;
uint64_t size = avio_rl64(pb);
// simple index objects should be ordered by stream number, this loop tries to find
nb_entries = avio_rl32(pb);
for (i = 0; i < nb_entries; i++) {
pkt_num = avio_rl32(pb);
- avio_skip(pb, 2);
+ ret = avio_skip(pb, 2);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "Skipping failed in asf_read_simple_index.\n");
+ return ret;
+ }
if (prev_pkt_num != pkt_num) {
av_add_index_entry(st, asf->first_packet_offset + asf->packet_size *
pkt_num, av_rescale(interval, i, 10000),
{
ASFContext *asf = s->priv_data;
AVIOContext *pb = s->pb;
- int ret;
+ int ret, data_size;
if (!asf_pkt->data_size) {
- asf_pkt->data_size = asf_pkt->size_left = avio_rl32(pb); // read media object size
- if (asf_pkt->data_size <= 0)
+ data_size = avio_rl32(pb); // read media object size
+ if (data_size <= 0)
return AVERROR_INVALIDDATA;
- if ((ret = av_new_packet(&asf_pkt->avpkt, asf_pkt->data_size)) < 0)
+ if ((ret = av_new_packet(&asf_pkt->avpkt, data_size)) < 0)
return ret;
+ asf_pkt->data_size = asf_pkt->size_left = data_size;
} else
avio_skip(pb, 4); // reading of media object size is already done
asf_pkt->dts = avio_rl32(pb); // read presentation time
return 0;
}
-static int asf_read_single_payload(AVFormatContext *s, AVPacket *pkt,
- ASFPacket *asf_pkt)
+static int asf_read_single_payload(AVFormatContext *s, ASFPacket *asf_pkt)
{
ASFContext *asf = s->priv_data;
AVIOContext *pb = s->pb;
int64_t offset;
uint64_t size;
unsigned char *p;
- int ret;
+ int ret, data_size;
if (!asf_pkt->data_size) {
- asf_pkt->data_size = asf_pkt->size_left = avio_rl32(pb); // read media object size
- if (asf_pkt->data_size <= 0)
+ data_size = avio_rl32(pb); // read media object size
+ if (data_size <= 0)
return AVERROR_EOF;
- if ((ret = av_new_packet(&asf_pkt->avpkt, asf_pkt->data_size)) < 0)
+ if ((ret = av_new_packet(&asf_pkt->avpkt, data_size)) < 0)
return ret;
+ asf_pkt->data_size = asf_pkt->size_left = data_size;
} else
avio_skip(pb, 4); // skip media object size
asf_pkt->dts = avio_rl32(pb); // read presentation time
}
if (!asf_pkt) {
if (asf->packet_offset + asf->packet_size <= asf->data_offset + asf->data_size) {
+ if (!asf->packet_size) {
+ av_log(s, AV_LOG_ERROR, "Invalid packet size 0.\n");
+ return AVERROR_INVALIDDATA;
+ }
avio_seek(pb, asf->packet_offset + asf->packet_size, SEEK_SET);
av_log(s, AV_LOG_WARNING, "Skipping the stream with the invalid stream index %d.\n",
asf->stream_index);
if ((ret = asf_read_subpayload(s, pkt, 1)) < 0)
return ret;
} else {
- if ((ret = asf_read_single_payload(s, pkt, asf_pkt)) < 0)
+ if ((ret = asf_read_single_payload(s, asf_pkt)) < 0)
return ret;
}
} else {
while (!pb->eof_reached) {
if (asf->state == PARSE_PACKET_HEADER) {
asf_read_packet_header(s);
+ if (pb->eof_reached)
+ break;
if (!asf->nb_mult_left)
asf->state = READ_SINGLE;
else