From: Colin Walters Date: Thu, 7 Jan 2010 21:12:15 +0000 (-0500) Subject: Correctly cast to a CommonBlob when looking up embedded types X-Git-Tag: GOBJECT_INTROSPECTION_0_6_8~21 X-Git-Url: http://git.roojs.org/?p=gnome.gobject-introspection;a=commitdiff_plain;h=e7b9f873f0152136af60753598077156e7ae1545 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 --- 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;