@@ -605,6 +605,7 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati
char *media_val = NULL;
char *range_val = NULL;
int max_url_size = c ? c->max_url_size: MAX_URL_SIZE;
+ int err;
if (!av_strcasecmp(fragmenturl_node->name, (const char *)"Initialization")) {
initialization_val = xmlGetProp(fragmenturl_node, "sourceURL");
@@ -648,7 +649,11 @@ static int parse_manifest_segmenturlnode(AVFormatContext *s, struct representati
av_free(seg);
return AVERROR(ENOMEM);
}
- dynarray_add(&rep->fragments, &rep->n_fragments, seg);
+ err = av_dynarray_add_nofree(&rep->fragments, &rep->n_fragments, seg);
+ if (err < 0) {
+ free_fragment(&seg);
+ return err;
+ }
}
}
@@ -660,6 +665,7 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat
{
xmlAttrPtr attr = NULL;
char *val = NULL;
+ int err;
if (!av_strcasecmp(fragment_timeline_node->name, (const char *)"S")) {
struct timeline *tml = av_mallocz(sizeof(struct timeline));
@@ -685,7 +691,11 @@ static int parse_manifest_segmenttimeline(AVFormatContext *s, struct representat
attr = attr->next;
xmlFree(val);
}
- dynarray_add(&rep->timelines, &rep->n_timelines, tml);
+ err = av_dynarray_add_nofree(&rep->timelines, &rep->n_timelines, tml);
+ if (err < 0) {
+ av_free(tml);
+ return err;
+ }
}
return 0;
@@ -975,13 +985,15 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
seg = av_mallocz(sizeof(struct fragment));
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) {
+ ret = av_dynarray_add_nofree(&rep->fragments, &rep->n_fragments, seg);
+ if (ret < 0) {
av_free(seg);
- goto enomem;
+ goto free;
}
+ seg->url = get_content_url(baseurl_nodes, 4, c->max_url_size, rep_id_val, rep_bandwidth_val, NULL);
+ if (!seg->url)
+ goto enomem;
seg->size = -1;
- dynarray_add(&rep->fragments, &rep->n_fragments, seg);
} else if (representation_segmentlist_node) {
// TODO: https://www.brendanlong.com/the-structure-of-an-mpeg-dash-mpd.html
// http://www-itec.uni-klu.ac.at/dash/ddash/mpdGenerator.php?fragmentlength=15&type=full
@@ -1051,18 +1063,20 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url,
switch (type) {
case AVMEDIA_TYPE_VIDEO:
- dynarray_add(&c->videos, &c->n_videos, rep);
+ ret = av_dynarray_add_nofree(&c->videos, &c->n_videos, rep);
break;
case AVMEDIA_TYPE_AUDIO:
- dynarray_add(&c->audios, &c->n_audios, rep);
+ ret = av_dynarray_add_nofree(&c->audios, &c->n_audios, rep);
break;
case AVMEDIA_TYPE_SUBTITLE:
- dynarray_add(&c->subtitles, &c->n_subtitles, rep);
+ ret = av_dynarray_add_nofree(&c->subtitles, &c->n_subtitles, rep);
break;
default:
av_log(s, AV_LOG_WARNING, "Unsupported the stream type %d\n", type);
break;
}
+ if (ret < 0)
+ goto free;
}
}
Up until now, the DASH demuxer used av_dynarray_add() to add audio/video/subtitles representations to arrays. Yet av_dynarray_add() frees the array upon failure, leading to leaks of its elements; furthermore, the element to be added leaks, too. This has been fixed by using av_dynarray_add_nofree() instead and by freeing the elements that could not be added to the list. Furthermore, errors from this are now checked and returned. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com> --- libavformat/dashdec.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-)