git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commit72dc2f8488502cf8d6e6d31a1584fe4cfa64b0c3
parent56c0c34690
authorIsaac Freund <[email protected]>
date2020-06-16 22:46
river-status: fix crash due to bad alignment

Using an ArrayList to back the wl_array we need to pass to libwayland
is much safer and avoids this kind of bug.

 river/OutputStatus.zig | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/river/OutputStatus.zig b/river/OutputStatus.zig
index 563e42b..6b09dd1 100644
--- a/river/OutputStatus.zig
+++ b/river/OutputStatus.zig
@@ -57,19 +57,23 @@ fn destroy(wl_client: ?*c.wl_client, wl_resource: ?*c.wl_resource) callconv(.C)
 
 /// Send the current tags of each view on the output to the client.
 pub fn sendViewTags(self: Self) void {
-    var view_tags: c.wl_array = undefined;
-    c.wl_array_init(&view_tags);
+    var view_tags = std.ArrayList(u32).init(util.allocator);
+    defer view_tags.deinit();
+
     var it = ViewStack(View).iterator(self.output.views.first, std.math.maxInt(u32));
-    while (it.next()) |node| {
-        const ptr = c.wl_array_add(&view_tags, @sizeOf(u32)) orelse {
-            c.wl_resource_post_no_memory(self.wl_resource);
-            Log.Error.log("out of memory", .{});
-            return;
-        };
-        const ptr_u32 = util.voidCast(u32, ptr);
-        ptr_u32.* = node.view.current_tags;
-    }
-    c.zriver_output_status_v1_send_view_tags(self.wl_resource, &view_tags);
+    while (it.next()) |node|
+        view_tags.append(node.view.current_tags) catch {
+        c.wl_resource_post_no_memory(self.wl_resource);
+        Log.Error.log("out of memory", .{});
+        return;
+    };
+
+    var wl_array = c.wl_array{
+        .size = view_tags.items.len,
+        .alloc = view_tags.capacity,
+        .data = view_tags.items.ptr,
+    };
+    c.zriver_output_status_v1_send_view_tags(self.wl_resource, &wl_array);
 }
 
 /// Send the currently focused tags of the output to the client.