gtk-rs / gtk4-rs

Rust bindings of GTK 4
https://gtk-rs.org/gtk4-rs/
MIT License
1.9k stars 174 forks source link

Segfault in `content_provider_get_value` from dereferencing null `error_ptr` #1671

Closed awused closed 7 months ago

awused commented 7 months ago

Bug description

Drag and drop with a ContentProvider that doesn't implement ContentProviderImpl::value onto a gtk::Entry in the same process.

Backtrace

You can get the backtrace running your program with the environment variable RUST_BACKTRACE=full.

#0  0x000055acb0b54877 in gdk4::subclass::content_provider::content_provider_get_value<aw_fm::gui::clipboard::imp::ClipboardProvider>
    (ptr=0x55acb58fede0, value_ptr=0x55acb52dbcf0, error_ptr=0x0)
    at /storage/src/third_party/gtk4-rs/gdk4/src/subclass/content_provider.rs:409
409             *error_ptr = e.into_glib_ptr();
[Current thread is 1 (Thread 0x7f701f2dbec0 (LWP 296838))]
warning: Missing auto-load script at offset 0 in section .debug_gdb_scripts
of file /cache/rust/debug/aw-fm.
Use `info auto-load python-scripts [REGEXP]' to list them.
Missing separate debuginfos, use: dnf debuginfo-install xorg-x11-drv-nvidia-libs-545.29.06-2.fc39.x86_64
(gdb) bt full
#0  0x000055acb0b54877 in gdk4::subclass::content_provider::content_provider_get_value<aw_fm::gui::clipboard::imp::ClipboardProvider>
    (ptr=0x55acb58fede0, value_ptr=0x55acb52dbcf0, error_ptr=0x0)
    at /storage/src/third_party/gtk4-rs/gdk4/src/subclass/content_provider.rs:409
        e = glib::error::Error {inner: glib::boxed::Boxed<glib_sys::GError, glib::error::Error> {inner: core::ptr::non_null::NonNull<glib_sys::GError> {pointer: 0x55acb5a8c080}, _dummy: core::marker::PhantomData<*mut glib::error::Error>}}
        ret = core::result::Result<glib::value::Value, glib::error::Error>::Err(glib::error::Error {inner: glib::boxed::Boxed<glib_sys::GError, glib::error::Error> {inner: core::ptr::non_null::NonNull<glib_sys::GError> {pointer: 0x55acb5a8c080}, _dummy: core::marker::PhantomData<*mut glib::error::Error>}})
        value = glib::value::Value {inner: gobject_sys::GValue {g_type: 64, data: [gobject_sys::GValue_data {v_int: 0, v_uint: 0, v_long: 0, v_ulong: 0, v_int64: 0, v_uint64: 0, v_float: 0, v_double: 0, v_pointer: 0x0}, gobject_sys::GValue_data {v_int: 0, v_uint: 0, v_long: 0, v_ulong: 0, v_int64: 0, v_uint64: 0, v_float: 0, v_double: 0, v_pointer: 0x0}]}}
        imp = 0x55acb58fedb0
        instance = 0x55acb58fede0
#1  0x00007f7020e70fb1 in gtk_drop_target_load_local (type=0x40 [gchararray], self=0x55acb52dbcb0 [GtkDropTarget])
    at ../gtk/gtkdroptarget.c:293
        drag = 0x55acb41582a0 [GdkX11Drag]
        drag = <optimized out>
#2  gtk_drop_target_load (self=self@entry=0x55acb52dbcb0 [GtkDropTarget]) at ../gtk/gtkdroptarget.c:321
        type = 0x40 [gchararray]
#3  0x00007f7020e714bb in gtk_drop_target_handle_event
    (controller=0x55acb52dbcb0 [GtkDropTarget], event=0x55acb58cc270 [GdkDNDEvent], x=363.99996948242188, y=9)
    at ../gtk/gtkdroptarget.c:463
        self = 0x55acb52dbcb0 [GtkDropTarget]
        __func__ = "gtk_drop_target_handle_event"
#4  0x00007f7020fce7df in gtk_event_controller_handle_event
    (y=<optimized out>, x=<optimized out>, target=<optimized out>, event=<optimized out>, controller=0x55acb52dbcb0 [GtkDropTarget])
    at ../gtk/gtkeventcontroller.c:362
        controller_class = 0x55acb38417e0
        priv = <optimized out>
        retval = 0
        controller_class = <optimized out>
        priv = <optimized out>
        retval = <optimized out>
        __func__ = {<optimized out> <repeats 34 times>}
        _g_boolean_var_13 = <optimized out>
        __inst = <optimized out>
        __t = <optimized out>
        __r = <optimized out>
        _g_boolean_var_14 = <optimized out>
        _pp = <optimized out>
        _ptr = <optimized out>
        _pp = <optimized out>
        _ptr = <optimized out>
#5  gtk_widget_run_controllers

I added some println debugging locally, and got Error { domain: g-io-error-quark, code: 15, message: "Cannot provide contents as gchararray" } as the value of e, though that doesn't seem to matter all that much since it's dereferencing a null error_ptr.

I worked around it locally by implementing ContentProviderImpl::value(), but there's something wrong with the implementation of content_provider_get_value if it segfaults instead of failing.

sdroege commented 7 months ago

This is probably fixed by https://github.com/gtk-rs/gtk4-rs/pull/1672. Can you confirm or provide a minimal testcase to reproduce the problem?

awused commented 7 months ago

I won't be able to test it myself until late tonight, though I expect that commit has fixed it since it was a pretty straightforward crash.

awused commented 7 months ago

Manually patched in https://github.com/gtk-rs/gtk4-rs/pull/1672 and it fixes the crash and actually makes the drag and drop work even without a ::value() implementation.

bilelmoussaoui commented 7 months ago

Thanks, will do a release sometime the upcoming weeks.