[gobject-introspection] Correctly cast to a CommonBlob when looking up embedded types



commit e7b9f873f0152136af60753598077156e7ae1545
Author: Colin Walters <walters verbum org>
Date:   Thu Jan 7 16:12:15 2010 -0500

    Correctly cast to a CommonBlob when looking up embedded types
    
    When looking at an embedded type (e.g. a Callback after a Field), the
    offset we put in the info structure was to the CallbackBlob itself.
    
    However the code in g_type_info_get_interface assumed that the offset
    was to a SimpleTypeBlob, which it wasn't.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=606180

 girepository/ginfo.c |   36 ++++++++++++++++++++++++++++--------
 1 files changed, 28 insertions(+), 8 deletions(-)
---
diff --git a/girepository/ginfo.c b/girepository/ginfo.c
index b11cc8f..ed2fc93 100644
--- a/girepository/ginfo.c
+++ b/girepository/ginfo.c
@@ -997,18 +997,38 @@ GIBaseInfo *
 g_type_info_get_interface (GITypeInfo *info)
 {
   GIRealInfo *rinfo = (GIRealInfo *)info;
-  SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
 
+  /* For embedded types, the given offset is a pointer to the actual blob,
+   * after the end of the field.  In that case we know it's a "subclass" of
+   * CommonBlob, so use that to determine the info type.
+   */
   if (rinfo->type_is_embedded)
-    return (GIBaseInfo *) g_info_new (type->offset, (GIBaseInfo*)info, rinfo->typelib,
-                                      rinfo->offset);
+    {
+      CommonBlob *common = (CommonBlob *)&rinfo->typelib->data[rinfo->offset];
+      GIInfoType info_type;
 
-  if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
+      switch (common->blob_type)
+        {
+          case BLOB_TYPE_CALLBACK:
+            info_type = GI_INFO_TYPE_CALLBACK;
+            break;
+          default:
+            g_assert_not_reached ();
+            return NULL;
+        }
+      return (GIBaseInfo *) g_info_new (info_type, (GIBaseInfo*)info, rinfo->typelib,
+                                        rinfo->offset);
+    }
+  else
     {
-      InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset];
-      
-      if (blob->tag == GI_TYPE_TAG_INTERFACE)
-        return g_info_from_entry (rinfo->repository, rinfo->typelib, blob->interface);
+      SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
+      if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
+        {
+          InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset];
+
+          if (blob->tag == GI_TYPE_TAG_INTERFACE)
+            return g_info_from_entry (rinfo->repository, rinfo->typelib, blob->interface);
+        }
     }
 
   return NULL;



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