From 3301e9b0ffa24542336af851321e38cdb33e8676 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sun, 19 Aug 2018 17:59:34 +0200 Subject: [PATCH] naughty.dbus: Duplicate surface data When an icon is sent over dbus, we turn this into a cairo ImageSurface. This is done by turning the actual icon data into a string and using cairo.ImageSurface.create_for_data() to create a surface for this data. However, this function only creates an ImageSurface that refers to this data. It does not copy the data. Thus, when the Lua GC later frees the string, we have a cairo surface that refers to already-freed data. Fix this by duplicating the cairo surface, which makes cairo create a copy of the data. Then, we finish the original surface. While doing this, the string is kept alive in a local variable. (Possibly) Fixes: https://github.com/awesomeWM/awesome/issues/2361 Signed-off-by: Uli Schlachter --- lib/naughty/dbus.lua | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/naughty/dbus.lua b/lib/naughty/dbus.lua index c3cd75929..bb9fcfc50 100644 --- a/lib/naughty/dbus.lua +++ b/lib/naughty/dbus.lua @@ -16,6 +16,7 @@ local string = string local capi = { awesome = awesome, dbus = dbus } local gtable = require("gears.table") +local gsurface = require("gears.surface") local cairo = require("lgi").cairo local schar = string.char @@ -102,7 +103,14 @@ local function convert_icon(w, h, rowstride, channels, data) offset = offset + rowstride end - return cairo.ImageSurface.create_for_data(tcat(rows), format, w, h, stride) + local pixels = tcat(rows) + local surf = cairo.ImageSurface.create_for_data(pixels, format, w, h, stride) + + -- The surface refers to 'pixels', which can be freed by the GC. Thus, + -- duplicate the surface to create a copy of the data owned by cairo. + local res = gsurface.duplicate_surface(surf) + surf:finish() + return res end capi.dbus.connect_signal("org.freedesktop.Notifications",