avformat/dashdec: Fix memleaks on error to add representation to dynarray

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.

Reviewed-by: Steven Liu <lq@chinaffmpeg.org>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
pull/352/head
Andreas Rheinhardt 4 years ago
parent f1c3c173c9
commit d63f8c873b
  1. 32
      libavformat/dashdec.c

@ -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;
}
}

Loading…
Cancel
Save