Commit ed4932a6 authored by Andreas Cadhalpun's avatar Andreas Cadhalpun

nutdec: fix various memleaks on failure

Reviewed-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
Signed-off-by: 's avatarAndreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
parent 4ae15605
...@@ -203,7 +203,8 @@ static int nut_probe(AVProbeData *p) ...@@ -203,7 +203,8 @@ static int nut_probe(AVProbeData *p)
tmp = ffio_read_varlen(bc); \ tmp = ffio_read_varlen(bc); \
if (!(check)) { \ if (!(check)) { \
av_log(s, AV_LOG_ERROR, "Error " #dst " is (%"PRId64")\n", tmp); \ av_log(s, AV_LOG_ERROR, "Error " #dst " is (%"PRId64")\n", tmp); \
return AVERROR_INVALIDDATA; \ ret = AVERROR_INVALIDDATA; \
goto fail; \
} \ } \
dst = tmp; \ dst = tmp; \
} while (0) } while (0)
...@@ -230,7 +231,7 @@ static int decode_main_header(NUTContext *nut) ...@@ -230,7 +231,7 @@ static int decode_main_header(NUTContext *nut)
AVIOContext *bc = s->pb; AVIOContext *bc = s->pb;
uint64_t tmp, end; uint64_t tmp, end;
unsigned int stream_count; unsigned int stream_count;
int i, j, count; int i, j, count, ret;
int tmp_stream, tmp_mul, tmp_pts, tmp_size, tmp_res, tmp_head_idx; int tmp_stream, tmp_mul, tmp_pts, tmp_size, tmp_res, tmp_head_idx;
end = get_packetheader(nut, bc, 1, MAIN_STARTCODE); end = get_packetheader(nut, bc, 1, MAIN_STARTCODE);
...@@ -264,7 +265,8 @@ static int decode_main_header(NUTContext *nut) ...@@ -264,7 +265,8 @@ static int decode_main_header(NUTContext *nut)
GET_V(nut->time_base[i].den, tmp > 0 && tmp < (1ULL << 31)); GET_V(nut->time_base[i].den, tmp > 0 && tmp < (1ULL << 31));
if (av_gcd(nut->time_base[i].num, nut->time_base[i].den) != 1) { if (av_gcd(nut->time_base[i].num, nut->time_base[i].den) != 1) {
av_log(s, AV_LOG_ERROR, "time base invalid\n"); av_log(s, AV_LOG_ERROR, "time base invalid\n");
return AVERROR_INVALIDDATA; ret = AVERROR_INVALIDDATA;
goto fail;
} }
} }
tmp_pts = 0; tmp_pts = 0;
...@@ -301,18 +303,21 @@ static int decode_main_header(NUTContext *nut) ...@@ -301,18 +303,21 @@ static int decode_main_header(NUTContext *nut)
while (tmp_fields-- > 8) { while (tmp_fields-- > 8) {
if (bc->eof_reached) { if (bc->eof_reached) {
av_log(s, AV_LOG_ERROR, "reached EOF while decoding main header\n"); av_log(s, AV_LOG_ERROR, "reached EOF while decoding main header\n");
return AVERROR_INVALIDDATA; ret = AVERROR_INVALIDDATA;
goto fail;
} }
ffio_read_varlen(bc); ffio_read_varlen(bc);
} }
if (count <= 0 || count > 256 - (i <= 'N') - i) { if (count <= 0 || count > 256 - (i <= 'N') - i) {
av_log(s, AV_LOG_ERROR, "illegal count %d at %d\n", count, i); av_log(s, AV_LOG_ERROR, "illegal count %d at %d\n", count, i);
return AVERROR_INVALIDDATA; ret = AVERROR_INVALIDDATA;
goto fail;
} }
if (tmp_stream >= stream_count) { if (tmp_stream >= stream_count) {
av_log(s, AV_LOG_ERROR, "illegal stream number\n"); av_log(s, AV_LOG_ERROR, "illegal stream number\n");
return AVERROR_INVALIDDATA; ret = AVERROR_INVALIDDATA;
goto fail;
} }
for (j = 0; j < count; j++, i++) { for (j = 0; j < count; j++, i++) {
...@@ -342,11 +347,14 @@ static int decode_main_header(NUTContext *nut) ...@@ -342,11 +347,14 @@ static int decode_main_header(NUTContext *nut)
rem -= nut->header_len[i]; rem -= nut->header_len[i];
if (rem < 0) { if (rem < 0) {
av_log(s, AV_LOG_ERROR, "invalid elision header\n"); av_log(s, AV_LOG_ERROR, "invalid elision header\n");
return AVERROR_INVALIDDATA; ret = AVERROR_INVALIDDATA;
goto fail;
} }
hdr = av_malloc(nut->header_len[i]); hdr = av_malloc(nut->header_len[i]);
if (!hdr) if (!hdr) {
return AVERROR(ENOMEM); ret = AVERROR(ENOMEM);
goto fail;
}
avio_read(bc, hdr, nut->header_len[i]); avio_read(bc, hdr, nut->header_len[i]);
nut->header[i] = hdr; nut->header[i] = hdr;
} }
...@@ -360,16 +368,26 @@ static int decode_main_header(NUTContext *nut) ...@@ -360,16 +368,26 @@ static int decode_main_header(NUTContext *nut)
if (skip_reserved(bc, end) || ffio_get_checksum(bc)) { if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
av_log(s, AV_LOG_ERROR, "main header checksum mismatch\n"); av_log(s, AV_LOG_ERROR, "main header checksum mismatch\n");
return AVERROR_INVALIDDATA; ret = AVERROR_INVALIDDATA;
goto fail;
} }
nut->stream = av_calloc(stream_count, sizeof(StreamContext)); nut->stream = av_calloc(stream_count, sizeof(StreamContext));
if (!nut->stream) if (!nut->stream) {
return AVERROR(ENOMEM); ret = AVERROR(ENOMEM);
goto fail;
}
for (i = 0; i < stream_count; i++) for (i = 0; i < stream_count; i++)
avformat_new_stream(s, NULL); avformat_new_stream(s, NULL);
return 0; return 0;
fail:
av_freep(&nut->time_base);
for (i = 1; i < nut->header_count; i++) {
av_freep(&nut->header[i]);
}
nut->header_count = 0;
return ret;
} }
static int decode_stream_header(NUTContext *nut) static int decode_stream_header(NUTContext *nut)
...@@ -377,9 +395,9 @@ static int decode_stream_header(NUTContext *nut) ...@@ -377,9 +395,9 @@ static int decode_stream_header(NUTContext *nut)
AVFormatContext *s = nut->avf; AVFormatContext *s = nut->avf;
AVIOContext *bc = s->pb; AVIOContext *bc = s->pb;
StreamContext *stc; StreamContext *stc;
int class, stream_id; int class, stream_id, ret;
uint64_t tmp, end; uint64_t tmp, end;
AVStream *st; AVStream *st = NULL;
end = get_packetheader(nut, bc, 1, STREAM_STARTCODE); end = get_packetheader(nut, bc, 1, STREAM_STARTCODE);
end += avio_tell(bc); end += avio_tell(bc);
...@@ -452,7 +470,8 @@ static int decode_stream_header(NUTContext *nut) ...@@ -452,7 +470,8 @@ static int decode_stream_header(NUTContext *nut)
if ((!st->sample_aspect_ratio.num) != (!st->sample_aspect_ratio.den)) { if ((!st->sample_aspect_ratio.num) != (!st->sample_aspect_ratio.den)) {
av_log(s, AV_LOG_ERROR, "invalid aspect ratio %d/%d\n", av_log(s, AV_LOG_ERROR, "invalid aspect ratio %d/%d\n",
st->sample_aspect_ratio.num, st->sample_aspect_ratio.den); st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);
return AVERROR_INVALIDDATA; ret = AVERROR_INVALIDDATA;
goto fail;
} }
ffio_read_varlen(bc); /* csp type */ ffio_read_varlen(bc); /* csp type */
} else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
...@@ -463,12 +482,19 @@ static int decode_stream_header(NUTContext *nut) ...@@ -463,12 +482,19 @@ static int decode_stream_header(NUTContext *nut)
if (skip_reserved(bc, end) || ffio_get_checksum(bc)) { if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
av_log(s, AV_LOG_ERROR, av_log(s, AV_LOG_ERROR,
"stream header %d checksum mismatch\n", stream_id); "stream header %d checksum mismatch\n", stream_id);
return AVERROR_INVALIDDATA; ret = AVERROR_INVALIDDATA;
goto fail;
} }
stc->time_base = &nut->time_base[stc->time_base_id]; stc->time_base = &nut->time_base[stc->time_base_id];
avpriv_set_pts_info(s->streams[stream_id], 63, stc->time_base->num, avpriv_set_pts_info(s->streams[stream_id], 63, stc->time_base->num,
stc->time_base->den); stc->time_base->den);
return 0; return 0;
fail:
if (st && st->codec) {
av_freep(&st->codec->extradata);
st->codec->extradata_size = 0;
}
return ret;
} }
static void set_disposition_bits(AVFormatContext *avf, char *value, static void set_disposition_bits(AVFormatContext *avf, char *value,
...@@ -492,7 +518,7 @@ static int decode_info_header(NUTContext *nut) ...@@ -492,7 +518,7 @@ static int decode_info_header(NUTContext *nut)
AVIOContext *bc = s->pb; AVIOContext *bc = s->pb;
uint64_t tmp, chapter_start, chapter_len; uint64_t tmp, chapter_start, chapter_len;
unsigned int stream_id_plus1, count; unsigned int stream_id_plus1, count;
int chapter_id, i, ret; int chapter_id, i, ret = 0;
int64_t value, end; int64_t value, end;
char name[256], str_value[1024], type_str[256]; char name[256], str_value[1024], type_str[256];
const char *type; const char *type;
...@@ -603,7 +629,8 @@ static int decode_info_header(NUTContext *nut) ...@@ -603,7 +629,8 @@ static int decode_info_header(NUTContext *nut)
av_log(s, AV_LOG_ERROR, "info header checksum mismatch\n"); av_log(s, AV_LOG_ERROR, "info header checksum mismatch\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
return 0; fail:
return FFMIN(ret, 0);
} }
static int decode_syncpoint(NUTContext *nut, int64_t *ts, int64_t *back_ptr) static int decode_syncpoint(NUTContext *nut, int64_t *ts, int64_t *back_ptr)
...@@ -669,9 +696,9 @@ static int find_and_decode_index(NUTContext *nut) ...@@ -669,9 +696,9 @@ static int find_and_decode_index(NUTContext *nut)
uint64_t tmp, end; uint64_t tmp, end;
int i, j, syncpoint_count; int i, j, syncpoint_count;
int64_t filesize = avio_size(bc); int64_t filesize = avio_size(bc);
int64_t *syncpoints; int64_t *syncpoints = NULL;
uint64_t max_pts; uint64_t max_pts;
int8_t *has_keyframe; int8_t *has_keyframe = NULL;
int ret = AVERROR_INVALIDDATA; int ret = AVERROR_INVALIDDATA;
if(filesize <= 0) if(filesize <= 0)
...@@ -987,7 +1014,7 @@ static int decode_frame_header(NUTContext *nut, int64_t *pts, int *stream_id, ...@@ -987,7 +1014,7 @@ static int decode_frame_header(NUTContext *nut, int64_t *pts, int *stream_id,
AVFormatContext *s = nut->avf; AVFormatContext *s = nut->avf;
AVIOContext *bc = s->pb; AVIOContext *bc = s->pb;
StreamContext *stc; StreamContext *stc;
int size, flags, size_mul, pts_delta, i, reserved_count; int size, flags, size_mul, pts_delta, i, reserved_count, ret;
uint64_t tmp; uint64_t tmp;
if (!(nut->flags & NUT_PIPE) && if (!(nut->flags & NUT_PIPE) &&
...@@ -1060,6 +1087,8 @@ static int decode_frame_header(NUTContext *nut, int64_t *pts, int *stream_id, ...@@ -1060,6 +1087,8 @@ static int decode_frame_header(NUTContext *nut, int64_t *pts, int *stream_id,
stc->last_flags = flags; stc->last_flags = flags;
return size; return size;
fail:
return ret;
} }
static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code) static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code)
...@@ -1098,10 +1127,14 @@ static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code) ...@@ -1098,10 +1127,14 @@ static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code)
pkt->pos = avio_tell(bc); // FIXME pkt->pos = avio_tell(bc); // FIXME
if (stc->last_flags & FLAG_SM_DATA) { if (stc->last_flags & FLAG_SM_DATA) {
int sm_size; int sm_size;
if (read_sm_data(s, bc, pkt, 0, pkt->pos + size) < 0) if (read_sm_data(s, bc, pkt, 0, pkt->pos + size) < 0) {
return AVERROR_INVALIDDATA; ret = AVERROR_INVALIDDATA;
if (read_sm_data(s, bc, pkt, 1, pkt->pos + size) < 0) goto fail;
return AVERROR_INVALIDDATA; }
if (read_sm_data(s, bc, pkt, 1, pkt->pos + size) < 0) {
ret = AVERROR_INVALIDDATA;
goto fail;
}
sm_size = avio_tell(bc) - pkt->pos; sm_size = avio_tell(bc) - pkt->pos;
size -= sm_size; size -= sm_size;
pkt->size -= sm_size; pkt->size -= sm_size;
...@@ -1110,7 +1143,7 @@ static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code) ...@@ -1110,7 +1143,7 @@ static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code)
ret = avio_read(bc, pkt->data + nut->header_len[header_idx], size); ret = avio_read(bc, pkt->data + nut->header_len[header_idx], size);
if (ret != size) { if (ret != size) {
if (ret < 0) if (ret < 0)
return ret; goto fail;
} }
av_shrink_packet(pkt, nut->header_len[header_idx] + ret); av_shrink_packet(pkt, nut->header_len[header_idx] + ret);
...@@ -1120,6 +1153,9 @@ static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code) ...@@ -1120,6 +1153,9 @@ static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code)
pkt->pts = pts; pkt->pts = pts;
return 0; return 0;
fail:
av_free_packet(pkt);
return ret;
} }
static int nut_read_packet(AVFormatContext *s, AVPacket *pkt) static int nut_read_packet(AVFormatContext *s, AVPacket *pkt)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment