From 1c37848f9029985d1271da9a0d161c2ebf0aca81 Mon Sep 17 00:00:00 2001 From: Vignesh Venkatasubramanian Date: Thu, 16 Apr 2015 17:32:21 -0700 Subject: [PATCH] webmdashenc: Add better error handling Return appropriate error codes and propagate the error codes from helper functions to the outer calls. Also fix a potential leak in call to av_realloc. Signed-off-by: Vignesh Venkatasubramanian Signed-off-by: Michael Niedermayer --- libavformat/webmdashenc.c | 55 ++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/libavformat/webmdashenc.c b/libavformat/webmdashenc.c index c5d715851f..a8eb8acb52 100644 --- a/libavformat/webmdashenc.c +++ b/libavformat/webmdashenc.c @@ -179,7 +179,7 @@ static int write_representation(AVFormatContext *s, AVStream *stream, char *id, AVDictionaryEntry *bandwidth = av_dict_get(stream->metadata, BANDWIDTH, NULL, 0); if ((w->is_live && (!filename)) || (!w->is_live && (!irange || !cues_start || !cues_end || !filename || !bandwidth))) { - return -1; + return AVERROR_INVALIDDATA; } avio_printf(s->pb, "priv_data; + int i; + for (i = 0; i < w->nb_as; i++) { + av_freep(&w->as[i].streams); + } + av_freep(&w->as); + w->nb_as = 0; +} + /* * Parses a live header filename and computes the representation id, * initialization pattern and the media pattern. Pass NULL if you don't want to @@ -274,9 +284,9 @@ static int parse_filename(char *filename, char **representation_id, underscore_pos = temp_pos + 1; temp_pos = av_stristr(temp_pos + 1, "_"); } - if (!underscore_pos) return -1; + if (!underscore_pos) return AVERROR_INVALIDDATA; period_pos = av_stristr(underscore_pos, "."); - if (!period_pos) return -1; + if (!period_pos) return AVERROR_INVALIDDATA; *(underscore_pos - 1) = 0; if (representation_id) { *representation_id = av_malloc(period_pos - underscore_pos + 1); @@ -373,19 +383,22 @@ static int write_adaptation_set(AVFormatContext *s, int as_index) for (i = 0; i < as->nb_streams; i++) { char *representation_id = NULL; + int ret; if (w->is_live) { AVDictionaryEntry *filename = av_dict_get(s->streams[as->streams[i]]->metadata, FILENAME, NULL, 0); if (!filename || - parse_filename(filename->value, &representation_id, NULL, NULL)) { - return -1; + (ret = parse_filename(filename->value, &representation_id, NULL, NULL))) { + return ret; } } else { representation_id = av_asprintf("%d", w->representation_id++); - if (!representation_id) return -1; + if (!representation_id) return AVERROR(ENOMEM); } - write_representation(s, s->streams[as->streams[i]], representation_id, - !width_in_as, !height_in_as, !sample_rate_in_as); + ret = write_representation(s, s->streams[as->streams[i]], + representation_id, !width_in_as, + !height_in_as, !sample_rate_in_as); + if (ret) return ret; av_free(representation_id); } avio_printf(s->pb, "\n"); @@ -416,9 +429,11 @@ static int parse_adaptation_sets(AVFormatContext *s) if (*p == ' ') continue; else if (state == new_set && !strncmp(p, "id=", 3)) { - w->as = av_realloc(w->as, sizeof(*w->as) * ++w->nb_as); - if (w->as == NULL) + void *mem = av_realloc(w->as, sizeof(*w->as) * (w->nb_as + 1)); + if (mem == NULL) return AVERROR(ENOMEM); + w->as = mem; + ++w->nb_as; w->as[w->nb_as - 1].nb_streams = 0; w->as[w->nb_as - 1].streams = NULL; p += 3; // consume "id=" @@ -453,8 +468,13 @@ static int webm_dash_manifest_write_header(AVFormatContext *s) { int i; double start = 0.0; + int ret; WebMDashMuxContext *w = s->priv_data; - parse_adaptation_sets(s); + ret = parse_adaptation_sets(s); + if (ret < 0) { + free_adaptation_sets(s); + return ret; + } write_header(s); avio_printf(s->pb, "pb, " start=\"PT%gS\"", start); @@ -464,7 +484,11 @@ static int webm_dash_manifest_write_header(AVFormatContext *s) avio_printf(s->pb, " >\n"); for (i = 0; i < w->nb_as; i++) { - if (write_adaptation_set(s, i) < 0) return -1; + ret = write_adaptation_set(s, i); + if (ret < 0) { + free_adaptation_sets(s); + return ret; + } } avio_printf(s->pb, "\n"); @@ -479,12 +503,7 @@ static int webm_dash_manifest_write_packet(AVFormatContext *s, AVPacket *pkt) static int webm_dash_manifest_write_trailer(AVFormatContext *s) { - WebMDashMuxContext *w = s->priv_data; - int i; - for (i = 0; i < w->nb_as; i++) { - av_freep(&w->as[i].streams); - } - av_freep(&w->as); + free_adaptation_sets(s); return 0; }