Revert revisions 157,149-148,136-129 and 120. Move back to using

2008-04-22  Johan Dahlin  <johan@gnome.org>

    * girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
    (g_type_info_is_pointer), (g_type_info_get_tag),
    (g_type_info_get_param_type), (g_type_info_get_interface),
    (g_type_info_get_array_length), (g_type_info_is_zero_terminated),
    (g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
    (g_error_domain_info_get_codes), (g_enum_info_get_value),
    (g_object_info_get_interface), (g_object_info_get_field),
    (g_interface_info_get_prerequisite),
    (g_signal_info_get_class_closure), (g_constant_info_get_value):
    * girepository/ginvoke.c (get_ffi_type):
    * girepository/girepository.h:
    * girepository/gmetadata.c (g_metadata_get_dir_entry),
    (g_metadata_check_sanity), (validate_header),
    (validate_array_type_blob), (validate_iface_type_blob),
    (validate_param_type_blob), (validate_error_type_blob),
    (validate_type_blob), (validate_constant_blob),
    (validate_struct_blob), (validate_enum_blob):
    * girepository/gmetadata.h:
    * tests/Makefile.am:
    * tests/invoke/Makefile.am:
    * tests/invoke/invoke.c (main):
    * tests/roundtrips.sh:
    * tools/Makefile.am:
    * tools/compiler.c (format_output), (write_out_metadata), (main):
    * tools/generate.c (write_type_name), (write_type_info),
    (write_constant_value), (write_enum_info), (load_metadata), (main):
    * tools/gidlcompilercontext.c:
    * tools/gidlcompilercontext.h:
    * tools/gidlcompilerentrynode.c:
    * tools/gidlcompilerentrynode.h:
    * tools/gidlcompilertypenode.c:
    * tools/gidlcompilertypenode.h:
    * tools/gidlmodule.c (g_idl_module_build_metadata):
    * tools/gidlmodule.h:
    * tools/gidlnode.c (init_stats), (dump_stats),
    (g_idl_node_get_size), (g_idl_node_get_full_size),
    (g_idl_node_cmp), (g_idl_node_can_have_member),
    (g_idl_node_add_member), (g_idl_node_param_direction_string),
    (parse_int_value), (parse_uint_value), (parse_float_value),
    (parse_boolean_value), (find_entry_node), (find_entry),
    (serialize_type), (g_idl_node_build_metadata), (write_string):
    * tools/gidlnode.h:
    * tools/gidlparser.c (parse_type_internal):
    * tools/quote-file.sh:
    Revert revisions 157,149-148,136-129 and 120.
    Move back to using g-idl-generate to generate the metadata and
    avoids dependency on a c compiler.


svn path=/trunk/; revision=214
This commit is contained in:
Johan Dahlin 2008-04-22 22:48:16 +00:00 committed by Johan Dahlin
parent e8fa684588
commit 4ff71171a9
5 changed files with 354 additions and 257 deletions

335
ginfo.c
View File

@ -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;
}
}

View File

@ -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:

View File

@ -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);

View File

@ -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))
{

View File

@ -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,