aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-09-19 04:28:47 +0200
committerAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2021-02-27 07:20:59 +0100
commit74b97ea6034c75044c43b065df1fc07e5b2e4b84 (patch)
tree7dbdbc032230973efd7eab9ad0e89060e14a9cff
parent06d5472b3c5f226530a0d8377496e1e4838a8413 (diff)
downloadffmpeg-74b97ea6034c75044c43b065df1fc07e5b2e4b84.tar.gz
avformat/dashdec: Fix leak of representation on error
If parsing a representation fails, it is not added to the list of representations and is therefore not freed in dash_close(); it therefore leaked in most error paths in parse_manifest_representation() (some error paths had (incomplete) code for freeing). This commit fixes freeing the representation in this case. Reviewed-by: Steven Liu <lq@chinaffmpeg.org> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com> (cherry picked from commit 5c91701dc7f46975f9fb714d30c70a81dc0ce90a)
-rw-r--r--libavformat/dashdec.c52
1 files changed, 21 insertions, 31 deletions
diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
index 3291c75007..5ed55687b7 100644
--- a/libavformat/dashdec.c
+++ b/libavformat/dashdec.c
@@ -887,9 +887,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
c->max_url_size = aligned(c->max_url_size
+ (rep_id_val ? strlen(rep_id_val) : 0)
+ (rep_bandwidth_val ? strlen(rep_bandwidth_val) : 0));
- if (ret == AVERROR(ENOMEM) || ret == 0) {
- goto end;
- }
+ if (ret == AVERROR(ENOMEM) || ret == 0)
+ goto free;
if (representation_segmenttemplate_node || fragment_template_node || period_segmenttemplate_node) {
fragment_timeline_node = NULL;
fragment_templates_tab[0] = representation_segmenttemplate_node;
@@ -907,19 +906,12 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
if (initialization_val) {
rep->init_section = av_mallocz(sizeof(struct fragment));
- if (!rep->init_section) {
- av_free(rep);
- ret = AVERROR(ENOMEM);
- goto end;
- }
+ if (!rep->init_section)
+ goto enomem;
c->max_url_size = aligned(c->max_url_size + strlen(initialization_val));
rep->init_section->url = get_content_url(baseurl_nodes, 4, c->max_url_size, rep_id_val, rep_bandwidth_val, initialization_val);
- if (!rep->init_section->url) {
- av_free(rep->init_section);
- av_free(rep);
- ret = AVERROR(ENOMEM);
- goto end;
- }
+ if (!rep->init_section->url)
+ goto enomem;
rep->init_section->size = -1;
xmlFree(initialization_val);
}
@@ -974,23 +966,19 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node);
while (fragment_timeline_node) {
ret = parse_manifest_segmenttimeline(s, rep, fragment_timeline_node);
- if (ret < 0) {
- return ret;
- }
+ if (ret < 0)
+ goto free;
fragment_timeline_node = xmlNextElementSibling(fragment_timeline_node);
}
}
} else if (representation_baseurl_node && !representation_segmentlist_node) {
seg = av_mallocz(sizeof(struct fragment));
- if (!seg) {
- ret = AVERROR(ENOMEM);
- goto end;
- }
+ if (!seg)
+ goto enomem;
seg->url = get_content_url(baseurl_nodes, 4, c->max_url_size, rep_id_val, rep_bandwidth_val, NULL);
if (!seg->url) {
av_free(seg);
- ret = AVERROR(ENOMEM);
- goto end;
+ goto enomem;
}
seg->size = -1;
dynarray_add(&rep->fragments, &rep->n_fragments, seg);
@@ -1027,9 +1015,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
baseurl_nodes,
rep_id_val,
rep_bandwidth_val);
- if (ret < 0) {
- return ret;
- }
+ if (ret < 0)
+ goto free;
fragmenturl_node = xmlNextElementSibling(fragmenturl_node);
}
@@ -1040,16 +1027,14 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node);
while (fragment_timeline_node) {
ret = parse_manifest_segmenttimeline(s, rep, fragment_timeline_node);
- if (ret < 0) {
- return ret;
- }
+ if (ret < 0)
+ goto free;
fragment_timeline_node = xmlNextElementSibling(fragment_timeline_node);
}
}
} else {
- free_representation(rep);
- rep = NULL;
av_log(s, AV_LOG_ERROR, "Unknown format of Representation node id[%s] \n", (const char *)rep_id_val);
+ goto free;
}
if (rep) {
@@ -1090,6 +1075,11 @@ end:
xmlFree(rep_framerate_val);
return ret;
+enomem:
+ ret = AVERROR(ENOMEM);
+free:
+ free_representation(rep);
+ goto end;
}
static int parse_manifest_adaptationset_attr(AVFormatContext *s, xmlNodePtr adaptionset_node)