From 4866baacf501094f43cc70b43a7ab13d50fbde50 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 6 Dec 2024 18:52:04 +0100 Subject: [PATCH] Release NSGLView, fixes heap-use-after-free --- libs/canvas/canvas.cc | 10 ++++++++++ libs/canvas/canvas/canvas.h | 2 +- libs/gtkmm2ext/gtkmm2ext/nsglview.h | 2 ++ libs/gtkmm2ext/nsglview.mm | 8 ++++++++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/libs/canvas/canvas.cc b/libs/canvas/canvas.cc index 16d027ef62..7cd635cb88 100644 --- a/libs/canvas/canvas.cc +++ b/libs/canvas/canvas.cc @@ -562,6 +562,16 @@ GtkCanvas::GtkCanvas () Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK); } +GtkCanvas::~GtkCanvas () +{ + _in_dtor = true; +#ifdef __APPLE__ + if (_nsglview) { + Gtkmm2ext::nsglview_destroy (_nsglview); + } +#endif +} + void GtkCanvas::set_single_exposure (bool yn) { diff --git a/libs/canvas/canvas/canvas.h b/libs/canvas/canvas/canvas.h index 3eec1e5ddb..ff1cdf669e 100644 --- a/libs/canvas/canvas/canvas.h +++ b/libs/canvas/canvas/canvas.h @@ -218,7 +218,7 @@ class LIBCANVAS_API GtkCanvas : public Canvas, public Gtk::EventBox, public Gtkm { public: GtkCanvas (); - ~GtkCanvas () { _in_dtor = true ; } + ~GtkCanvas (); void use_nsglview (bool retina = true); diff --git a/libs/gtkmm2ext/gtkmm2ext/nsglview.h b/libs/gtkmm2ext/gtkmm2ext/nsglview.h index 63645fc202..d678fa858f 100644 --- a/libs/gtkmm2ext/gtkmm2ext/nsglview.h +++ b/libs/gtkmm2ext/gtkmm2ext/nsglview.h @@ -26,9 +26,11 @@ namespace Gtkmm2ext class CairoCanvas; void* nsglview_create (CairoCanvas*, bool use_backing_scale); + void nsglview_destroy (void*); void nsglview_overlay (void*, GdkWindow*); void nsglview_resize (void*, int x, int y, int w, int h); void nsglview_queue_draw (void*, int x, int y, int w, int h); void nsglview_set_visible (void*, bool); + } #endif diff --git a/libs/gtkmm2ext/nsglview.mm b/libs/gtkmm2ext/nsglview.mm index 78482dddd5..026fabef71 100644 --- a/libs/gtkmm2ext/nsglview.mm +++ b/libs/gtkmm2ext/nsglview.mm @@ -396,6 +396,14 @@ Gtkmm2ext::nsglview_create (Gtkmm2ext::CairoCanvas* canvas, bool use_backing_sca return gl_view; } +void +Gtkmm2ext::nsglview_destroy (void* glv) +{ + ArdourCanvasOpenGLView* gl_view = (ArdourCanvasOpenGLView*) glv; + [gl_view removeFromSuperview]; + [gl_view release]; +} + void Gtkmm2ext::nsglview_overlay (void* glv, GdkWindow* window) {