[gobject-introspection] girepository: Return pointer array for interface cache



commit e49cfb8d3462d624cad8b76c6560bd76996ed544
Author: Philip Chimento <philip chimento gmail com>
Date:   Thu Jun 20 00:18:13 2019 -0700

    girepository: Return pointer array for interface cache
    
    In g_irepository_get_object_gtype_interfaces(), returning the address of
    the first GIBaseInfo* does not work reliably, because the GIBaseInfos
    are not necessarily stored contiguously. So the second and subsequent
    ones might be garbage.
    
    Instead, return the address of the array of GIBaseInfo pointers.
    
    Add a test that verifies the functionality, as well.
    
    This is unfortunately an API and ABI break.

 girepository/girepository.c   |  6 +++---
 girepository/girepository.h   |  2 +-
 tests/repository/gitestrepo.c | 24 ++++++++++++++++++++++++
 3 files changed, 28 insertions(+), 4 deletions(-)
---
diff --git a/girepository/girepository.c b/girepository/girepository.c
index ca5dc2b9..08149da8 100644
--- a/girepository/girepository.c
+++ b/girepository/girepository.c
@@ -984,13 +984,13 @@ g_irepository_find_by_error_domain (GIRepository *repository,
  * returning a concrete class of #GLocalFile, which is a #GType we
  * see at runtime, but not statically.
  *
- * Since: 1.60
+ * Since: 1.62
  */
 void
 g_irepository_get_object_gtype_interfaces (GIRepository      *repository,
                                            GType              gtype,
                                            guint             *n_interfaces_out,
-                                           GIInterfaceInfo  **interfaces_out)
+                                           GIInterfaceInfo ***interfaces_out)
 {
   GTypeInterfaceCache *cache;
 
@@ -1039,7 +1039,7 @@ g_irepository_get_object_gtype_interfaces (GIRepository      *repository,
     }
 
   *n_interfaces_out = cache->n_interfaces;
-  *interfaces_out = *((GIInterfaceInfo**)&(cache->interfaces[0]));
+  *interfaces_out = (GIInterfaceInfo**)&cache->interfaces[0];
 }
 
 static void
diff --git a/girepository/girepository.h b/girepository/girepository.h
index 8dfcca2c..073985b6 100644
--- a/girepository/girepository.h
+++ b/girepository/girepository.h
@@ -163,7 +163,7 @@ GI_AVAILABLE_IN_1_60
 void          g_irepository_get_object_gtype_interfaces (GIRepository      *repository,
                                                          GType              gtype,
                                                          guint             *n_interfaces_out,
-                                                         GIInterfaceInfo  **interfaces_out);
+                                                         GIInterfaceInfo ***interfaces_out);
 
 GI_AVAILABLE_IN_ALL
 gint          g_irepository_get_n_infos   (GIRepository *repository,
diff --git a/tests/repository/gitestrepo.c b/tests/repository/gitestrepo.c
index 6c10b076..abe30d98 100644
--- a/tests/repository/gitestrepo.c
+++ b/tests/repository/gitestrepo.c
@@ -57,6 +57,29 @@ test_type_info_get_name (GIRepository *repo)
   g_base_info_unref ((GIBaseInfo*)typeinfo);
 }
 
+static void
+test_get_gtype_interfaces (GIRepository *repo)
+{
+  GIInterfaceInfo **interfaces;
+  guint n_interfaces, ix;
+  gboolean found_initable = FALSE, found_async_initable = FALSE;
+
+  g_irepository_get_object_gtype_interfaces (repo, G_TYPE_DBUS_CONNECTION, &n_interfaces, &interfaces);
+
+  g_assert_cmpuint (n_interfaces, ==, 2);
+
+  for (ix = 0; ix < n_interfaces; ix++)
+    {
+      const gchar *name = g_base_info_get_name(*(interfaces + ix));
+      if (strcmp (name, "Initable") == 0)
+        found_initable = TRUE;
+      else if (strcmp (name, "AsyncInitable") == 0)
+        found_async_initable = TRUE;
+    }
+
+  g_assert_true (found_initable);
+  g_assert_true (found_async_initable);
+}
 
 int
 main(int argc, char **argv)
@@ -161,6 +184,7 @@ main(int argc, char **argv)
   }
 
   test_type_info_get_name (repo);
+  test_get_gtype_interfaces (repo);
 
   /* Error quark tests */
   errorinfo = g_irepository_find_by_error_domain (repo, G_RESOLVER_ERROR);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]