diff --git a/ginfo.c b/ginfo.c index 934961141..6d66de21b 100644 --- a/ginfo.c +++ b/ginfo.c @@ -161,35 +161,29 @@ g_info_from_entry (GMetadata *metadata, { GIBaseInfo *result; DirEntry *entry = g_metadata_get_dir_entry (metadata, index); - + if (entry->local) result = g_info_new (entry->blob_type, NULL, metadata, entry->offset); - else + else { - const gchar *namespace = NULL; - const gchar *name = NULL; + const gchar *namespace = g_metadata_get_string (metadata, entry->offset); + const gchar *name = g_metadata_get_string (metadata, entry->name); + GIRepository *repository = g_irepository_get_default (); - - namespace = g_metadata_get_string (metadata, entry->offset); - name = g_metadata_get_string (metadata, entry->name); - + result = g_irepository_find_by_name (repository, namespace, name); if (result == NULL) { GIUnresolvedInfo *unresolved; + unresolved = g_new0 (GIUnresolvedInfo, 1); + unresolved->type = GI_INFO_TYPE_UNRESOLVED; unresolved->ref_count = 1; unresolved->container = NULL; unresolved->name = name; - if (entry->offset) - { - unresolved->namespace = namespace; - } - else - { - unresolved->namespace = NULL; - } + unresolved->namespace = namespace; + result = (GIBaseInfo*)unresolved; } } @@ -534,27 +528,15 @@ signature_offset (GICallableInfo *info) return 0; } -/* Type blobs when created always point to a SimpleTypeBlob, - * If the type tag means that the type needs to be complex then - * the SimpleTypeBlob has an offset which points to the real type. - */ GITypeInfo * g_type_info_new (GIBaseInfo *container, GMetadata *metadata, guint32 offset) { - TypeHeader *header; - SimpleTypeBlob *simple; + SimpleTypeBlob *type = (SimpleTypeBlob *)&metadata->data[offset]; - header = (TypeHeader *)&metadata->data[offset]; - if (TYPE_IS_COMPLEX (header->tag)) - { - simple = (SimpleTypeBlob *)&metadata->data[offset]; - offset = simple->offset; - } - - return (GITypeInfo*)g_info_new (GI_INFO_TYPE_TYPE, container, - metadata, offset); + return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, metadata, + type->reserved == 0 ? offset : type->offset); } /** @@ -739,18 +721,32 @@ gboolean g_type_info_is_pointer (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; - - return header->pointer != 0; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved == 0) + return type->pointer; + else + { + InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->metadata->data[base->offset]; + + return iface->pointer; + } } GITypeTag g_type_info_get_tag (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; - return header->tag; + if (type->reserved == 0) + return type->tag; + else + { + InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->metadata->data[base->offset]; + + return iface->tag; + } } GITypeInfo * @@ -758,39 +754,42 @@ g_type_info_get_param_type (GITypeInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; - ParamTypeBlob *param = (ParamTypeBlob *)&base->metadata->data[base->offset]; - - switch (header->tag) + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved != 0) { - case TYPE_TAG_ARRAY: - case TYPE_TAG_LIST: - case TYPE_TAG_SLIST: - case TYPE_TAG_HASH: - { - guint32 offset = base->offset + sizeof(ParamTypeBlob) + - (sizeof(SimpleTypeBlob)* n); - return g_type_info_new (base, base->metadata, offset); - } - default: - return NULL; - } + ParamTypeBlob *param = (ParamTypeBlob *)&base->metadata->data[base->offset]; - g_assert_not_reached (); + switch (param->tag) + { + case GI_TYPE_TAG_ARRAY: + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: + case GI_TYPE_TAG_GHASH: + return g_type_info_new (base, base->metadata, base->offset + 4 + 4 * n); + break; + + default: ; + } + } + + return NULL; } GIBaseInfo * g_type_info_get_interface (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; - SimpleTypeBlob *simple = (SimpleTypeBlob *)&base->metadata->data[base->offset]; - - if (header->tag == TYPE_TAG_SYMBOL) + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved != 0) { - CommonBlob *common = (CommonBlob *)&base->metadata->data[simple->offset]; - return g_info_from_entry (base->metadata, simple->offset); + InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->metadata->data[base->offset]; + + if (blob->tag == GI_TYPE_TAG_INTERFACE) + return g_info_from_entry (base->metadata, blob->interface); } + return NULL; } @@ -798,13 +797,19 @@ gint g_type_info_get_array_length (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; - ArrayTypeBlob *array = (ArrayTypeBlob *)&base->metadata->data[base->offset]; - - if (header->tag == TYPE_TAG_ARRAY && array->has_length) + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved != 0) { - return array->length; + ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->metadata->data[base->offset]; + + if (blob->tag == GI_TYPE_TAG_ARRAY) + { + if (blob->has_length) + return blob->length; + } } + return -1; } @@ -812,24 +817,33 @@ gboolean g_type_info_is_zero_terminated (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; - ArrayTypeBlob *array = (ArrayTypeBlob *)&base->metadata->data[base->offset]; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved != 0) + { + ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->metadata->data[base->offset]; - return (header->tag == TYPE_TAG_ARRAY && - array->zero_terminated); + if (blob->tag == GI_TYPE_TAG_ARRAY) + return blob->zero_terminated; + } + + return FALSE; } gint g_type_info_get_n_error_domains (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; - ErrorTypeBlob *error = (ErrorTypeBlob *)&base->metadata->data[base->offset]; - - if (header->tag == TYPE_TAG_ERROR) + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved != 0) { - return error->n_domains; + ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->metadata->data[base->offset]; + + if (blob->tag == GI_TYPE_TAG_ERROR) + return blob->n_domains; } + return 0; } @@ -838,16 +852,17 @@ g_type_info_get_error_domain (GITypeInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; - ErrorTypeBlob *error = (ErrorTypeBlob *)&base->metadata->data[base->offset]; - guint16 *domain; - - if (header->tag == TYPE_TAG_ERROR) + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved != 0) { - domain = (guint16*) (&base->metadata->data[base->offset + sizeof(ErrorTypeBlob)]); - return (GIErrorDomainInfo *) g_info_from_entry (base->metadata, - domain[n]); + ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->metadata->data[base->offset]; + + if (blob->tag == GI_TYPE_TAG_ERROR) + return (GIErrorDomainInfo *) g_info_from_entry (base->metadata, + blob->domains[n]); } + return NULL; } @@ -866,13 +881,9 @@ GIInterfaceInfo * g_error_domain_info_get_codes (GIErrorDomainInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->metadata->data[base->offset]; - - /* FIXME need to check if blob really is an enum */ - return (GIInterfaceInfo *) g_info_new (BLOB_TYPE_ENUM, - NULL, - base->metadata, - blob->error_codes); + ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->metadata->data[base->offset]; + + return (GIInterfaceInfo *) g_info_from_entry (base->metadata, blob->error_codes); } @@ -999,8 +1010,8 @@ g_struct_info_get_method (GIStructInfo *info, gint offset; offset = base->offset + header->struct_blob_size - + blob->n_fields * header->field_blob_size - + n * header->function_blob_size; + + blob->n_fields * header->field_blob_size + + n * header->function_blob_size; return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, base->metadata, offset); } @@ -1054,15 +1065,6 @@ g_enum_info_get_n_values (GIEnumInfo *info) return blob->n_values; } -gboolean -g_enum_info_is_registered (GIEnumInfo *info) -{ - GIBaseInfo *base = (GIBaseInfo *)info; - EnumBlob *blob = (EnumBlob *)&base->metadata->data[base->offset]; - - return !blob->unregistered; -} - GIValueInfo * g_enum_info_get_value (GIEnumInfo *info, gint n) @@ -1073,8 +1075,7 @@ g_enum_info_get_value (GIEnumInfo *info, offset = base->offset + header->enum_blob_size + n * header->value_blob_size; - return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, base, - base->metadata, offset); + return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, base, base->metadata, offset); } /* GIObjectInfo functions */ @@ -1123,11 +1124,8 @@ g_object_info_get_interface (GIObjectInfo *info, { GIBaseInfo *base = (GIBaseInfo *)info; ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; - guint16 *interface; - interface = (guint16 *)&base->metadata->data[base->offset + sizeof(ObjectBlob)]; - - return (GIInterfaceInfo *) g_info_from_entry (base->metadata, interface[n]); + return (GIInterfaceInfo *) g_info_from_entry (base->metadata, blob->interfaces[n]); } gint @@ -1152,8 +1150,7 @@ g_object_info_get_field (GIObjectInfo *info, + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + n * header->field_blob_size; - return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, - base->metadata, offset); + return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->metadata, offset); } gint @@ -1335,11 +1332,8 @@ g_interface_info_get_prerequisite (GIInterfaceInfo *info, { GIBaseInfo *base = (GIBaseInfo *)info; InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; - guint16 *prerequisite; - prerequisite = (guint16 *)&base->metadata->data[base->offset + sizeof(InterfaceBlob)]; - - return g_info_from_entry (base->metadata, prerequisite[n]); + return g_info_from_entry (base->metadata, blob->prerequisites[n]); } @@ -1578,8 +1572,7 @@ g_signal_info_get_class_closure (GISignalInfo *info) SignalBlob *blob = (SignalBlob *)&base->metadata->data[base->offset]; if (blob->has_class_closure) - return g_interface_info_get_vfunc ((GIInterfaceInfo *)base->container, - blob->class_closure); + return g_interface_info_get_vfunc ((GIInterfaceInfo *)base->container, blob->class_closure); return NULL; } @@ -1653,67 +1646,63 @@ g_constant_info_get_value (GIConstantInfo *info, { GIBaseInfo *base = (GIBaseInfo *)info; ConstantBlob *blob = (ConstantBlob *)&base->metadata->data[base->offset]; - TypeHeader *header = (TypeHeader*) &blob->type; - if (TYPE_IS_SIMPLE (header->tag)) + /* FIXME non-basic types ? */ + if (blob->type.reserved == 0) { - switch (header->tag) - { - case GI_TYPE_TAG_BOOLEAN: - value->v_boolean = *(gboolean*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_INT8: - value->v_int8 = *(gint8*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_UINT8: - value->v_uint8 = *(guint8*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_INT16: - value->v_int16 = *(gint16*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_UINT16: - value->v_uint16 = *(guint16*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_INT32: - value->v_int32 = *(gint32*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_UINT32: - value->v_uint32 = *(guint32*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_INT64: - value->v_int64 = *(gint64*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_UINT64: - value->v_uint64 = *(guint64*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_FLOAT: - value->v_float = *(gfloat*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_DOUBLE: - value->v_double = *(gdouble*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_INT: - value->v_int = *(gint*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_UINT: - value->v_uint = *(guint*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_LONG: - value->v_long = *(glong*)&base->metadata->data[blob->offset]; - break; - case GI_TYPE_TAG_ULONG: - value->v_ulong = *(gulong*)&base->metadata->data[blob->offset]; - break; - } - } - else - { - switch (header->tag) - { - case GI_TYPE_TAG_SYMBOL: - value->v_string = *(gchar**)&base->metadata->data[blob->offset]; - break; - } + if (blob->type.pointer) + value->v_pointer = g_memdup (&base->metadata->data[blob->offset], blob->size); + else + { + switch (blob->type.tag) + { + case GI_TYPE_TAG_BOOLEAN: + value->v_boolean = *(gboolean*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_INT8: + value->v_int8 = *(gint8*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_UINT8: + value->v_uint8 = *(guint8*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_INT16: + value->v_int16 = *(gint16*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_UINT16: + value->v_uint16 = *(guint16*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_INT32: + value->v_int32 = *(gint32*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_UINT32: + value->v_uint32 = *(guint32*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_INT64: + value->v_int64 = *(gint64*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_UINT64: + value->v_uint64 = *(guint64*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_FLOAT: + value->v_float = *(gfloat*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_DOUBLE: + value->v_double = *(gdouble*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_INT: + value->v_int = *(gint*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_UINT: + value->v_uint = *(guint*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_LONG: + value->v_long = *(glong*)&base->metadata->data[blob->offset]; + break; + case GI_TYPE_TAG_ULONG: + value->v_ulong = *(gulong*)&base->metadata->data[blob->offset]; + break; + } + } } return blob->size; @@ -1814,4 +1803,4 @@ g_union_info_get_discriminator (GIUnionInfo *info, } return NULL; -} +} diff --git a/ginvoke.c b/ginvoke.c index 6324536aa..986ca7850 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -100,8 +100,8 @@ get_ffi_type (GITypeInfo *info) break; case GI_TYPE_TAG_UTF8: case GI_TYPE_TAG_FILENAME: - case GI_TYPE_TAG_SYMBOL: case GI_TYPE_TAG_ARRAY: + case GI_TYPE_TAG_INTERFACE: case GI_TYPE_TAG_GLIST: case GI_TYPE_TAG_GSLIST: case GI_TYPE_TAG_GHASH: diff --git a/girepository.h b/girepository.h index 0c1ac6630..7ad1067a1 100644 --- a/girepository.h +++ b/girepository.h @@ -277,8 +277,8 @@ typedef enum { GI_TYPE_TAG_DOUBLE = 17, GI_TYPE_TAG_UTF8 = 18, GI_TYPE_TAG_FILENAME = 19, - GI_TYPE_TAG_SYMBOL = 20, - GI_TYPE_TAG_ARRAY = 21, + GI_TYPE_TAG_ARRAY = 20, + GI_TYPE_TAG_INTERFACE = 21, GI_TYPE_TAG_GLIST = 22, GI_TYPE_TAG_GSLIST = 23, GI_TYPE_TAG_GHASH = 24, @@ -355,7 +355,6 @@ const gchar * g_registered_type_info_get_type_init (GIRegisteredTypeInf /* GIEnumInfo */ gint g_enum_info_get_n_values (GIEnumInfo *info); -gboolean g_enum_info_get_is_registered (GIEnumInfo *info); GIValueInfo * g_enum_info_get_value (GIEnumInfo *info, gint n); diff --git a/gmetadata.c b/gmetadata.c index 8c9827023..b68039043 100644 --- a/gmetadata.c +++ b/gmetadata.c @@ -30,11 +30,6 @@ #define ALIGN_VALUE(this, boundary) \ (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) -static gboolean -validate_blob (GMetadata *metadata, - guint32 offset, - GError **error); - DirEntry * g_metadata_get_dir_entry (GMetadata *metadata, @@ -42,9 +37,41 @@ g_metadata_get_dir_entry (GMetadata *metadata, { Header *header = (Header *)metadata->data; - return (DirEntry *)&metadata->data[header->directory + ((index - 1) * header->entry_blob_size)]; + return (DirEntry *)&metadata->data[header->directory + (index - 1) * header->entry_blob_size]; } +void +g_metadata_check_sanity (void) +{ + /* Check that struct layout is as we expect */ + g_assert (sizeof (Header) == 100); + g_assert (sizeof (DirEntry) == 12); + g_assert (sizeof (SimpleTypeBlob) == 4); + g_assert (sizeof (ArgBlob) == 12); + g_assert (sizeof (SignatureBlob) == 8); + g_assert (sizeof (CommonBlob) == 8); + g_assert (sizeof (FunctionBlob) == 16); + g_assert (sizeof (InterfaceTypeBlob) == 4); + g_assert (sizeof (ArrayTypeBlob) == 8); + g_assert (sizeof (ParamTypeBlob) == 4); + g_assert (sizeof (ErrorTypeBlob) == 4); + g_assert (sizeof (ErrorDomainBlob) == 16); + g_assert (sizeof (ValueBlob) == 12); + g_assert (sizeof (FieldBlob) == 12); + g_assert (sizeof (RegisteredTypeBlob) == 16); + g_assert (sizeof (StructBlob) == 20); + g_assert (sizeof (EnumBlob) == 20); + g_assert (sizeof (PropertyBlob) == 12); + g_assert (sizeof (SignalBlob) == 12); + g_assert (sizeof (VFuncBlob) == 16); + g_assert (sizeof (ObjectBlob) == 32); + g_assert (sizeof (InterfaceBlob) == 28); + g_assert (sizeof (ConstantBlob) == 20); + g_assert (sizeof (AnnotationBlob) == 12); + g_assert (sizeof (UnionBlob) == 28); +} + + static gboolean is_aligned (guint32 offset) { @@ -124,6 +151,32 @@ validate_header (GMetadata *metadata, return FALSE; } + if (header->entry_blob_size != 12 || + header->function_blob_size != 16 || + header->callback_blob_size != 12 || + header->signal_blob_size != 12 || + header->vfunc_blob_size != 16 || + header->arg_blob_size != 12 || + header->property_blob_size != 12 || + header->field_blob_size != 12 || + header->value_blob_size != 12 || + header->constant_blob_size != 20 || + header->error_domain_blob_size != 16 || + header->annotation_blob_size != 12 || + header->signature_blob_size != 8 || + header->enum_blob_size != 20 || + header->struct_blob_size != 20 || + header->object_blob_size != 32 || + header->interface_blob_size != 28 || + header->union_blob_size != 28) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_HEADER, + "Blob size mismatch"); + return FALSE; + } + if (!is_aligned (header->directory)) { g_set_error (error, @@ -176,16 +229,17 @@ validate_array_type_blob (GMetadata *metadata, gboolean return_type, GError **error) { - ArrayTypeBlob *blob = (ArrayTypeBlob*)&metadata->data[offset]; - TypeHeader *header = (TypeHeader *)&metadata->data[offset]; + ArrayTypeBlob *blob; - if (!header->pointer) + blob = (ArrayTypeBlob*)&metadata->data[offset]; + + if (!blob->pointer) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", header->tag); - return FALSE; + "Pointer type exected for tag %d", blob->tag); + return FALSE; } /* FIXME validate length */ @@ -198,6 +252,32 @@ validate_array_type_blob (GMetadata *metadata, return TRUE; } +static gboolean +validate_iface_type_blob (GMetadata *metadata, + guint32 offset, + guint32 signature_offset, + gboolean return_type, + GError **error) +{ + InterfaceTypeBlob *blob; + Header *header; + + header = (Header *)metadata->data; + + blob = (InterfaceTypeBlob*)&metadata->data[offset]; + + if (blob->interface == 0 || blob->interface > header->n_entries) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid directory index %d", blob->interface); + return FALSE; + } + + return TRUE; +} + static gboolean validate_param_type_blob (GMetadata *metadata, guint32 offset, @@ -206,17 +286,17 @@ validate_param_type_blob (GMetadata *metadata, gint n_params, GError **error) { - ParamTypeBlob *blob = (ParamTypeBlob*)&metadata->data[offset]; - TypeHeader *header = (TypeHeader *)&metadata->data[offset]; + ParamTypeBlob *blob; gint i; + blob = (ParamTypeBlob*)&metadata->data[offset]; - if (!header->pointer) + if (!blob->pointer) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", header->tag); + "Pointer type exected for tag %d", blob->tag); return FALSE; } @@ -249,39 +329,35 @@ validate_error_type_blob (GMetadata *metadata, GError **error) { ErrorTypeBlob *blob; - TypeHeader *type_header; Header *header; gint i; DirEntry *entry; - guint16 *domain; blob = (ErrorTypeBlob*)&metadata->data[offset]; - type_header = (TypeHeader*)&metadata->data[offset]; header = (Header *)metadata->data; - if (!type_header->pointer) + if (!blob->pointer) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", type_header->tag); - return FALSE; + "Pointer type exected for tag %d", blob->tag); + return FALSE; } - domain = (guint16*)&metadata->data[offset + sizeof(ErrorTypeBlob)]; - for (i = 0; i < blob->n_domains; i++, domain++) + for (i = 0; i < blob->n_domains; i++) { - if (*domain == 0 || *domain > header->n_entries) + if (blob->domains[i] == 0 || blob->domains[i] > header->n_entries) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Invalid directory index %d", *domain); + "Invalid directory index %d", blob->domains[i]); return FALSE; } - entry = g_metadata_get_dir_entry (metadata, *domain); + entry = g_metadata_get_dir_entry (metadata, blob->domains[i]); if (entry->blob_type != BLOB_TYPE_ERROR_DOMAIN && (entry->local || entry->blob_type != BLOB_TYPE_INVALID)) @@ -305,14 +381,14 @@ validate_type_blob (GMetadata *metadata, GError **error) { SimpleTypeBlob *simple; - TypeHeader *header; - + InterfaceTypeBlob *iface; + simple = (SimpleTypeBlob *)&metadata->data[offset]; - header = (TypeHeader *)&metadata->data[offset]; - if (TYPE_IS_SIMPLE(header->tag)) + if (simple->reserved == 0 && + simple->reserved2 == 0) { - if (header->tag >= TYPE_TAG_ARRAY) + if (simple->tag >= TYPE_TAG_ARRAY) { g_set_error (error, G_METADATA_ERROR, @@ -321,29 +397,31 @@ validate_type_blob (GMetadata *metadata, return FALSE; } - if (header->tag >= TYPE_TAG_UTF8 && - !header->pointer) + if (simple->tag >= TYPE_TAG_UTF8 && + !simple->pointer) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", header->tag); - return FALSE; + "Pointer type exected for tag %d", simple->tag); + return FALSE; } return TRUE; } - switch (header->tag) + iface = (InterfaceTypeBlob*)&metadata->data[simple->offset]; + + switch (iface->tag) { case TYPE_TAG_ARRAY: if (!validate_array_type_blob (metadata, simple->offset, signature_offset, return_type, error)) return FALSE; break; - case TYPE_TAG_SYMBOL: - if (!validate_blob (metadata, simple->offset, - error)) + case TYPE_TAG_INTERFACE: + if (!validate_iface_type_blob (metadata, simple->offset, + signature_offset, return_type, error)) return FALSE; break; case TYPE_TAG_LIST: @@ -608,7 +686,6 @@ validate_constant_blob (GMetadata *metadata, 0, 0 }; ConstantBlob *blob; - TypeHeader *header; SimpleTypeBlob *type; if (metadata->len < offset + sizeof (ConstantBlob)) @@ -652,12 +729,11 @@ validate_constant_blob (GMetadata *metadata, "Misaligned constant value"); return FALSE; } - + type = (SimpleTypeBlob *)&metadata->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)]; - header = (TypeHeader *)&metadata->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)]; - if (TYPE_IS_SIMPLE(header->tag)) + if (type->reserved == 0) { - if (header->tag == 0) + if (type->tag == 0) { g_set_error (error, G_METADATA_ERROR, @@ -666,8 +742,8 @@ validate_constant_blob (GMetadata *metadata, return FALSE; } - if (value_size[header->tag] != 0 && - blob->size != value_size[header->tag]) + if (value_size[type->tag] != 0 && + blob->size != value_size[type->tag]) { g_set_error (error, G_METADATA_ERROR, @@ -988,6 +1064,17 @@ validate_struct_blob (GMetadata *metadata, return FALSE; } } + else + { + if (blob->gtype_name || blob->gtype_init) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Gtype data in struct"); + return FALSE; + } + } if (metadata->len < offset + sizeof (StructBlob) + blob->n_fields * sizeof (FieldBlob) + @@ -1073,6 +1160,17 @@ validate_enum_blob (GMetadata *metadata, return FALSE; } } + else + { + if (blob->gtype_name || blob->gtype_init) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Gtype data in unregistered enum"); + return FALSE; + } + } if (!is_name (metadata->data, blob->name)) { diff --git a/gmetadata.h b/gmetadata.h index aa4166289..a22ee235e 100644 --- a/gmetadata.h +++ b/gmetadata.h @@ -28,7 +28,6 @@ G_BEGIN_DECLS #define G_IDL_MAGIC "GOBJ\nMETADATA\r\n\032" -#define G_IDL_MAGIC_ESCAPED "GOBJ\\nMETADATA\\r\\n\\032" enum { @@ -96,6 +95,10 @@ typedef struct guint32 offset; } DirEntry; + +#define TYPE_POINTER_MASK 1 << 7 +#define TYPE_TAG_MASK 63 + typedef enum { TYPE_TAG_VOID = 0, @@ -118,34 +121,28 @@ typedef enum TYPE_TAG_DOUBLE = 17, TYPE_TAG_UTF8 = 18, TYPE_TAG_FILENAME = 19, - TYPE_TAG_SYMBOL = 20, - TYPE_TAG_ARRAY = 21, + TYPE_TAG_ARRAY = 20, + TYPE_TAG_INTERFACE = 21, TYPE_TAG_LIST = 22, TYPE_TAG_SLIST = 23, TYPE_TAG_HASH = 24, TYPE_TAG_ERROR = 25 } TypeTag; -typedef struct +typedef union { - guint pointer :1; - guint reserved :2; - guint tag :5; -} TypeHeader; - -#define TYPE_IS_SIMPLE(tAG) (tAG < TYPE_TAG_SYMBOL ? TRUE : FALSE) - -#define TYPE_IS_SYMBOL(tAG) (tAG == TYPE_TAG_SYMBOL ? TRUE : FALSE) - -#define TYPE_IS_COMPLEX(tAG) (tAG > TYPE_TAG_SYMBOL ? TRUE : FALSE) - -typedef struct -{ - TypeHeader header; - + struct + { + guint reserved : 8; + guint reserved2 :16; + guint pointer : 1; + guint reserved3 : 2; + guint tag : 5; + }; guint32 offset; } SimpleTypeBlob; + typedef struct { guint32 name; @@ -174,9 +171,7 @@ typedef struct guint16 n_arguments; -#if 0 ArgBlob arguments[]; -#endif } SignatureBlob; typedef struct @@ -217,13 +212,25 @@ typedef struct guint32 signature; } CallbackBlob; +typedef struct +{ + guint pointer :1; + guint reserved :2; + guint tag :5; + guint8 reserved2; + guint16 interface; +} InterfaceTypeBlob; + typedef struct { - TypeHeader header; + guint pointer :1; + guint reserved :2; + guint tag :5; guint zero_terminated :1; guint has_length :1; guint reserved2 :6; + guint16 length; SimpleTypeBlob type; @@ -231,24 +238,26 @@ typedef struct typedef struct { - TypeHeader header; + guint pointer :1; + guint reserved :2; + guint tag :5; guint8 reserved2; guint16 n_types; -#if 0 + SimpleTypeBlob type[]; -#endif } ParamTypeBlob; typedef struct { - TypeHeader header; + guint pointer :1; + guint reserved :2; + guint tag :5; + guint8 reserved2; guint16 n_domains; -#if 0 guint16 domains[]; -#endif } ErrorTypeBlob; typedef struct @@ -362,9 +371,7 @@ typedef struct guint16 n_values; guint16 reserved2; -#if 0 - ValueBlob values[]; -#endif + ValueBlob values[]; } EnumBlob; typedef struct @@ -439,9 +446,10 @@ typedef struct guint16 n_vfuncs; guint16 n_constants; + guint16 interfaces[]; + #if 0 /* variable-length parts of the blob */ - guint16 interfaces[]; FieldBlob fields[]; PropertyBlob properties[]; FunctionBlob methods[]; @@ -468,10 +476,10 @@ typedef struct guint16 n_vfuncs; guint16 n_constants; + guint16 prerequisites[]; -#if 0 +#if 0 /* variable-length parts of the blob */ - guint16 prerequisites[]; PropertyBlob properties[]; FunctionBlob methods[]; SignalBlob signals[]; @@ -513,8 +521,11 @@ struct _GMetadata { DirEntry *g_metadata_get_dir_entry (GMetadata *metadata, guint16 index); +void g_metadata_check_sanity (void); + #define g_metadata_get_string(metadata,offset) ((const gchar*)&(metadata->data)[(offset)]) + typedef enum { G_METADATA_ERROR_INVALID,