DropTarget: Fix critical if reject drop pre-enter
authorDaniel Boles <dboles.src@gmail.com>
Tue, 27 Jun 2023 20:03:10 +0000 (21:03 +0100)
committerDaniel Boles <dboles.src@gmail.com>
Tue, 27 Jun 2023 20:37:32 +0000 (21:37 +0100)
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/5922

The docs of `Gtk.DropTarget::accept` say this:
> If the decision whether the drop will be accepted or rejected depends
> on the data, [`::accept`] should return `TRUE`, [`:preload`] should be
> set and the value should be inspected via the `::notify:value` signal,
> calling `gtk_drop_target_reject()` if required.

But this pattern causes a CRITICAL, given these steps:
* Create a `DragSource` and `DropTarget`
* Keep the default `::accept` handler and set `:preload` to `TRUE`
* Connect to `notify::value` and therein call `DropTarget.reject()`
* CRITICAL at `DropTarget.enter()`→`Drop.get_actions()` on NULL instance

We should let the documented case work without a CRITICAL or worse, null
deref. And per @otte on the bug, we should bail earlier before `::enter`
& setting `GTK_STATE_FLAG_DROP_ACTIVE`; neither should occur if rejected

This fixes that, by checking after `start_drop()` when notifications are
thawed, whether any handler has `reject()`ed & set our `drop` to `NULL`.

gtk/gtkdroptarget.c

index f99c476ac4e2ab094b5bff6030adff6721fe3886..c4871f106e8aebc571110b058ca3a62f07cf6b8e 100644 (file)
@@ -507,7 +507,12 @@ gtk_drop_target_handle_crossing (GtkEventController    *controller,
       graphene_point_init (&self->coords, x, y);
       gtk_drop_target_start_drop (self, crossing->drop);
 
-      g_signal_emit (self, signals[ENTER], 0, x, y, &preferred);
+      /* start_drop ends w/ thaw_notify, where handler may reject, so recheck */
+      if (self->drop != NULL)
+        g_signal_emit (self, signals[ENTER], 0, x, y, &preferred);
+      else
+        preferred = 0;
+
       if (!gdk_drag_action_is_unique (preferred))
         {
           g_critical ("Handler for GtkDropTarget::enter on %s %p did not return a unique preferred action",