summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDudemanguy <random342@airmail.cc>2021-11-02 18:28:53 -0500
committerDudemanguy <random342@airmail.cc>2021-11-03 00:32:27 +0000
commit5512f53722a46dd7b4844ca8f7e47b5fed2d7259 (patch)
treee876f08035f9cb6db9e6850a1cf7560fd5a12f22
parent171627b267bb741fafe0d06bf4dc9c6b9fe4571d (diff)
downloadmpv-5512f53722a46dd7b4844ca8f7e47b5fed2d7259.tar.bz2
mpv-5512f53722a46dd7b4844ca8f7e47b5fed2d7259.tar.xz
player: fix autofit/geometry related segfault
Back when runtime updating of autofit/geometry was added for wayland and x11 (commits: 4445ac828dca0298543103094357e64f8828ef56 and ced92ba607ebd98687b26ef3d8c09d5f6e22cf4b respectively), the naive assumption was that window-related geometry would always be available. While this is true 99% of the time, this isn't a guarentee. It is possible for certain things such as loading shaders to delay starting up the player. This causes autofit/geometry options to be registered as a runtime update and triggers VOCTRL_VO_OPTS_CHANGED. This ends up calling some geometry-related functions but this happens before the actual values are available. Hence, a nullptr was accessed which segfaults. At least one user experienced this with a combination of options in wayland but in theory the same thing could happen under x11. The fix is simple. Just be sure to check that the required geometry is available before doing any calculations. In wayland, this would be wl->current_output. Additionally add an assert to set_geometry (we should never use this function without wl->current_output) to be extra sure. In x11, the check is on x11->window. Later when the reconfig for each backend actually happens, the autofit/geometry set by the user happens anyway so ignoring it in this case does no harm. Fixes #9381.
-rw-r--r--video/out/wayland_common.c13
-rw-r--r--video/out/x11_common.c3
2 files changed, 11 insertions, 5 deletions
diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c
index 6810069d4f..72bacad15d 100644
--- a/video/out/wayland_common.c
+++ b/video/out/wayland_common.c
@@ -1370,6 +1370,7 @@ static int set_cursor_visibility(struct vo_wayland_state *wl, bool on)
static void set_geometry(struct vo_wayland_state *wl)
{
struct vo *vo = wl->vo;
+ assert(wl->current_output);
struct vo_win_geometry geo;
struct mp_rect screenrc = wl->current_output->geometry;
@@ -1597,11 +1598,13 @@ int vo_wayland_control(struct vo *vo, int *events, int request, void *arg)
if (opt == &opts->geometry || opt == &opts->autofit ||
opt == &opts->autofit_smaller || opt == &opts->autofit_larger)
{
- set_geometry(wl);
- wl->window_size = wl->vdparams;
- if (!wl->vo_opts->fullscreen && !wl->vo_opts->window_maximized)
- wl->geometry = wl->window_size;
- wl->pending_vo_events |= VO_EVENT_RESIZE;
+ if (wl->current_output) {
+ set_geometry(wl);
+ wl->window_size = wl->vdparams;
+ if (!wl->vo_opts->fullscreen && !wl->vo_opts->window_maximized)
+ wl->geometry = wl->window_size;
+ wl->pending_vo_events |= VO_EVENT_RESIZE;
+ }
}
}
return VO_TRUE;
diff --git a/video/out/x11_common.c b/video/out/x11_common.c
index 2e685e2297..fe27483f0a 100644
--- a/video/out/x11_common.c
+++ b/video/out/x11_common.c
@@ -1847,6 +1847,9 @@ static void vo_x11_set_geometry(struct vo *vo)
{
struct vo_x11_state *x11 = vo->x11;
+ if (!x11->window)
+ return;
+
if (x11->opts->window_maximized) {
x11->pending_geometry_change = true;
} else {