mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-04-14 00:58:38 +02:00
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>
This commit is contained in:
parent
5d63f154ef
commit
5c91701dc7
@ -887,9 +887,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
|
|||||||
c->max_url_size = aligned(c->max_url_size
|
c->max_url_size = aligned(c->max_url_size
|
||||||
+ (rep_id_val ? strlen(rep_id_val) : 0)
|
+ (rep_id_val ? strlen(rep_id_val) : 0)
|
||||||
+ (rep_bandwidth_val ? strlen(rep_bandwidth_val) : 0));
|
+ (rep_bandwidth_val ? strlen(rep_bandwidth_val) : 0));
|
||||||
if (ret == AVERROR(ENOMEM) || ret == 0) {
|
if (ret == AVERROR(ENOMEM) || ret == 0)
|
||||||
goto end;
|
goto free;
|
||||||
}
|
|
||||||
if (representation_segmenttemplate_node || fragment_template_node || period_segmenttemplate_node) {
|
if (representation_segmenttemplate_node || fragment_template_node || period_segmenttemplate_node) {
|
||||||
fragment_timeline_node = NULL;
|
fragment_timeline_node = NULL;
|
||||||
fragment_templates_tab[0] = representation_segmenttemplate_node;
|
fragment_templates_tab[0] = representation_segmenttemplate_node;
|
||||||
@ -907,19 +906,12 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
|
|||||||
|
|
||||||
if (initialization_val) {
|
if (initialization_val) {
|
||||||
rep->init_section = av_mallocz(sizeof(struct fragment));
|
rep->init_section = av_mallocz(sizeof(struct fragment));
|
||||||
if (!rep->init_section) {
|
if (!rep->init_section)
|
||||||
av_free(rep);
|
goto enomem;
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
c->max_url_size = aligned(c->max_url_size + strlen(initialization_val));
|
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);
|
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) {
|
if (!rep->init_section->url)
|
||||||
av_free(rep->init_section);
|
goto enomem;
|
||||||
av_free(rep);
|
|
||||||
ret = AVERROR(ENOMEM);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
rep->init_section->size = -1;
|
rep->init_section->size = -1;
|
||||||
xmlFree(initialization_val);
|
xmlFree(initialization_val);
|
||||||
}
|
}
|
||||||
@ -974,23 +966,19 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
|
|||||||
fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node);
|
fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node);
|
||||||
while (fragment_timeline_node) {
|
while (fragment_timeline_node) {
|
||||||
ret = parse_manifest_segmenttimeline(s, rep, fragment_timeline_node);
|
ret = parse_manifest_segmenttimeline(s, rep, fragment_timeline_node);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
return ret;
|
goto free;
|
||||||
}
|
|
||||||
fragment_timeline_node = xmlNextElementSibling(fragment_timeline_node);
|
fragment_timeline_node = xmlNextElementSibling(fragment_timeline_node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (representation_baseurl_node && !representation_segmentlist_node) {
|
} else if (representation_baseurl_node && !representation_segmentlist_node) {
|
||||||
seg = av_mallocz(sizeof(struct fragment));
|
seg = av_mallocz(sizeof(struct fragment));
|
||||||
if (!seg) {
|
if (!seg)
|
||||||
ret = AVERROR(ENOMEM);
|
goto enomem;
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
seg->url = get_content_url(baseurl_nodes, 4, c->max_url_size, rep_id_val, rep_bandwidth_val, NULL);
|
seg->url = get_content_url(baseurl_nodes, 4, c->max_url_size, rep_id_val, rep_bandwidth_val, NULL);
|
||||||
if (!seg->url) {
|
if (!seg->url) {
|
||||||
av_free(seg);
|
av_free(seg);
|
||||||
ret = AVERROR(ENOMEM);
|
goto enomem;
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
seg->size = -1;
|
seg->size = -1;
|
||||||
dynarray_add(&rep->fragments, &rep->n_fragments, seg);
|
dynarray_add(&rep->fragments, &rep->n_fragments, seg);
|
||||||
@ -1027,9 +1015,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
|
|||||||
baseurl_nodes,
|
baseurl_nodes,
|
||||||
rep_id_val,
|
rep_id_val,
|
||||||
rep_bandwidth_val);
|
rep_bandwidth_val);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
return ret;
|
goto free;
|
||||||
}
|
|
||||||
fragmenturl_node = xmlNextElementSibling(fragmenturl_node);
|
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);
|
fragment_timeline_node = xmlFirstElementChild(fragment_timeline_node);
|
||||||
while (fragment_timeline_node) {
|
while (fragment_timeline_node) {
|
||||||
ret = parse_manifest_segmenttimeline(s, rep, fragment_timeline_node);
|
ret = parse_manifest_segmenttimeline(s, rep, fragment_timeline_node);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
return ret;
|
goto free;
|
||||||
}
|
|
||||||
fragment_timeline_node = xmlNextElementSibling(fragment_timeline_node);
|
fragment_timeline_node = xmlNextElementSibling(fragment_timeline_node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
av_log(s, AV_LOG_ERROR, "Unknown format of Representation node id[%s] \n", (const char *)rep_id_val);
|
||||||
|
goto free;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rep) {
|
if (rep) {
|
||||||
@ -1090,6 +1075,11 @@ end:
|
|||||||
xmlFree(rep_framerate_val);
|
xmlFree(rep_framerate_val);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
enomem:
|
||||||
|
ret = AVERROR(ENOMEM);
|
||||||
|
free:
|
||||||
|
free_representation(rep);
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_manifest_adaptationset_attr(AVFormatContext *s, xmlNodePtr adaptionset_node)
|
static int parse_manifest_adaptationset_attr(AVFormatContext *s, xmlNodePtr adaptionset_node)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user