[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