Skip to content

Commit cbfb65b

Browse files
authored
Merge pull request #1768 from pjungkamp/g_list_store_find_with_equal_func
gio: Fix segfault in ListStore::find_with_equal_func
2 parents d54f65d + 64d2372 commit cbfb65b

File tree

1 file changed

+36
-17
lines changed

1 file changed

+36
-17
lines changed

gio/src/list_store.rs

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -150,34 +150,53 @@ impl ListStore {
150150
(*func)(&a).into_glib()
151151
}
152152

153-
unsafe {
154-
// GIO requires a non-NULL item to be passed in so we're constructing a fake item here.
155-
// See https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3284
153+
let mut func = equal_func;
154+
let func_obj: &mut (dyn FnMut(&Object) -> bool) = &mut func;
155+
let func_ptr = &func_obj as *const &mut (dyn FnMut(&Object) -> bool) as glib::ffi::gpointer;
156+
let mut position = std::mem::MaybeUninit::uninit();
157+
158+
// GIO prior to 2.76 requires a non-NULL item to be passed in so we're constructing a fake item here.
159+
// See https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3284
160+
#[cfg(not(feature = "v2_76"))]
161+
let result = unsafe {
162+
let g_class: *mut glib::gobject_ffi::GTypeClass =
163+
glib::gobject_ffi::g_type_class_peek(self.item_type().into_glib()) as *mut _;
164+
165+
// g_class will be `NULL` when no instance of the `item-type` has been created yet.
166+
// See https://github.com/gtk-rs/gtk-rs-core/issues/1767
167+
if g_class.is_null() {
168+
return None;
169+
}
170+
156171
let item = glib::gobject_ffi::GObject {
157-
g_type_instance: glib::gobject_ffi::GTypeInstance {
158-
g_class: glib::gobject_ffi::g_type_class_peek(self.item_type().into_glib())
159-
as *mut _,
160-
},
172+
g_type_instance: glib::gobject_ffi::GTypeInstance { g_class },
161173
ref_count: 1,
162174
qdata: std::ptr::null_mut(),
163175
};
164-
let mut func = equal_func;
165-
let func_obj: &mut (dyn FnMut(&Object) -> bool) = &mut func;
166-
let func_ptr =
167-
&func_obj as *const &mut (dyn FnMut(&Object) -> bool) as glib::ffi::gpointer;
168176

169-
let mut position = std::mem::MaybeUninit::uninit();
170-
171-
let found = bool::from_glib(ffi::g_list_store_find_with_equal_func_full(
177+
bool::from_glib(ffi::g_list_store_find_with_equal_func_full(
172178
self.to_glib_none().0,
173179
mut_override(&item as *const _),
174180
Some(equal_func_trampoline),
175181
func_ptr,
176182
position.as_mut_ptr(),
177-
));
183+
))
184+
.then(|| position.assume_init())
185+
};
178186

179-
found.then(|| position.assume_init())
180-
}
187+
#[cfg(feature = "v2_76")]
188+
let result = unsafe {
189+
bool::from_glib(ffi::g_list_store_find_with_equal_func_full(
190+
self.to_glib_none().0,
191+
std::ptr::null_mut(),
192+
Some(equal_func_trampoline),
193+
func_ptr,
194+
position.as_mut_ptr(),
195+
))
196+
.then(|| position.assume_init())
197+
};
198+
199+
result
181200
}
182201
}
183202

0 commit comments

Comments
 (0)