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
This commit is contained in:
Colin Walters 2010-01-07 16:12:15 -05:00
parent 109159ee05
commit 7d5da3d09f

38
ginfo.c
View File

@ -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);
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);
CommonBlob *common = (CommonBlob *)&rinfo->typelib->data[rinfo->offset];
GIInfoType info_type;
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
{
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;