[FFmpeg-devel] [PATCH 3/3] nutdec: fix various memleaks on failure
Michael Niedermayer
michaelni at gmx.at
Sat May 23 01:36:08 CEST 2015
On Fri, May 22, 2015 at 11:36:55PM +0200, Andreas Cadhalpun wrote:
> Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun at googlemail.com>
> ---
> libavformat/nutdec.c | 77 +++++++++++++++++++++++++++++++++++++---------------
> 1 file changed, 55 insertions(+), 22 deletions(-)
>
> diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c
> index 969f446..fc40f57 100644
> --- a/libavformat/nutdec.c
> +++ b/libavformat/nutdec.c
> @@ -203,7 +203,8 @@ static int nut_probe(AVProbeData *p)
> tmp = ffio_read_varlen(bc); \
> if (!(check)) { \
> av_log(s, AV_LOG_ERROR, "Error " #dst " is (%"PRId64")\n", tmp); \
> - return AVERROR_INVALIDDATA; \
> + ret = AVERROR_INVALIDDATA; \
> + goto fail; \
> } \
> dst = tmp; \
> } while (0)
> @@ -230,7 +231,7 @@ static int decode_main_header(NUTContext *nut)
> AVIOContext *bc = s->pb;
> uint64_t tmp, end;
> 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;
>
> end = get_packetheader(nut, bc, 1, MAIN_STARTCODE);
> @@ -264,7 +265,8 @@ static int decode_main_header(NUTContext *nut)
> 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) {
> av_log(s, AV_LOG_ERROR, "time base invalid\n");
> - return AVERROR_INVALIDDATA;
> + ret = AVERROR_INVALIDDATA;
> + goto fail;
> }
> }
> tmp_pts = 0;
> @@ -301,18 +303,21 @@ static int decode_main_header(NUTContext *nut)
> while (tmp_fields-- > 8) {
> if (bc->eof_reached) {
> 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);
> }
>
> if (count <= 0 || count > 256 - (i <= 'N') - 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) {
> 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++) {
> @@ -342,11 +347,14 @@ static int decode_main_header(NUTContext *nut)
> rem -= nut->header_len[i];
> if (rem < 0) {
> 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]);
> - if (!hdr)
> - return AVERROR(ENOMEM);
> + if (!hdr) {
> + ret = AVERROR(ENOMEM);
> + goto fail;
> + }
> avio_read(bc, hdr, nut->header_len[i]);
> nut->header[i] = hdr;
> }
> @@ -360,16 +368,25 @@ static int decode_main_header(NUTContext *nut)
>
> if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
> 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));
> - if (!nut->stream)
> - return AVERROR(ENOMEM);
> + if (!nut->stream) {
> + ret = AVERROR(ENOMEM);
> + goto fail;
> + }
> for (i = 0; i < stream_count; i++)
> avformat_new_stream(s, NULL);
>
> return 0;
> +fail:
> + av_freep(&nut->time_base);
> + for (i = 1; i < nut->header_count; i++) {
> + av_freep(&nut->header[i]);
> + }
header_count should be reset here too
> + return ret;
> }
>
> static int decode_stream_header(NUTContext *nut)
> @@ -377,9 +394,9 @@ static int decode_stream_header(NUTContext *nut)
> AVFormatContext *s = nut->avf;
> AVIOContext *bc = s->pb;
> StreamContext *stc;
> - int class, stream_id;
> + int class, stream_id, ret;
> uint64_t tmp, end;
> - AVStream *st;
> + AVStream *st = 0;
nitpick: NULL
>
> end = get_packetheader(nut, bc, 1, STREAM_STARTCODE);
> end += avio_tell(bc);
> @@ -452,7 +469,8 @@ static int decode_stream_header(NUTContext *nut)
> if ((!st->sample_aspect_ratio.num) != (!st->sample_aspect_ratio.den)) {
> av_log(s, AV_LOG_ERROR, "invalid aspect ratio %d/%d\n",
> st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);
> - return AVERROR_INVALIDDATA;
> + ret = AVERROR_INVALIDDATA;
> + goto fail;
> }
> ffio_read_varlen(bc); /* csp type */
> } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
> @@ -463,12 +481,17 @@ static int decode_stream_header(NUTContext *nut)
> if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
> av_log(s, AV_LOG_ERROR,
> "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];
> avpriv_set_pts_info(s->streams[stream_id], 63, stc->time_base->num,
> stc->time_base->den);
> return 0;
> +fail:
> + if (st && st->codec)
> + av_freep(&st->codec->extradata);
extradata_size should maybe be reset here too
[...]
> @@ -1095,10 +1121,14 @@ static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code)
> pkt->pos = avio_tell(bc); // FIXME
> if (stc->last_flags & FLAG_SM_DATA) {
> int sm_size;
> - if (read_sm_data(s, bc, pkt, 0, pkt->pos + size) < 0)
> - return AVERROR_INVALIDDATA;
> - if (read_sm_data(s, bc, pkt, 1, pkt->pos + size) < 0)
> - return AVERROR_INVALIDDATA;
> + if (read_sm_data(s, bc, pkt, 0, pkt->pos + size) < 0) {
> + ret = AVERROR_INVALIDDATA;
> + goto fail;
> + }
> + if (read_sm_data(s, bc, pkt, 1, pkt->pos + size) < 0) {
> + ret = AVERROR_INVALIDDATA;
> + goto fail;
> + }
it seems this function is missing a int ret
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Breaking DRM is a little like attempting to break through a door even
though the window is wide open and the only thing in the house is a bunch
of things you dont want and which you would get tomorrow for free anyway
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20150523/c58b57dc/attachment.asc>
More information about the ffmpeg-devel
mailing list