diff options
author | Colin Walters <walters@verbum.org> | 2010-01-07 16:12:15 -0500 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2010-01-12 17:13:10 -0500 |
commit | e7b9f873f0152136af60753598077156e7ae1545 (patch) | |
tree | e882b6c4db84a68f5dfacae68094e8f3223fda1b /girepository | |
parent | 95376a93bc6df5a1385e719b6a37304ba6925c72 (diff) | |
download | gobject-introspection-e7b9f873f0152136af60753598077156e7ae1545.tar.gz |
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
Diffstat (limited to 'girepository')
-rw-r--r-- | girepository/ginfo.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/girepository/ginfo.c b/girepository/ginfo.c index b11cc8fc..ed2fc93d 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; |