From 8892570093948de16a50e06b1a7d6890405de7a1 Mon Sep 17 00:00:00 2001 From: Shawn Wallace Date: Mon, 22 Jul 2024 18:24:21 -0400 Subject: [PATCH] Fix panic when title contains null bytes Fixes #42 --- src/xstate/mod.rs | 6 +++++- tests/integration.rs | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/xstate/mod.rs b/src/xstate/mod.rs index e8aee23..23acd77 100644 --- a/src/xstate/mod.rs +++ b/src/xstate/mod.rs @@ -4,7 +4,7 @@ use selection::{SelectionData, SelectionTarget}; use crate::server::WindowAttributes; use bitflags::bitflags; use log::{debug, trace, warn}; -use std::ffi::CString; +use std::ffi::{CString, CStr}; use std::os::fd::{AsRawFd, BorrowedFd}; use std::sync::Arc; use xcb::{x, Xid, XidNew}; @@ -526,6 +526,9 @@ impl XState { let cookie = self.get_property_cookie(window, x::ATOM_WM_NAME, x::ATOM_STRING, 256); let resolver = |reply: x::GetPropertyReply| { let data: &[u8] = reply.value(); + // strip trailing zeros or wayland-rs will lose its mind + // https://github.com/Smithay/wayland-rs/issues/748 + let data = data.split(|byte| *byte == 0).next().unwrap(); let name = String::from_utf8_lossy(data).to_string(); WmName::WmName(name) }; @@ -545,6 +548,7 @@ impl XState { self.get_property_cookie(window, self.atoms.net_wm_name, self.atoms.utf8_string, 256); let resolver = |reply: x::GetPropertyReply| { let data: &[u8] = reply.value(); + let data = data.split(|byte| *byte == 0).next().unwrap(); let name = String::from_utf8_lossy(data).to_string(); WmName::NetWmName(name) }; diff --git a/tests/integration.rs b/tests/integration.rs index f221f37..991888f 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -979,3 +979,38 @@ fn bad_clipboard_data() { let e = e.expect("No selection notify event"); assert_eq!(e.property(), x::ATOM_NONE); } + +// issue #42 +#[test] +fn funny_window_title() { + let mut f = Fixture::new(); + let mut connection = Connection::new(&f.display); + let window = connection.new_window(connection.root, 0, 0, 20, 20, false); + connection.set_property( + window, + x::ATOM_STRING, + x::ATOM_WM_NAME, + b"title\0\0\0\0", + ); + connection.map_window(window); + f.wait_and_dispatch(); + + let surface = f + .testwl + .last_created_surface_id() + .expect("No surface created!"); + f.configure_and_verify_new_toplevel(&mut connection, window, surface); + let data = f.testwl.get_surface_data(surface).unwrap(); + assert_eq!(data.toplevel().title, Some("title".into())); + + connection.set_property( + window, + x::ATOM_STRING, + x::ATOM_WM_NAME, + b"title\0irrelevantdata\0", + ); + f.wait_and_dispatch(); + + let data = f.testwl.get_surface_data(surface).unwrap(); + assert_eq!(data.toplevel().title, Some("title".into())); +}