> On 17 Apr 2018, at 03:02, Richard Shaffer <rshaf...@tunein.com> wrote: > > On Fri, Apr 13, 2018 at 5:14 PM, <rshaf...@tunein.com> wrote: > >> From: Richard Shaffer <rshaf...@tunein.com> >> >> The HLSContext struct contains fields which duplicate the data stored in >> the >> avio_opts field. This change removes those fields in favor of avio_opts, >> and >> updates the code accordingly. >> --- >> The original patch caused the buffer pointed to by new_cookies in open_url >> to be >> leaked. The only thing that buffer is used for is to store the value until >> it >> can be passed to av_dict_set. To fix the leak, v2 of the patch simply calls >> av_dict_set with the AV_DICT_DONT_STRDUP_VAL flag, so that the dictionary >> takes >> ownership of the memory instead of copying it again. >> >> libavformat/hls.c | 74 +++++++----------------------- >> ------------------------- >> 1 file changed, 9 insertions(+), 65 deletions(-) >> >> diff --git a/libavformat/hls.c b/libavformat/hls.c >> index 1257cd101c..d6158c0ada 100644 >> --- a/libavformat/hls.c >> +++ b/libavformat/hls.c >> @@ -202,11 +202,6 @@ typedef struct HLSContext { >> int64_t first_timestamp; >> int64_t cur_timestamp; >> AVIOInterruptCB *interrupt_callback; >> - char *referer; ///< holds HTTP referer set as >> an AVOption to the HTTP protocol context >> - char *user_agent; ///< holds HTTP user agent set >> as an AVOption to the HTTP protocol context >> - char *cookies; ///< holds HTTP cookie values >> set in either the initial response or as an AVOption to the HTTP protocol >> context >> - char *headers; ///< holds HTTP headers set as >> an AVOption to the HTTP protocol context >> - char *http_proxy; ///< holds the address of the >> HTTP proxy server >> AVDictionary *avio_opts; >> int strict_std_compliance; >> char *allowed_extensions; >> @@ -267,10 +262,6 @@ static void free_playlist_list(HLSContext *c) >> av_free(pls); >> } >> av_freep(&c->playlists); >> - av_freep(&c->cookies); >> - av_freep(&c->user_agent); >> - av_freep(&c->headers); >> - av_freep(&c->http_proxy); >> c->n_playlists = 0; >> } >> >> @@ -593,14 +584,6 @@ static int ensure_playlist(HLSContext *c, struct >> playlist **pls, const char *url >> return 0; >> } >> >> -static void update_options(char **dest, const char *name, void *src) >> -{ >> - av_freep(dest); >> - av_opt_get(src, name, AV_OPT_SEARCH_CHILDREN, (uint8_t**)dest); >> - if (*dest && !strlen(*dest)) >> - av_freep(dest); >> -} >> - >> static int open_url_keepalive(AVFormatContext *s, AVIOContext **pb, >> const char *url) >> { >> @@ -684,12 +667,8 @@ static int open_url(AVFormatContext *s, AVIOContext >> **pb, const char *url, >> if (!(s->flags & AVFMT_FLAG_CUSTOM_IO)) >> av_opt_get(*pb, "cookies", AV_OPT_SEARCH_CHILDREN, >> (uint8_t**)&new_cookies); >> >> - if (new_cookies) { >> - av_free(c->cookies); >> - c->cookies = new_cookies; >> - } >> - >> - av_dict_set(&opts, "cookies", c->cookies, 0); >> + if (new_cookies) >> + av_dict_set(&opts, "cookies", new_cookies, >> AV_DICT_DONT_STRDUP_VAL); >> } >> >> av_dict_free(&tmp); >> @@ -736,14 +715,7 @@ static int parse_playlist(HLSContext *c, const char >> *url, >> >> if (!in) { >> AVDictionary *opts = NULL; >> - /* Some HLS servers don't like being sent the range header */ >> - av_dict_set(&opts, "seekable", "0", 0); >> - >> - // broker prior HTTP options that should be consistent across >> requests >> - av_dict_set(&opts, "user_agent", c->user_agent, 0); >> - av_dict_set(&opts, "cookies", c->cookies, 0); >> - av_dict_set(&opts, "headers", c->headers, 0); >> - av_dict_set(&opts, "http_proxy", c->http_proxy, 0); >> + av_dict_copy(&opts, c->avio_opts, 0); >> >> if (c->http_persistent) >> av_dict_set(&opts, "multiple_requests", "1", 0); >> @@ -1169,14 +1141,6 @@ static int open_input(HLSContext *c, struct >> playlist *pls, struct segment *seg, >> int ret; >> int is_http = 0; >> >> - // broker prior HTTP options that should be consistent across requests >> - av_dict_set(&opts, "user_agent", c->user_agent, 0); >> - av_dict_set(&opts, "referer", c->referer, 0); >> - av_dict_set(&opts, "cookies", c->cookies, 0); >> - av_dict_set(&opts, "headers", c->headers, 0); >> - av_dict_set(&opts, "http_proxy", c->http_proxy, 0); >> - av_dict_set(&opts, "seekable", "0", 0); >> - >> if (c->http_persistent) >> av_dict_set(&opts, "multiple_requests", "1", 0); >> >> @@ -1193,7 +1157,6 @@ static int open_input(HLSContext *c, struct playlist >> *pls, struct segment *seg, >> if (seg->key_type == KEY_NONE) { >> ret = open_url(pls->parent, in, seg->url, c->avio_opts, opts, >> &is_http); >> } else if (seg->key_type == KEY_AES_128) { >> - AVDictionary *opts2 = NULL; >> char iv[33], key[33], url[MAX_URL_SIZE]; >> if (strcmp(seg->key, pls->key_url)) { >> AVIOContext *pb = NULL; >> @@ -1218,14 +1181,10 @@ static int open_input(HLSContext *c, struct >> playlist *pls, struct segment *seg, >> else >> snprintf(url, sizeof(url), "crypto:%s", seg->url); >> >> - av_dict_copy(&opts2, c->avio_opts, 0); >> - av_dict_set(&opts2, "key", key, 0); >> - av_dict_set(&opts2, "iv", iv, 0); >> - >> - ret = open_url(pls->parent, in, url, opts2, opts, &is_http); >> - >> - av_dict_free(&opts2); >> + av_dict_set(&opts, "key", key, 0); >> + av_dict_set(&opts, "iv", iv, 0); >> >> + ret = open_url(pls->parent, in, url, c->avio_opts, opts, >> &is_http); >> if (ret < 0) { >> goto cleanup; >> } >> @@ -1781,7 +1740,6 @@ static int hls_close(AVFormatContext *s) >> >> static int hls_read_header(AVFormatContext *s) >> { >> - void *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb; >> HLSContext *c = s->priv_data; >> int ret = 0, i; >> int highest_cur_seq_no = 0; >> @@ -1794,29 +1752,15 @@ static int hls_read_header(AVFormatContext *s) >> c->first_timestamp = AV_NOPTS_VALUE; >> c->cur_timestamp = AV_NOPTS_VALUE; >> >> - if (u) { >> - // get the previous user agent & set back to null if string size >> is zero >> - update_options(&c->user_agent, "user_agent", u); >> - >> - // get the previous cookies & set back to null if string size is >> zero >> - update_options(&c->cookies, "cookies", u); >> - >> - // get the previous headers & set back to null if string size is >> zero >> - update_options(&c->headers, "headers", u); >> - >> - // get the previous http proxt & set back to null if string size >> is zero >> - update_options(&c->http_proxy, "http_proxy", u); >> - } >> - >> - if ((ret = parse_playlist(c, s->url, NULL, s->pb)) < 0) >> - goto fail; >> - >> if ((ret = save_avio_options(s)) < 0) >> goto fail; >> >> /* Some HLS servers don't like being sent the range header */ >> av_dict_set(&c->avio_opts, "seekable", "0", 0); >> >> + if ((ret = parse_playlist(c, s->url, NULL, s->pb)) < 0) >> + goto fail; >> + >> if (c->n_variants == 0) { >> av_log(NULL, AV_LOG_WARNING, "Empty playlist\n"); >> ret = AVERROR_EOF; >> -- >> 2.15.1 (Apple Git-101) >> >> > Just wanted to send a reminder about this patch. The original version was > sent about a week ago. If anyone has time to review and either comment or > merge, that would be really great.
Pushed > > -Richard > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel Thanks Steven _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel