Commit bd131b64 authored by Andreas Rheinhardt's avatar Andreas Rheinhardt Committed by Steven Liu

avformat/hlsenc: Fix leak of options when writing packets

Under certain circumstances hls_write_packet() would add options to an
AVDictionary. Said dictionary was never explicitly freed, instead it was
presumed that these options would be consumed when opening a new
IO-context. This left several possibilities for memleaks:

a) When no new IO-context would be opened at all. This is possible when
using both the flags temp_file and single_file together with a file
output.
b) When an error happens before one actually tries to open the new
IO-context.
c) When the new IO-context does not consume all options.

All three have been fixed; furthermore, the AVDictionary has been put
into a smaller scope (namely the only part of hls_write_packet() where
it is actually used).
Signed-off-by: 's avatarAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
Reviewed-by: 's avatarSteven Liu <lq@onvideo.cn>
parent 9e4b3ccb
...@@ -2241,7 +2241,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -2241,7 +2241,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
int use_temp_file = 0; int use_temp_file = 0;
uint8_t *buffer = NULL; uint8_t *buffer = NULL;
VariantStream *vs = NULL; VariantStream *vs = NULL;
AVDictionary *options = NULL;
char *old_filename = NULL; char *old_filename = NULL;
for (i = 0; i < hls->nb_varstreams; i++) { for (i = 0; i < hls->nb_varstreams; i++) {
...@@ -2343,11 +2342,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -2343,11 +2342,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
use_temp_file = proto && !strcmp(proto, "file") && (hls->flags & HLS_TEMP_FILE); use_temp_file = proto && !strcmp(proto, "file") && (hls->flags & HLS_TEMP_FILE);
} }
// look to rename the asset name
if (use_temp_file) {
av_dict_set(&options, "mpegts_flags", "resend_headers", 0);
}
if (hls->flags & HLS_SINGLE_FILE) { if (hls->flags & HLS_SINGLE_FILE) {
ret = flush_dynbuf(vs, &range_length); ret = flush_dynbuf(vs, &range_length);
av_freep(&vs->temp_buffer); av_freep(&vs->temp_buffer);
...@@ -2356,8 +2350,8 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -2356,8 +2350,8 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
} }
vs->size = range_length; vs->size = range_length;
} else { } else {
set_http_options(s, &options, hls);
if ((hls->max_seg_size > 0 && (vs->size >= hls->max_seg_size)) || !byterange_mode) { if ((hls->max_seg_size > 0 && (vs->size >= hls->max_seg_size)) || !byterange_mode) {
AVDictionary *options = NULL;
char *filename = NULL; char *filename = NULL;
if (hls->key_info_file || hls->encrypt) { if (hls->key_info_file || hls->encrypt) {
av_dict_set(&options, "encryption_key", hls->key_string, 0); av_dict_set(&options, "encryption_key", hls->key_string, 0);
...@@ -2367,12 +2361,21 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -2367,12 +2361,21 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
filename = av_asprintf("%s", oc->url); filename = av_asprintf("%s", oc->url);
} }
if (!filename) { if (!filename) {
av_dict_free(&options);
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} }
// look to rename the asset name
if (use_temp_file)
av_dict_set(&options, "mpegts_flags", "resend_headers", 0);
set_http_options(s, &options, hls);
ret = hlsenc_io_open(s, &vs->out, filename, &options); ret = hlsenc_io_open(s, &vs->out, filename, &options);
if (ret < 0) { if (ret < 0) {
av_log(s, hls->ignore_io_errors ? AV_LOG_WARNING : AV_LOG_ERROR, av_log(s, hls->ignore_io_errors ? AV_LOG_WARNING : AV_LOG_ERROR,
"Failed to open file '%s'\n", filename); "Failed to open file '%s'\n", filename);
av_dict_free(&options);
return hls->ignore_io_errors ? 0 : ret; return hls->ignore_io_errors ? 0 : ret;
} }
if (hls->segment_type == SEGMENT_TYPE_FMP4) { if (hls->segment_type == SEGMENT_TYPE_FMP4) {
...@@ -2380,6 +2383,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -2380,6 +2383,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
} }
ret = flush_dynbuf(vs, &range_length); ret = flush_dynbuf(vs, &range_length);
if (ret < 0) { if (ret < 0) {
av_dict_free(&options);
return ret; return ret;
} }
ret = hlsenc_io_close(s, &vs->out, filename); ret = hlsenc_io_close(s, &vs->out, filename);
...@@ -2391,6 +2395,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -2391,6 +2395,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
reflush_dynbuf(vs, &range_length); reflush_dynbuf(vs, &range_length);
ret = hlsenc_io_close(s, &vs->out, filename); ret = hlsenc_io_close(s, &vs->out, filename);
} }
av_dict_free(&options);
av_freep(&vs->temp_buffer); av_freep(&vs->temp_buffer);
av_freep(&filename); av_freep(&filename);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment