data_device: Fix crash when destroying data_offer 22/280022/1
authorSeunghun Lee <shiin.lee@samsung.com>
Thu, 18 Aug 2022 01:46:12 +0000 (10:46 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Mon, 22 Aug 2022 09:08:16 +0000 (18:08 +0900)
The listener of destroy of data_source has to be removed when destroying
data_offer no matter whether offer->source is null or not.
That's because there is the case where calls data_offer_destroy after
nullifying offer->source.

Change-Id: I3c2fd97de39b52b4cae4de4c1390e773fb7c1047

src/data_device/data_offer.c

index eff2406..81a2b44 100644 (file)
@@ -97,21 +97,18 @@ void
 data_offer_destroy(struct ds_data_offer *offer)
 {
     wl_list_remove(&offer->link);
+    wl_list_remove(&offer->source_destroy.link);
 
-    if (offer->source) {
-        wl_list_remove(&offer->source_destroy.link);
-
+    if (offer->type == DS_DATA_OFFER_DRAG && offer->source) {
         // If the drag destination has version < 3, wl_data_offer.finish
         // won't be called, so do this here as a safety net, because
         // we still want the version >= 3 drag source to be happy.
-        if (offer->type == DS_DATA_OFFER_DRAG) {
-            if (wl_resource_get_version(offer->resource) <
-                    WL_DATA_OFFER_ACTION_SINCE_VERSION) {
-                data_offer_source_dnd_finish(offer);
-            }
-            else if (offer->source->iface->dnd_finish) {
-                ds_data_source_destroy(offer->source);
-            }
+        if (wl_resource_get_version(offer->resource) <
+                WL_DATA_OFFER_ACTION_SINCE_VERSION) {
+            data_offer_source_dnd_finish(offer);
+        }
+        else if (offer->source->iface->dnd_finish) {
+            ds_data_source_destroy(offer->source);
         }
     }
 
@@ -139,9 +136,7 @@ data_offer_handle_source_destroy(struct wl_listener *listener, void *data)
 
     offer = wl_container_of(listener, offer, source_destroy);
 
-    wl_list_remove(&offer->source_destroy.link);
     offer->source = NULL;
-
     data_offer_destroy(offer);
 }