diff options
author | Robert Mader <robert.mader@posteo.de> | 2020-08-26 22:55:40 +0200 |
---|---|---|
committer | Robert Mader <robert.mader@posteo.de> | 2020-08-27 00:28:21 +0200 |
commit | 35353fa60ad8c6238120be602c0daab52d0281cf (patch) | |
tree | a528bb90da9a46b628d204b90fdcbd39b43de2f8 | |
parent | d37e728bbd189513adbce1fa0889ef37b2efe6cc (diff) | |
download | mutter-35353fa60ad8c6238120be602c0daab52d0281cf.tar.gz |
wayland/xdg-shell: Move popup role assignment behind checks
If we returned early in one of the checks but already assigned the
surface role, we'd later run into a double-free and crash. Just do
the checks at the beginning.
Also add a missing return statement that was left out in commit
88ff196fe3ca5 and tighten the parent surface check.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1415
(cherry picked from commit 1c4a518cd36b9b3be5b7c0ef5d053b5f2bb3aa51)
-rw-r--r-- | src/wayland/meta-wayland-xdg-shell.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/src/wayland/meta-wayland-xdg-shell.c b/src/wayland/meta-wayland-xdg-shell.c index df4d6f118..8bc0f88eb 100644 --- a/src/wayland/meta-wayland-xdg-shell.c +++ b/src/wayland/meta-wayland-xdg-shell.c @@ -171,6 +171,10 @@ static MetaWaylandSurface * surface_from_xdg_surface_resource (struct wl_resource *resource) { MetaWaylandSurfaceRole *surface_role = wl_resource_get_user_data (resource); + + if (!META_IS_WAYLAND_SURFACE_ROLE (surface_role)) + return NULL; + return meta_wayland_surface_role_get_surface (surface_role); } @@ -1851,18 +1855,6 @@ xdg_surface_constructor_get_popup (struct wl_client *client, MetaWaylandXdgPopup *xdg_popup; MetaWaylandXdgSurface *xdg_surface; - if (!meta_wayland_surface_assign_role (surface, - META_TYPE_WAYLAND_XDG_POPUP, - "shell-client", shell_client, - "xdg-surface-resource", xdg_surface_resource, - NULL)) - { - wl_resource_post_error (xdg_wm_base_resource, XDG_WM_BASE_ERROR_ROLE, - "wl_surface@%d already has a different role", - wl_resource_get_id (surface->resource)); - return; - } - if (!parent_resource) { wl_resource_post_error (xdg_wm_base_resource, @@ -1870,10 +1862,11 @@ xdg_surface_constructor_get_popup (struct wl_client *client, "Parent surface is null but Mutter does not yet " "support specifying parent surfaces via other " "protocols"); + return; } parent_surface = surface_from_xdg_surface_resource (parent_resource); - if (!META_IS_WAYLAND_XDG_SURFACE (parent_surface->role)) + if (!parent_surface || !META_IS_WAYLAND_XDG_SURFACE (parent_surface->role)) { wl_resource_post_error (xdg_wm_base_resource, XDG_WM_BASE_ERROR_INVALID_POPUP_PARENT, @@ -1890,6 +1883,18 @@ xdg_surface_constructor_get_popup (struct wl_client *client, return; } + if (!meta_wayland_surface_assign_role (surface, + META_TYPE_WAYLAND_XDG_POPUP, + "shell-client", shell_client, + "xdg-surface-resource", xdg_surface_resource, + NULL)) + { + wl_resource_post_error (xdg_wm_base_resource, XDG_WM_BASE_ERROR_ROLE, + "wl_surface@%d already has a different role", + wl_resource_get_id (surface->resource)); + return; + } + xdg_popup = META_WAYLAND_XDG_POPUP (surface->role); xdg_popup->resource = wl_resource_create (client, |