From 4a90b15f74281dce6d0502b4005cbff3c4e7cff3 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 9 Jun 2015 22:30:32 +0200 Subject: vo_opengl: fix dangling pointers with vo_cmdline gl_video_set_options() does not acquire ownership of the opts parameter or its contents. In case of vo_cmdline, opts will point to temporary memory. This memory will be free'd at a later point, and p->opts will point to free'd memory on the next reinitialization. The fix is pretty ugly, but it's a quick bug fix. This can probably be removed once VO sub-options are exposed as properties. Fixes #2035. --- video/out/gl_video.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/video/out/gl_video.c b/video/out/gl_video.c index 19013c5272..c856fbe0df 100644 --- a/video/out/gl_video.c +++ b/video/out/gl_video.c @@ -2762,12 +2762,31 @@ static const char *handle_scaler_opt(const char *name, bool tscale) return NULL; } +static char **dup_str_array(void *parent, char **src) +{ + if (!src) + return NULL; + + char **res = talloc_new(parent); + int num = 0; + for (int n = 0; src && src[n]; n++) + MP_TARRAY_APPEND(res, res, num, talloc_strdup(res, src[n])); + MP_TARRAY_APPEND(res, res, num, NULL); + return res; +} + // Set the options, and possibly update the filter chain too. // Note: assumes all options are valid and verified by the option parser. void gl_video_set_options(struct gl_video *p, struct gl_video_opts *opts, int *queue_size) { + talloc_free(p->opts.source_shader); + talloc_free(p->opts.scale_shader); + talloc_free(p->opts.pre_shaders); + talloc_free(p->opts.post_shaders); + p->opts = *opts; + for (int n = 0; n < 4; n++) { p->opts.scaler[n].kernel.name = (char *)handle_scaler_opt(p->opts.scaler[n].kernel.name, n==3); @@ -2787,6 +2806,11 @@ void gl_video_set_options(struct gl_video *p, struct gl_video_opts *opts, } } + p->opts.source_shader = talloc_strdup(p, p->opts.source_shader); + p->opts.scale_shader = talloc_strdup(p, p->opts.scale_shader); + p->opts.pre_shaders = dup_str_array(p, p->opts.pre_shaders); + p->opts.post_shaders = dup_str_array(p, p->opts.post_shaders); + check_gl_features(p); uninit_rendering(p); } -- cgit v1.2.3