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 <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2018-08-19 17:59:34 +02:00
parent 81da3a2ce7
commit 3301e9b0ff
1 changed files with 9 additions and 1 deletions

View File

@ -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",