From 4e811edc68982e298f812e610ff783040440a9f5 Mon Sep 17 00:00:00 2001 From: Philip Van Hoof Date: Sun, 8 Jun 2008 14:37:30 +0000 Subject: tools/gidlnode.c 2008-06-08 Philip Van Hoof * girepository/girepository.c: * girepository/gtypelib.c: * girepository/ginfo.c: * girepository/ginvoke.c: * girepository/girepository.h: * girepository/gtypelib.h: * girepository/gmetadata.c: * girepository/Makefile.am: * girepository/gmetadata.h: * tools/compiler.c: * tools/gidlmodule.c: * tools/gidlnode.c * tools/generate.c: * tools/gidlmodule.h: * tools/gidlparser.c: Renamed GMetadata to GTypelib svn path=/trunk/; revision=288 --- ChangeLog | 20 + girepository/Makefile.am | 4 +- girepository/ginfo.c | 50 +- girepository/ginvoke.c | 2 +- girepository/girepository.c | 46 +- girepository/girepository.h | 20 +- girepository/gmetadata.c | 1959 ------------------------------------------- girepository/gmetadata.h | 549 ------------ girepository/gtypelib.c | 1959 +++++++++++++++++++++++++++++++++++++++++++ girepository/gtypelib.h | 549 ++++++++++++ tools/compiler.c | 24 +- tools/generate.c | 16 +- tools/gidlmodule.c | 4 +- tools/gidlmodule.h | 4 +- tools/gidlnode.c | 2 +- tools/gidlparser.c | 2 +- 16 files changed, 2615 insertions(+), 2595 deletions(-) delete mode 100644 girepository/gmetadata.c delete mode 100644 girepository/gmetadata.h create mode 100644 girepository/gtypelib.c create mode 100644 girepository/gtypelib.h diff --git a/ChangeLog b/ChangeLog index 64447ad6..c1f4dae2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2008-06-08 Philip Van Hoof + + * girepository/girepository.c: + * girepository/gtypelib.c: + * girepository/ginfo.c: + * girepository/ginvoke.c: + * girepository/girepository.h: + * girepository/gtypelib.h: + * girepository/gmetadata.c: + * girepository/Makefile.am: + * girepository/gmetadata.h: + * tools/compiler.c: + * tools/gidlmodule.c: + * tools/gidlnode.c + * tools/generate.c: + * tools/gidlmodule.h: + * tools/gidlparser.c: + + Renamed GMetadata to GTypelib + 2008-06-07 Johan Dahlin * giscanner/xmlwriter.py: diff --git a/girepository/Makefile.am b/girepository/Makefile.am index e95b3cd7..9dd5e547 100644 --- a/girepository/Makefile.am +++ b/girepository/Makefile.am @@ -8,8 +8,8 @@ noinst_LTLIBRARIES = libgirepository.la libgirepository_la_SOURCES = \ girepository.c \ - gmetadata.h \ - gmetadata.c \ + gtypelib.h \ + gtypelib.c \ ginfo.c \ ginvoke.c libgirepository_la_CPPFLAGS = $(GIREPO_CFLAGS) diff --git a/girepository/ginfo.c b/girepository/ginfo.c index 4a2568e0..c54b3928 100644 --- a/girepository/ginfo.c +++ b/girepository/ginfo.c @@ -24,7 +24,7 @@ #include #include "girepository.h" -#include "gmetadata.h" +#include "gtypelib.h" struct _GIBaseInfo { @@ -32,7 +32,7 @@ struct _GIBaseInfo gint ref_count; GIBaseInfo *container; - GMetadata *metadata; + GTypelib *metadata; guint32 offset; }; @@ -136,7 +136,7 @@ struct _GIUnionInfo GIBaseInfo * g_info_new (GIInfoType type, GIBaseInfo *container, - GMetadata *metadata, + GTypelib *metadata, guint32 offset) { GIBaseInfo *info; @@ -156,18 +156,18 @@ g_info_new (GIInfoType type, } static GIBaseInfo * -g_info_from_entry (GMetadata *metadata, +g_info_from_entry (GTypelib *metadata, guint16 index) { GIBaseInfo *result; - DirEntry *entry = g_metadata_get_dir_entry (metadata, index); + DirEntry *entry = g_typelib_get_dir_entry (metadata, index); if (entry->local) result = g_info_new (entry->blob_type, NULL, metadata, entry->offset); else { - const gchar *namespace = g_metadata_get_string (metadata, entry->offset); - const gchar *name = g_metadata_get_string (metadata, entry->name); + const gchar *namespace = g_typelib_get_string (metadata, entry->offset); + const gchar *name = g_typelib_get_string (metadata, entry->name); GIRepository *repository = g_irepository_get_default (); @@ -240,7 +240,7 @@ g_base_info_get_name (GIBaseInfo *info) { CommonBlob *blob = (CommonBlob *)&info->metadata->data[info->offset]; - return g_metadata_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->metadata, blob->name); } break; @@ -248,7 +248,7 @@ g_base_info_get_name (GIBaseInfo *info) { ValueBlob *blob = (ValueBlob *)&info->metadata->data[info->offset]; - return g_metadata_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->metadata, blob->name); } break; @@ -256,7 +256,7 @@ g_base_info_get_name (GIBaseInfo *info) { SignalBlob *blob = (SignalBlob *)&info->metadata->data[info->offset]; - return g_metadata_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->metadata, blob->name); } break; @@ -264,7 +264,7 @@ g_base_info_get_name (GIBaseInfo *info) { PropertyBlob *blob = (PropertyBlob *)&info->metadata->data[info->offset]; - return g_metadata_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->metadata, blob->name); } break; @@ -272,7 +272,7 @@ g_base_info_get_name (GIBaseInfo *info) { VFuncBlob *blob = (VFuncBlob *)&info->metadata->data[info->offset]; - return g_metadata_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->metadata, blob->name); } break; @@ -280,7 +280,7 @@ g_base_info_get_name (GIBaseInfo *info) { FieldBlob *blob = (FieldBlob *)&info->metadata->data[info->offset]; - return g_metadata_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->metadata, blob->name); } break; @@ -288,7 +288,7 @@ g_base_info_get_name (GIBaseInfo *info) { ArgBlob *blob = (ArgBlob *)&info->metadata->data[info->offset]; - return g_metadata_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->metadata, blob->name); } break; @@ -320,7 +320,7 @@ g_base_info_get_namespace (GIBaseInfo *info) return unresolved->namespace; } - return g_metadata_get_string (info->metadata, header->namespace); + return g_typelib_get_string (info->metadata, header->namespace); } gboolean @@ -430,9 +430,9 @@ g_base_info_get_annotation (GIBaseInfo *info, { res = next; - rname = g_metadata_get_string (base->metadata, res->name); + rname = g_typelib_get_string (base->metadata, res->name); if (strcmp (name, rname) == 0) - return g_metadata_get_string (base->metadata, res->value); + return g_typelib_get_string (base->metadata, res->value); next = res += header->annotation_blob_size; } @@ -447,7 +447,7 @@ g_base_info_get_container (GIBaseInfo *info) return info->container; } -GMetadata * +GTypelib * g_base_info_get_metadata (GIBaseInfo *info) { return info->metadata; @@ -460,7 +460,7 @@ g_function_info_get_symbol (GIFunctionInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; FunctionBlob *blob = (FunctionBlob *)&base->metadata->data[base->offset]; - return g_metadata_get_string (base->metadata, blob->symbol); + return g_typelib_get_string (base->metadata, blob->symbol); } GIFunctionInfoFlags @@ -530,7 +530,7 @@ signature_offset (GICallableInfo *info) GITypeInfo * g_type_info_new (GIBaseInfo *container, - GMetadata *metadata, + GTypelib *metadata, guint32 offset) { SimpleTypeBlob *type = (SimpleTypeBlob *)&metadata->data[offset]; @@ -874,7 +874,7 @@ g_error_domain_info_get_quark (GIErrorDomainInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->metadata->data[base->offset]; - return g_metadata_get_string (base->metadata, blob->get_quark); + return g_typelib_get_string (base->metadata, blob->get_quark); } GIInterfaceInfo * @@ -951,7 +951,7 @@ g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info) RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&base->metadata->data[base->offset]; if (blob->gtype_name) - return g_metadata_get_string (base->metadata, blob->gtype_name); + return g_typelib_get_string (base->metadata, blob->gtype_name); return NULL; } @@ -963,7 +963,7 @@ g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info) RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&base->metadata->data[base->offset]; if (blob->gtype_init) - return g_metadata_get_string (base->metadata, blob->gtype_init); + return g_typelib_get_string (base->metadata, blob->gtype_init); return NULL; } @@ -1116,7 +1116,7 @@ g_object_info_get_type_name (GIObjectInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; - return g_metadata_get_string (base->metadata, blob->gtype_name); + return g_typelib_get_string (base->metadata, blob->gtype_name); } const gchar * @@ -1125,7 +1125,7 @@ g_object_info_get_type_init (GIObjectInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; - return g_metadata_get_string (base->metadata, blob->gtype_init); + return g_typelib_get_string (base->metadata, blob->gtype_init); } gint diff --git a/girepository/ginvoke.c b/girepository/ginvoke.c index 26f3c580..d283b69f 100644 --- a/girepository/ginvoke.c +++ b/girepository/ginvoke.c @@ -24,7 +24,7 @@ #include #include "girepository.h" -#include "gmetadata.h" +#include "gtypelib.h" #include "config.h" GQuark diff --git a/girepository/girepository.c b/girepository/girepository.c index c9b3b683..c2b119cd 100644 --- a/girepository/girepository.c +++ b/girepository/girepository.c @@ -26,7 +26,7 @@ #include #include #include "girepository.h" -#include "gmetadata.h" +#include "gtypelib.h" static GIRepository *default_repository = NULL; static GHashTable *default_metadata = NULL; @@ -34,7 +34,7 @@ static GSList *search_path = NULL; struct _GIRepositoryPrivate { - GHashTable *metadata; /* (string) namespace -> GMetadata */ + GHashTable *metadata; /* (string) namespace -> GTypelib */ }; G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT); @@ -70,7 +70,7 @@ g_irepository_class_init (GIRepositoryClass *class) const gchar * g_irepository_register (GIRepository *repository, - GMetadata *metadata) + GTypelib *metadata) { Header *header; const gchar *name; @@ -88,7 +88,7 @@ g_irepository_register (GIRepository *repository, if (repository->priv->metadata == NULL) repository->priv->metadata = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) NULL, - (GDestroyNotify) g_metadata_free); + (GDestroyNotify) g_typelib_free); table = repository->priv->metadata; } else @@ -96,11 +96,11 @@ g_irepository_register (GIRepository *repository, if (default_metadata == NULL) default_metadata = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) NULL, - (GDestroyNotify) g_metadata_free); + (GDestroyNotify) g_typelib_free); table = default_metadata; } - name = g_metadata_get_string (metadata, header->namespace); + name = g_typelib_get_string (metadata, header->namespace); if (g_hash_table_lookup (table, name)) { @@ -158,7 +158,7 @@ g_irepository_get_default (void) if (default_metadata == NULL) default_metadata = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) NULL, - (GDestroyNotify) g_metadata_free); + (GDestroyNotify) g_typelib_free); default_repository->priv->metadata = default_metadata; } @@ -170,7 +170,7 @@ count_interfaces (gpointer key, gpointer value, gpointer data) { - guchar *metadata = ((GMetadata *) value)->data; + guchar *metadata = ((GTypelib *) value)->data; gint *n_interfaces = (gint *)data; *n_interfaces += ((Header *)metadata)->n_local_entries; @@ -184,7 +184,7 @@ g_irepository_get_n_infos (GIRepository *repository, if (namespace) { - GMetadata *metadata; + GTypelib *metadata; metadata = g_hash_table_lookup (repository->priv->metadata, namespace); @@ -214,7 +214,7 @@ find_interface (gpointer key, gpointer data) { gint i; - GMetadata *metadata = (GMetadata *)value; + GTypelib *metadata = (GTypelib *)value; IfaceData *iface_data = (IfaceData *)data; gint index; gint n_entries; @@ -230,8 +230,8 @@ find_interface (gpointer key, { for (i = 1; i <= n_entries; i++) { - entry = g_metadata_get_dir_entry (metadata, i); - name = g_metadata_get_string (metadata, entry->name); + entry = g_typelib_get_dir_entry (metadata, i); + name = g_typelib_get_string (metadata, entry->name); if (strcmp (name, iface_data->name) == 0) { index = i; @@ -243,12 +243,12 @@ find_interface (gpointer key, { for (i = 1; i <= n_entries; i++) { - entry = g_metadata_get_dir_entry (metadata, i); + entry = g_typelib_get_dir_entry (metadata, i); if (entry->blob_type < 4) continue; offset = *(guint32*)&metadata->data[entry->offset + 8]; - type = g_metadata_get_string (metadata, offset); + type = g_typelib_get_string (metadata, offset); if (strcmp (type, iface_data->type) == 0) { index = i; @@ -266,7 +266,7 @@ find_interface (gpointer key, if (index != 0) { - entry = g_metadata_get_dir_entry (metadata, index); + entry = g_typelib_get_dir_entry (metadata, index); iface_data->iface = g_info_new (entry->blob_type, NULL, metadata, entry->offset); } @@ -286,7 +286,7 @@ g_irepository_get_info (GIRepository *repository, if (namespace) { - GMetadata *metadata; + GTypelib *metadata; metadata = g_hash_table_lookup (repository->priv->metadata, namespace); @@ -329,7 +329,7 @@ g_irepository_find_by_name (GIRepository *repository, if (namespace) { - GMetadata *metadata; + GTypelib *metadata; metadata = g_hash_table_lookup (repository->priv->metadata, namespace); @@ -374,7 +374,7 @@ const gchar * g_irepository_get_shared_library (GIRepository *repository, const gchar *namespace) { - GMetadata *metadata; + GTypelib *metadata; Header *header; metadata = g_hash_table_lookup (repository->priv->metadata, namespace); @@ -382,7 +382,7 @@ g_irepository_get_shared_library (GIRepository *repository, return NULL; header = (Header *) metadata->data; if (header->shared_library) - return g_metadata_get_string (metadata, header->shared_library); + return g_typelib_get_string (metadata, header->shared_library); else return NULL; } @@ -418,7 +418,7 @@ g_irepository_register_file (GIRepository *repository, gchar *fname, *full_path; GMappedFile *mfile; GError *error1 = NULL; - GMetadata *metadata = NULL; + GTypelib *metadata = NULL; const gchar *metadata_namespace, *shlib_fname; GModule *module; guint32 shlib; @@ -449,8 +449,8 @@ g_irepository_register_file (GIRepository *repository, continue; } g_free (full_path); - metadata = g_metadata_new_from_mapped_file (mfile); - metadata_namespace = g_metadata_get_string (metadata, ((Header *) metadata->data)->namespace); + metadata = g_typelib_new_from_mapped_file (mfile); + metadata_namespace = g_typelib_get_string (metadata, ((Header *) metadata->data)->namespace); if (strcmp (metadata_namespace, namespace) != 0) { g_set_error (error, G_IREPOSITORY_ERROR, G_IREPOSITORY_ERROR_NAMESPACE_MISMATCH, @@ -472,7 +472,7 @@ g_irepository_register_file (GIRepository *repository, /* optionally load shared library and attach it to the metadata */ shlib = ((Header *) metadata->data)->shared_library; if (shlib) { - shlib_fname = g_metadata_get_string (metadata, shlib); + shlib_fname = g_typelib_get_string (metadata, shlib); module = g_module_open (shlib_fname, G_MODULE_BIND_LAZY|G_MODULE_BIND_LOCAL); if (module == NULL) { g_set_error (error, G_IREPOSITORY_ERROR, diff --git a/girepository/girepository.h b/girepository/girepository.h index fa625aa2..ae5e2c58 100644 --- a/girepository/girepository.h +++ b/girepository/girepository.h @@ -52,7 +52,7 @@ typedef struct _GIArgInfo GIArgInfo; typedef struct _GITypeInfo GITypeInfo; typedef struct _GIErrorDomainInfo GIErrorDomainInfo; typedef struct _GIUnresolvedInfo GIUnresolvedInfo; -typedef struct _GMetadata GMetadata; +typedef struct _GTypelib GTypelib; struct _GIRepository { @@ -73,7 +73,7 @@ struct _GIRepositoryClass GType g_irepository_get_type (void) G_GNUC_CONST; GIRepository *g_irepository_get_default (void); const gchar * g_irepository_register (GIRepository *repository, - GMetadata *metadata); + GTypelib *metadata); void g_irepository_unregister (GIRepository *repository, const gchar *namespace); const gchar * g_irepository_register_file (GIRepository *repository, @@ -96,15 +96,15 @@ const gchar * g_irepository_get_shared_library (GIRepository *repository, const gchar *namespace); /* Metadata */ -GMetadata * g_metadata_new_from_memory (guchar *memory, +GTypelib * g_typelib_new_from_memory (guchar *memory, gsize len); -GMetadata * g_metadata_new_from_const_memory (const guchar *memory, +GTypelib * g_typelib_new_from_const_memory (const guchar *memory, gsize len); -GMetadata * g_metadata_new_from_mapped_file (GMappedFile *mfile); -void g_metadata_free (GMetadata *metadata); -void g_metadata_set_module (GMetadata *metadata, +GTypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile); +void g_typelib_free (GTypelib *metadata); +void g_typelib_set_module (GTypelib *metadata, GModule *module); -const gchar * g_metadata_get_namespace (GMetadata *metadata); +const gchar * g_typelib_get_namespace (GTypelib *metadata); typedef enum { @@ -156,11 +156,11 @@ gboolean g_base_info_is_deprecated (GIBaseInfo *info); const gchar * g_base_info_get_annotation (GIBaseInfo *info, const gchar *name); GIBaseInfo * g_base_info_get_container (GIBaseInfo *info); -GMetadata * g_base_info_get_metadata (GIBaseInfo *info); +GTypelib * g_base_info_get_metadata (GIBaseInfo *info); GIBaseInfo * g_info_new (GIInfoType type, GIBaseInfo *container, - GMetadata *metadata, + GTypelib *metadata, guint32 offset); diff --git a/girepository/gmetadata.c b/girepository/gmetadata.c deleted file mode 100644 index c33e6bff..00000000 --- a/girepository/gmetadata.c +++ /dev/null @@ -1,1959 +0,0 @@ -/* GObject introspection: metadata validation, auxiliary functions - * related to the binary metadata format - * - * Copyright (C) 2005 Matthias Clasen - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include -#include - -#include - -#include "gmetadata.h" - - -#define ALIGN_VALUE(this, boundary) \ - (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) - - -DirEntry * -g_metadata_get_dir_entry (GMetadata *metadata, - guint16 index) -{ - Header *header = (Header *)metadata->data; - - 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) -{ - return offset == ALIGN_VALUE (offset, 4); -} - -#define MAX_NAME_LEN 200 - -static gboolean -is_name (const guchar *data, guint32 offset) -{ - gchar *name; - - name = (gchar*)&data[offset]; - - if (!memchr (name, '\0', MAX_NAME_LEN)) - return FALSE; - - if (strspn (name, G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_") < strlen (name)) - return FALSE; - - return TRUE; -} - -static gboolean -validate_header (GMetadata *metadata, - GError **error) -{ - Header *header; - - if (metadata->len < sizeof (Header)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - header = (Header *)metadata->data; - - if (strncmp (header->magic, G_IDL_MAGIC, 16) != 0) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_HEADER, - "Magic string not found"); - return FALSE; - - } - - if (header->major_version != 1 || header->minor_version != 0) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_HEADER, - "Version mismatch"); - return FALSE; - - } - - if (header->n_entries < header->n_local_entries) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_HEADER, - "Inconsistent entry counts"); - return FALSE; - } - - if (header->size != metadata->len) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_HEADER, - "Metadata size mismatch"); - 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, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_HEADER, - "Misaligned directory"); - return FALSE; - } - - if (!is_aligned (header->annotations)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_HEADER, - "Misaligned annotations"); - return FALSE; - } - - if (header->annotations == 0 && header->n_annotations > 0) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_HEADER, - "Wrong number of annotations"); - return FALSE; - } - - if (!is_name (metadata->data, header->namespace)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_HEADER, - "Invalid namespace name"); - return FALSE; - } - - return TRUE; -} - -static gboolean validate_type_blob (GMetadata *metadata, - guint32 offset, - guint32 signature_offset, - gboolean return_type, - GError **error); - -static gboolean -validate_array_type_blob (GMetadata *metadata, - guint32 offset, - guint32 signature_offset, - gboolean return_type, - GError **error) -{ - ArrayTypeBlob *blob; - - 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", blob->tag); - return FALSE; - } - - /* FIXME validate length */ - - if (!validate_type_blob (metadata, - offset + G_STRUCT_OFFSET (ArrayTypeBlob, type), - 0, FALSE, error)) - return FALSE; - - 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, - guint32 signature_offset, - gboolean return_type, - gint n_params, - GError **error) -{ - ParamTypeBlob *blob; - gint i; - - blob = (ParamTypeBlob*)&metadata->data[offset]; - - if (!blob->pointer) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", blob->tag); - return FALSE; - } - - if (blob->n_types != n_params) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Parameter type number mismatch"); - return FALSE; - } - - for (i = 0; i < n_params; i++) - { - if (!validate_type_blob (metadata, - offset + sizeof (ParamTypeBlob) + - i * sizeof (SimpleTypeBlob), - 0, FALSE, error)) - return FALSE; - } - - return TRUE; -} - -static gboolean -validate_error_type_blob (GMetadata *metadata, - guint32 offset, - guint32 signature_offset, - gboolean return_type, - GError **error) -{ - ErrorTypeBlob *blob; - Header *header; - gint i; - DirEntry *entry; - - blob = (ErrorTypeBlob*)&metadata->data[offset]; - - header = (Header *)metadata->data; - - if (!blob->pointer) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", blob->tag); - return FALSE; - } - - for (i = 0; i < blob->n_domains; i++) - { - 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", blob->domains[i]); - return FALSE; - } - - 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)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Wrong blob type"); - return FALSE; - } - } - - return TRUE; -} - -static gboolean -validate_type_blob (GMetadata *metadata, - guint32 offset, - guint32 signature_offset, - gboolean return_type, - GError **error) -{ - SimpleTypeBlob *simple; - InterfaceTypeBlob *iface; - - simple = (SimpleTypeBlob *)&metadata->data[offset]; - - if (simple->reserved == 0 && - simple->reserved2 == 0) - { - if (simple->tag >= TYPE_TAG_ARRAY) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Wrong tag in simple type"); - return FALSE; - } - - 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", simple->tag); - return FALSE; - } - - return TRUE; - } - - 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_INTERFACE: - if (!validate_iface_type_blob (metadata, simple->offset, - signature_offset, return_type, error)) - return FALSE; - break; - case TYPE_TAG_LIST: - case TYPE_TAG_SLIST: - if (!validate_param_type_blob (metadata, simple->offset, - signature_offset, return_type, 1, error)) - return FALSE; - break; - case TYPE_TAG_HASH: - if (!validate_param_type_blob (metadata, simple->offset, - signature_offset, return_type, 2, error)) - return FALSE; - break; - case TYPE_TAG_ERROR: - if (!validate_error_type_blob (metadata, simple->offset, - signature_offset, return_type, error)) - return FALSE; - break; - default: - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Wrong tag in complex type"); - return FALSE; - } - - return TRUE; -} - -static gboolean -validate_arg_blob (GMetadata *metadata, - guint32 offset, - guint32 signature_offset, - GError **error) -{ - ArgBlob *blob; - - if (metadata->len < offset + sizeof (ArgBlob)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - blob = (ArgBlob*) &metadata->data[offset]; - - if (!is_name (metadata->data, blob->name)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid argument name"); - return FALSE; - } - - if (!validate_type_blob (metadata, - offset + G_STRUCT_OFFSET (ArgBlob, arg_type), - signature_offset, FALSE, error)) - return FALSE; - - return TRUE; -} - -static gboolean -validate_signature_blob (GMetadata *metadata, - guint32 offset, - GError **error) -{ - SignatureBlob *blob; - gint i; - - if (metadata->len < offset + sizeof (SignatureBlob)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - blob = (SignatureBlob*) &metadata->data[offset]; - - if (blob->return_type.offset != 0) - { - if (!validate_type_blob (metadata, - offset + G_STRUCT_OFFSET (SignatureBlob, return_type), - offset, TRUE, error)) - return FALSE; - } - - for (i = 0; i < blob->n_arguments; i++) - { - if (!validate_arg_blob (metadata, - offset + sizeof (SignatureBlob) + - i * sizeof (ArgBlob), - offset, - error)) - return FALSE; - } - - /* FIXME check constraints on return_value */ - /* FIXME check array-length pairs */ - return TRUE; -} - -static gboolean -validate_function_blob (GMetadata *metadata, - guint32 offset, - guint16 container_type, - GError **error) -{ - FunctionBlob *blob; - - if (metadata->len < offset + sizeof (FunctionBlob)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - blob = (FunctionBlob*) &metadata->data[offset]; - - if (blob->blob_type != BLOB_TYPE_FUNCTION) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Wrong blob type"); - return FALSE; - } - - if (!is_name (metadata->data, blob->name)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid function name"); - return FALSE; - } - - if (!is_name (metadata->data, blob->symbol)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid function symbol"); - return FALSE; - } - - if (blob->constructor) - { - switch (container_type) - { - case BLOB_TYPE_BOXED: - case BLOB_TYPE_OBJECT: - case BLOB_TYPE_INTERFACE: - break; - default: - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Constructor not allowed"); - return FALSE; - } - } - - if (blob->setter || blob->getter || blob->wraps_vfunc) - { - switch (container_type) - { - case BLOB_TYPE_OBJECT: - case BLOB_TYPE_INTERFACE: - break; - default: - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Setter, getter or wrapper not allowed"); - return FALSE; - } - } - - if (blob->index) - { - if (!(blob->setter || blob->getter || blob->wraps_vfunc)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Must be setter, getter or wrapper"); - return FALSE; - } - } - - /* FIXME: validate index range */ - /* FIXME: validate "this" argument for methods */ - /* FIXME: validate return type for constructors */ - - if (!validate_signature_blob (metadata, blob->signature, error)) - return FALSE; - - return TRUE; -} - -static gboolean -validate_callback_blob (GMetadata *metadata, - guint32 offset, - GError **error) -{ - CallbackBlob *blob; - - if (metadata->len < offset + sizeof (CallbackBlob)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - blob = (CallbackBlob*) &metadata->data[offset]; - - if (blob->blob_type != BLOB_TYPE_CALLBACK) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Wrong blob type"); - return FALSE; - } - - if (!is_name (metadata->data, blob->name)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid callback name"); - return FALSE; - } - - if (!validate_signature_blob (metadata, blob->signature, error)) - return FALSE; - - return TRUE; -} - -static gboolean -validate_constant_blob (GMetadata *metadata, - guint32 offset, - GError **error) -{ - gint value_size[] = { - 0, 4, 1, 1, 2, 2, 4, 4, 8, 8, - sizeof (gint), sizeof (guint), - sizeof (glong), sizeof (gulong), - sizeof (gssize), sizeof (gsize), - sizeof (gfloat), sizeof (gdouble), - 0, 0 - }; - ConstantBlob *blob; - SimpleTypeBlob *type; - - if (metadata->len < offset + sizeof (ConstantBlob)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - blob = (ConstantBlob*) &metadata->data[offset]; - - if (blob->blob_type != BLOB_TYPE_CONSTANT) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Wrong blob type"); - return FALSE; - } - - if (!is_name (metadata->data, blob->name)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid constant name"); - return FALSE; - } - - if (!validate_type_blob (metadata, offset + G_STRUCT_OFFSET (ConstantBlob, type), - 0, FALSE, error)) - return FALSE; - - if (!is_aligned (blob->offset)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Misaligned constant value"); - return FALSE; - } - - type = (SimpleTypeBlob *)&metadata->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)]; - if (type->reserved == 0) - { - if (type->tag == 0) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Constant value type void"); - return FALSE; - } - - if (value_size[type->tag] != 0 && - blob->size != value_size[type->tag]) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Constant value size mismatch"); - return FALSE; - } - /* FIXME check string values */ - } - - return TRUE; -} - -static gboolean -validate_value_blob (GMetadata *metadata, - guint32 offset, - GError **error) -{ - ValueBlob *blob; - - if (metadata->len < offset + sizeof (ValueBlob)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - blob = (ValueBlob*) &metadata->data[offset]; - - if (!is_name (metadata->data, blob->name)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid value name"); - return FALSE; - } - - return TRUE; -} - -static gboolean -validate_field_blob (GMetadata *metadata, - guint32 offset, - GError **error) -{ - FieldBlob *blob; - - if (metadata->len < offset + sizeof (FieldBlob)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - blob = (FieldBlob*) &metadata->data[offset]; - - if (!is_name (metadata->data, blob->name)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid field name"); - return FALSE; - } - - if (!validate_type_blob (metadata, - offset + G_STRUCT_OFFSET (FieldBlob, type), - 0, FALSE, error)) - return FALSE; - - return TRUE; -} - -static gboolean -validate_property_blob (GMetadata *metadata, - guint32 offset, - GError **error) -{ - PropertyBlob *blob; - - if (metadata->len < offset + sizeof (PropertyBlob)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - blob = (PropertyBlob*) &metadata->data[offset]; - - if (!is_name (metadata->data, blob->name)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid property name"); - return FALSE; - } - - if (!validate_type_blob (metadata, - offset + G_STRUCT_OFFSET (PropertyBlob, type), - 0, FALSE, error)) - return FALSE; - - return TRUE; -} - -static gboolean -validate_signal_blob (GMetadata *metadata, - guint32 offset, - guint32 container_offset, - GError **error) -{ - SignalBlob *blob; - gint n_signals; - - if (metadata->len < offset + sizeof (SignalBlob)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - blob = (SignalBlob*) &metadata->data[offset]; - - if (!is_name (metadata->data, blob->name)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid signal name"); - return FALSE; - } - - if ((blob->run_first != 0) + - (blob->run_last != 0) + - (blob->run_cleanup != 0) != 1) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid signal run flags"); - return FALSE; - } - - if (blob->has_class_closure) - { - if (((CommonBlob*)&metadata->data[container_offset])->blob_type == BLOB_TYPE_OBJECT) - { - ObjectBlob *object; - - object = (ObjectBlob*)&metadata->data[container_offset]; - - n_signals = object->n_signals; - } - else - { - InterfaceBlob *iface; - - iface = (InterfaceBlob*)&metadata->data[container_offset]; - - n_signals = iface->n_signals; - } - - if (blob->class_closure >= n_signals) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid class closure index"); - return FALSE; - } - } - - if (!validate_signature_blob (metadata, blob->signature, error)) - return FALSE; - - return TRUE; -} - -static gboolean -validate_vfunc_blob (GMetadata *metadata, - guint32 offset, - guint32 container_offset, - GError **error) -{ - VFuncBlob *blob; - gint n_vfuncs; - - if (metadata->len < offset + sizeof (VFuncBlob)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - blob = (VFuncBlob*) &metadata->data[offset]; - - if (!is_name (metadata->data, blob->name)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid vfunc name"); - return FALSE; - } - - if (blob->class_closure) - { - if (((CommonBlob*)&metadata->data[container_offset])->blob_type == BLOB_TYPE_OBJECT) - { - ObjectBlob *object; - - object = (ObjectBlob*)&metadata->data[container_offset]; - - n_vfuncs = object->n_vfuncs; - } - else - { - InterfaceBlob *iface; - - iface = (InterfaceBlob*)&metadata->data[container_offset]; - - n_vfuncs = iface->n_vfuncs; - } - - if (blob->class_closure >= n_vfuncs) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid class closure index"); - return FALSE; - } - } - - if (!validate_signature_blob (metadata, blob->signature, error)) - return FALSE; - - return TRUE; -} - -static gboolean -validate_struct_blob (GMetadata *metadata, - guint32 offset, - guint16 blob_type, - GError **error) -{ - StructBlob *blob; - gint i; - - if (metadata->len < offset + sizeof (StructBlob)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - blob = (StructBlob*) &metadata->data[offset]; - - if (blob->blob_type != blob_type) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Wrong blob type"); - return FALSE; - } - - if ((blob->blob_type == BLOB_TYPE_BOXED && blob->unregistered) || - (blob->blob_type == BLOB_TYPE_STRUCT && !blob->unregistered)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Registration/blob type mismatch"); - return FALSE; - } - - if (!is_name (metadata->data, blob->name)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid struct name"); - return FALSE; - } - - if (blob_type == BLOB_TYPE_BOXED) - { - if (!is_name (metadata->data, blob->gtype_name)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid boxed type name"); - return FALSE; - } - - if (!is_name (metadata->data, blob->gtype_init)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid boxed type init"); - 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) + - blob->n_methods * sizeof (FunctionBlob)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - for (i = 0; i < blob->n_fields; i++) - { - if (!validate_field_blob (metadata, - offset + sizeof (StructBlob) + - i * sizeof (FieldBlob), - error)) - return FALSE; - } - - for (i = 0; i < blob->n_methods; i++) - { - if (!validate_function_blob (metadata, - offset + sizeof (StructBlob) + - blob->n_fields * sizeof (FieldBlob) + - i * sizeof (FunctionBlob), - blob_type, - error)) - return FALSE; - } - - return TRUE; -} - -static gboolean -validate_enum_blob (GMetadata *metadata, - guint32 offset, - guint16 blob_type, - GError **error) -{ - EnumBlob *blob; - ValueBlob *v1, *v2; - gint i, j; - - if (metadata->len < offset + sizeof (EnumBlob)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - blob = (EnumBlob*) &metadata->data[offset]; - - if (blob->blob_type != blob_type) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Wrong blob type"); - return FALSE; - } - - if (!blob->unregistered) - { - if (!is_name (metadata->data, blob->gtype_name)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid enum type name"); - return FALSE; - } - - if (!is_name (metadata->data, blob->gtype_init)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid enum type init"); - 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)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid enum name"); - return FALSE; - } - - if (metadata->len < offset + sizeof (EnumBlob) + - blob->n_values * sizeof (ValueBlob)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - for (i = 0; i < blob->n_values; i++) - { - if (!validate_value_blob (metadata, - offset + sizeof (EnumBlob) + - i * sizeof (ValueBlob), - error)) - return FALSE; - - v1 = (ValueBlob *)&metadata->data[offset + sizeof (EnumBlob) + - i * sizeof (ValueBlob)]; - for (j = 0; j < i; j++) - { - v2 = (ValueBlob *)&metadata->data[offset + sizeof (EnumBlob) + - j * sizeof (ValueBlob)]; - - if (v1->value == v2->value) - { - /* FIXME should this be an error ? */ - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Duplicate enum value"); - return FALSE; - } - } - } - - return TRUE; -} - -static gboolean -validate_object_blob (GMetadata *metadata, - guint32 offset, - GError **error) -{ - Header *header; - ObjectBlob *blob; - gint i; - guint32 offset2; - - header = (Header *)metadata->data; - - if (metadata->len < offset + sizeof (ObjectBlob)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - blob = (ObjectBlob*) &metadata->data[offset]; - - if (blob->blob_type != BLOB_TYPE_OBJECT) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Wrong blob type"); - return FALSE; - } - - if (!is_name (metadata->data, blob->gtype_name)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid object type name"); - return FALSE; - } - - if (!is_name (metadata->data, blob->gtype_init)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid object type init"); - return FALSE; - } - - if (!is_name (metadata->data, blob->name)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid object name"); - return FALSE; - } - - if (blob->parent > header->n_entries) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid parent index"); - return FALSE; - } - - if (blob->parent != 0) - { - DirEntry *entry; - - entry = g_metadata_get_dir_entry (metadata, blob->parent); - if (entry->blob_type != BLOB_TYPE_OBJECT && - (entry->local || entry->blob_type != 0)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Parent not object"); - return FALSE; - } - } - - if (metadata->len < offset + sizeof (ObjectBlob) + - (blob->n_interfaces + blob->n_interfaces % 2) * 2 + - blob->n_fields * sizeof (FieldBlob) + - blob->n_properties * sizeof (PropertyBlob) + - blob->n_methods * sizeof (FunctionBlob) + - blob->n_signals * sizeof (SignalBlob) + - blob->n_vfuncs * sizeof (VFuncBlob) + - blob->n_constants * sizeof (ConstantBlob)) - - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - offset2 = offset + sizeof (ObjectBlob); - - for (i = 0; i < blob->n_interfaces; i++, offset2 += 2) - { - guint16 iface; - DirEntry *entry; - - iface = *(guint16*)&metadata->data[offset2]; - if (iface == 0 || iface > header->n_entries) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid interface index"); - return FALSE; - } - - entry = g_metadata_get_dir_entry (metadata, iface); - - if (entry->blob_type != BLOB_TYPE_INTERFACE && - (entry->local || entry->blob_type != 0)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Not an interface"); - return FALSE; - } - } - - offset2 += 2 * (blob->n_interfaces %2); - - for (i = 0; i < blob->n_fields; i++, offset2 += sizeof (FieldBlob)) - { - if (!validate_field_blob (metadata, offset2, error)) - return FALSE; - } - - for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob)) - { - if (!validate_property_blob (metadata, offset2, error)) - return FALSE; - } - - for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob)) - { - if (!validate_function_blob (metadata, offset2, BLOB_TYPE_OBJECT, error)) - return FALSE; - } - - for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob)) - { - if (!validate_signal_blob (metadata, offset2, offset, error)) - return FALSE; - } - - for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob)) - { - if (!validate_vfunc_blob (metadata, offset2, offset, error)) - return FALSE; - } - - for (i = 0; i < blob->n_constants; i++, offset2 += sizeof (ConstantBlob)) - { - if (!validate_constant_blob (metadata, offset2, error)) - return FALSE; - } - - return TRUE; -} - -static gboolean -validate_interface_blob (GMetadata *metadata, - guint32 offset, - GError **error) -{ - Header *header; - InterfaceBlob *blob; - gint i; - guint32 offset2; - - header = (Header *)metadata->data; - - if (metadata->len < offset + sizeof (InterfaceBlob)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - blob = (InterfaceBlob*) &metadata->data[offset]; - - if (blob->blob_type != BLOB_TYPE_INTERFACE) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Wrong blob type"); - return FALSE; - } - - if (!is_name (metadata->data, blob->gtype_name)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid interface type name"); - return FALSE; - } - - if (!is_name (metadata->data, blob->gtype_init)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid interface type init"); - return FALSE; - } - - if (!is_name (metadata->data, blob->name)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid interface name"); - return FALSE; - } - - if (metadata->len < offset + sizeof (InterfaceBlob) + - (blob->n_prerequisites + blob->n_prerequisites % 2) * 2 + - blob->n_properties * sizeof (PropertyBlob) + - blob->n_methods * sizeof (FunctionBlob) + - blob->n_signals * sizeof (SignalBlob) + - blob->n_vfuncs * sizeof (VFuncBlob) + - blob->n_constants * sizeof (ConstantBlob)) - - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - offset2 = offset + sizeof (InterfaceBlob); - - for (i = 0; i < blob->n_prerequisites; i++, offset2 += 2) - { - DirEntry *entry; - guint16 req; - - req = *(guint16*)&metadata->data[offset2]; - if (req == 0 || req > header->n_entries) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Invalid prerequisite index"); - return FALSE; - } - - entry = g_metadata_get_dir_entry (metadata, req); - if (entry->blob_type != BLOB_TYPE_INTERFACE && - entry->blob_type != BLOB_TYPE_OBJECT && - (entry->local || entry->blob_type != 0)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, - "Not an interface or object"); - return FALSE; - } - } - - offset2 += 2 * (blob->n_prerequisites % 2); - - for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob)) - { - if (!validate_property_blob (metadata, offset2, error)) - return FALSE; - } - - for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob)) - { - if (!validate_function_blob (metadata, offset2, BLOB_TYPE_INTERFACE, error)) - return FALSE; - } - - for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob)) - { - if (!validate_signal_blob (metadata, offset2, offset, error)) - return FALSE; - } - - for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob)) - { - if (!validate_vfunc_blob (metadata, offset2, offset, error)) - return FALSE; - } - - for (i = 0; i < blob->n_constants; i++, offset2 += sizeof (ConstantBlob)) - { - if (!validate_constant_blob (metadata, offset2, error)) - return FALSE; - } - - return TRUE; -} - -static gboolean -validate_errordomain_blob (GMetadata *metadata, - guint32 offset, - GError **error) -{ - return TRUE; -} - -static gboolean -validate_union_blob (GMetadata *metadata, - guint32 offset, - GError **error) -{ - return TRUE; -} - -static gboolean -validate_blob (GMetadata *metadata, - guint32 offset, - GError **error) -{ - CommonBlob *common; - - if (metadata->len < offset + sizeof (CommonBlob)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - common = (CommonBlob*)&metadata->data[offset]; - - switch (common->blob_type) - { - case BLOB_TYPE_FUNCTION: - if (!validate_function_blob (metadata, offset, 0, error)) - return FALSE; - break; - case BLOB_TYPE_CALLBACK: - if (!validate_callback_blob (metadata, offset, error)) - return FALSE; - break; - case BLOB_TYPE_STRUCT: - case BLOB_TYPE_BOXED: - if (!validate_struct_blob (metadata, offset, common->blob_type, error)) - return FALSE; - break; - case BLOB_TYPE_ENUM: - case BLOB_TYPE_FLAGS: - if (!validate_enum_blob (metadata, offset, common->blob_type, error)) - return FALSE; - break; - case BLOB_TYPE_OBJECT: - if (!validate_object_blob (metadata, offset, error)) - return FALSE; - break; - case BLOB_TYPE_INTERFACE: - if (!validate_interface_blob (metadata, offset, error)) - return FALSE; - break; - case BLOB_TYPE_CONSTANT: - if (!validate_constant_blob (metadata, offset, error)) - return FALSE; - break; - case BLOB_TYPE_ERROR_DOMAIN: - if (!validate_errordomain_blob (metadata, offset, error)) - return FALSE; - break; - case BLOB_TYPE_UNION: - if (!validate_union_blob (metadata, offset, error)) - return FALSE; - break; - default: - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_ENTRY, - "Invalid blob type"); - return FALSE; - } - - return TRUE; -} - -static gboolean -validate_directory (GMetadata *metadata, - GError **error) -{ - Header *header = (Header *)metadata->data; - DirEntry *entry; - gint i; - - if (metadata->len < header->directory + header->n_entries * sizeof (DirEntry)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - for (i = 0; i < header->n_entries; i++) - { - entry = g_metadata_get_dir_entry (metadata, i + 1); - - if (!is_name (metadata->data, entry->name)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_DIRECTORY, - "Invalid entry name"); - return FALSE; - } - - if ((entry->local && entry->blob_type == BLOB_TYPE_INVALID) || - entry->blob_type > BLOB_TYPE_UNION) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_DIRECTORY, - "Invalid entry type"); - return FALSE; - } - - if (i < header->n_local_entries) - { - if (!entry->local) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_DIRECTORY, - "Too few local directory entries"); - return FALSE; - } - - if (!is_aligned (entry->offset)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_DIRECTORY, - "Misaligned entry"); - return FALSE; - } - - if (!validate_blob (metadata, entry->offset, error)) - return FALSE; - } - else - { - if (entry->local) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_DIRECTORY, - "Too many local directory entries"); - return FALSE; - } - - if (!is_name (metadata->data, entry->offset)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_DIRECTORY, - "Invalid namespace name"); - return FALSE; - } - } - } - - return TRUE; -} - -static gboolean -validate_annotations (GMetadata *metadata, - GError **error) -{ - Header *header = (Header *)metadata->data; - - if (header->size < header->annotations + header->n_annotations * sizeof (AnnotationBlob)) - { - g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - - return TRUE; -} - -gboolean -g_metadata_validate (GMetadata *metadata, - GError **error) -{ - if (!validate_header (metadata, error)) - return FALSE; - - if (!validate_directory (metadata, error)) - return FALSE; - - if (!validate_annotations (metadata, error)) - return FALSE; - - return TRUE; -} - -GQuark -g_metadata_error_quark (void) -{ - static GQuark quark = 0; - if (quark == 0) - quark = g_quark_from_static_string ("g-metadata-error-quark"); - return quark; -} - -static const char* -find_some_symbol (GMetadata *metadata) -{ - Header *header = (Header *) metadata->data; - gint i; - - for (i = 0; i < header->n_entries; i++) - { - DirEntry *entry; - - entry = g_metadata_get_dir_entry (metadata, i + 1); - - switch (entry->blob_type) - { - case BLOB_TYPE_FUNCTION: - { - FunctionBlob *blob = (FunctionBlob *) &metadata->data[entry->offset]; - - if (blob->symbol) - return g_metadata_get_string (metadata, blob->symbol); - } - break; - case BLOB_TYPE_OBJECT: - { - RegisteredTypeBlob *blob = (RegisteredTypeBlob *) &metadata->data[entry->offset]; - - if (blob->gtype_init) - return g_metadata_get_string (metadata, blob->gtype_init); - } - break; - default: - break; - } - } - - return NULL; -} - -static inline void -_g_metadata_init (GMetadata *metadata) -{ - Header *header; - - header = (Header *) metadata->data; - if (header->shared_library) - { - const gchar *shlib; - - shlib = g_metadata_get_string (metadata, header->shared_library); - /* note that NULL shlib means to open the main app, which is allowed */ - - /* If we do have a shared lib, first be sure the main app isn't already linked to it */ - if (shlib != NULL) - { - const char *symbol_in_module; - - symbol_in_module = find_some_symbol (metadata); - if (symbol_in_module != NULL) - { - metadata->module = g_module_open (NULL, G_MODULE_BIND_LAZY); - if (metadata->module == NULL) - { - g_warning ("Could not open main app as GModule: %s", - g_module_error ()); - } - else - { - void *sym; - if (!g_module_symbol (metadata->module, symbol_in_module, &sym)) - { - /* we will try opening the shlib, symbol is not in app already */ - g_module_close (metadata->module); - metadata->module = NULL; - } - } - } - else - { - g_warning ("Could not find any symbols in metadata"); - } - } - - if (metadata->module == NULL) - { - /* Glade's autoconnect feature and OpenGL's extension mechanism - * as used by Clutter rely on dlopen(NULL) to work as a means of - * accessing the app's symbols. This keeps us from using - * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well; - * in general libraries are not expecting multiple copies of - * themselves and are not expecting to be unloaded. So we just - * load modules globally for now. - */ - - metadata->module = g_module_open (shlib, G_MODULE_BIND_LAZY); - if (metadata->module == NULL) - g_warning ("Failed to load shared library referenced by the metadata: %s", - g_module_error ()); - } - } -} - -/** - * g_metadata_new_from_memory: - * @memory: address of memory chunk containing the metadata - * @len: length of memory chunk containing the metadata - * - * Creates a new #GMetadata from a memory location. The memory block - * pointed to by @metadata will be automatically g_free()d when the - * repository is destroyed. - * - * Return value: the new #GMetadata - **/ -GMetadata * -g_metadata_new_from_memory (guchar *memory, gsize len) -{ - GMetadata *meta; - - meta = g_new0 (GMetadata, 1); - meta->data = memory; - meta->len = len; - meta->owns_memory = TRUE; - _g_metadata_init (meta); - return meta; -} - -/** - * g_metadata_new_from_const_memory: - * @memory: address of memory chunk containing the metadata - * @len: length of memory chunk containing the metadata - * - * Creates a new #GMetadata from a memory location. - * - * Return value: the new #GMetadata - **/ -GMetadata * -g_metadata_new_from_const_memory (const guchar *memory, gsize len) -{ - GMetadata *meta; - - meta = g_new0 (GMetadata, 1); - meta->data = (guchar *) memory; - meta->len = len; - meta->owns_memory = FALSE; - _g_metadata_init (meta); - return meta; -} - -/** - * g_metadata_new_from_mapped_file: - * @mfile: a #GMappedFile, that will be free'd when the repository is destroyed - * - * Creates a new #GMetadata from a #GMappedFile. - * - * Return value: the new #GMetadata - **/ -GMetadata * -g_metadata_new_from_mapped_file (GMappedFile *mfile) -{ - GMetadata *meta; - - meta = g_new0 (GMetadata, 1); - meta->mfile = mfile; - meta->owns_memory = FALSE; - meta->data = (guchar *) g_mapped_file_get_contents (mfile); - meta->len = g_mapped_file_get_length (mfile); - _g_metadata_init (meta); - return meta; -} - -/** - * g_metadata_free: - * @metadata: a #GMetadata - * - * Free a #GMetadata. - **/ -void -g_metadata_free (GMetadata *metadata) -{ - if (metadata->mfile) - g_mapped_file_free (metadata->mfile); - else - if (metadata->owns_memory) - g_free (metadata->data); - if (metadata->module) - g_module_close (metadata->module); - g_free (metadata); -} - -/** - * g_metadata_set_module: - * @metadata: a #GMetadata instance - * @module: a #GModule; takes ownership of this module - * - * Sets the target module for all symbols referenced by the metadata. - **/ -void -g_metadata_set_module (GMetadata *metadata, GModule *module) -{ - if (metadata->module) - g_module_close (metadata->module); - metadata->module = module; -} - -const gchar * -g_metadata_get_namespace(GMetadata *metadata) -{ - return g_metadata_get_string (metadata, ((Header *) metadata->data)->namespace); -} diff --git a/girepository/gmetadata.h b/girepository/gmetadata.h deleted file mode 100644 index a22ee235..00000000 --- a/girepository/gmetadata.h +++ /dev/null @@ -1,549 +0,0 @@ -/* GObject introspection: struct definitions for the binary - * metadata format, validation - * - * Copyright (C) 2005 Matthias Clasen - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __G_METADATA_H__ -#define __G_METADATA_H__ - -#include -#include "girepository.h" - -G_BEGIN_DECLS - -#define G_IDL_MAGIC "GOBJ\nMETADATA\r\n\032" - -enum -{ - BLOB_TYPE_INVALID, - BLOB_TYPE_FUNCTION, - BLOB_TYPE_CALLBACK, - BLOB_TYPE_STRUCT, - BLOB_TYPE_BOXED, - BLOB_TYPE_ENUM, - BLOB_TYPE_FLAGS, - BLOB_TYPE_OBJECT, - BLOB_TYPE_INTERFACE, - BLOB_TYPE_CONSTANT, - BLOB_TYPE_ERROR_DOMAIN, - BLOB_TYPE_UNION -}; - -typedef struct -{ - gchar magic[16]; - guint8 major_version; - guint8 minor_version; - guint16 reserved; - guint16 n_entries; - guint16 n_local_entries; - guint32 directory; - guint32 n_annotations; - guint32 annotations; - - guint32 size; - guint32 namespace; - guint32 shared_library; - - guint16 entry_blob_size; - guint16 function_blob_size; - guint16 callback_blob_size; - guint16 signal_blob_size; - guint16 vfunc_blob_size; - guint16 arg_blob_size; - guint16 property_blob_size; - guint16 field_blob_size; - guint16 value_blob_size; - guint16 annotation_blob_size; - guint16 constant_blob_size; - guint16 error_domain_blob_size; - - guint16 signature_blob_size; - guint16 enum_blob_size; - guint16 struct_blob_size; - guint16 object_blob_size; - guint16 interface_blob_size; - guint16 union_blob_size; - - guint16 padding[7]; -} Header; - -typedef struct -{ - guint16 blob_type; - - guint local : 1; - guint reserved :15; - - guint32 name; - guint32 offset; -} DirEntry; - - -#define TYPE_POINTER_MASK 1 << 7 -#define TYPE_TAG_MASK 63 - -typedef enum -{ - TYPE_TAG_VOID = 0, - TYPE_TAG_BOOLEAN = 1, - TYPE_TAG_INT8 = 2, - TYPE_TAG_UINT8 = 3, - TYPE_TAG_INT16 = 4, - TYPE_TAG_UINT16 = 5, - TYPE_TAG_INT32 = 6, - TYPE_TAG_UINT32 = 7, - TYPE_TAG_INT64 = 8, - TYPE_TAG_UINT64 = 9, - TYPE_TAG_INT = 10, - TYPE_TAG_UINT = 11, - TYPE_TAG_LONG = 12, - TYPE_TAG_ULONG = 13, - TYPE_TAG_SSIZE = 14, - TYPE_TAG_SIZE = 15, - TYPE_TAG_FLOAT = 16, - TYPE_TAG_DOUBLE = 17, - TYPE_TAG_UTF8 = 18, - TYPE_TAG_FILENAME = 19, - 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 union -{ - struct - { - guint reserved : 8; - guint reserved2 :16; - guint pointer : 1; - guint reserved3 : 2; - guint tag : 5; - }; - guint32 offset; -} SimpleTypeBlob; - - -typedef struct -{ - guint32 name; - - guint in : 1; - guint out : 1; - guint dipper : 1; - guint null_ok : 1; - guint optional : 1; - guint transfer_ownership : 1; - guint transfer_container_ownership : 1; - guint return_value : 1; - guint reserved :24; - - SimpleTypeBlob arg_type; -} ArgBlob; - -typedef struct -{ - SimpleTypeBlob return_type; - - guint may_return_null : 1; - guint caller_owns_return_value : 1; - guint caller_owns_return_container : 1; - guint reserved :13; - - guint16 n_arguments; - - ArgBlob arguments[]; -} SignatureBlob; - -typedef struct -{ - guint16 blob_type; /* 1 */ - - guint deprecated : 1; - guint reserved :15; - - guint32 name; -} CommonBlob; - -typedef struct -{ - guint16 blob_type; /* 1 */ - - guint deprecated : 1; - guint setter : 1; - guint getter : 1; - guint constructor : 1; - guint wraps_vfunc : 1; - guint reserved : 1; - guint index :10; - - guint32 name; - guint32 symbol; - guint32 signature; -} FunctionBlob; - -typedef struct -{ - guint16 blob_type; /* 2 */ - - guint deprecated : 1; - guint reserved :15; - - guint32 name; - guint32 signature; -} CallbackBlob; - -typedef struct -{ - guint pointer :1; - guint reserved :2; - guint tag :5; - guint8 reserved2; - guint16 interface; -} InterfaceTypeBlob; - -typedef struct -{ - guint pointer :1; - guint reserved :2; - guint tag :5; - - guint zero_terminated :1; - guint has_length :1; - guint reserved2 :6; - - guint16 length; - - SimpleTypeBlob type; -} ArrayTypeBlob; - -typedef struct -{ - guint pointer :1; - guint reserved :2; - guint tag :5; - - guint8 reserved2; - guint16 n_types; - - SimpleTypeBlob type[]; -} ParamTypeBlob; - -typedef struct -{ - guint pointer :1; - guint reserved :2; - guint tag :5; - - guint8 reserved2; - guint16 n_domains; - - guint16 domains[]; -} ErrorTypeBlob; - -typedef struct -{ - guint16 blob_type; /* 10 */ - - guint deprecated : 1; - guint reserved :15; - - guint32 name; - - guint32 get_quark; - guint16 error_codes; - guint16 reserved2; -} ErrorDomainBlob; - -typedef struct -{ - guint deprecated : 1; - guint reserved :31; - guint32 name; - guint32 value; -} ValueBlob; - -typedef struct -{ - guint32 name; - - guint readable : 1; - guint writable : 1; - guint reserved : 6; - guint8 bits; - - guint16 struct_offset; - - SimpleTypeBlob type; -} FieldBlob; - -typedef struct -{ - guint16 blob_type; - guint deprecated : 1; - guint unregistered :15; - guint32 name; - - guint32 gtype_name; - guint32 gtype_init; -} RegisteredTypeBlob; - -typedef struct -{ - guint16 blob_type; - - guint deprecated : 1; - guint unregistered : 1; - guint reserved :14; - - guint32 name; - - guint32 gtype_name; - guint32 gtype_init; - - guint16 n_fields; - guint16 n_methods; - -#if 0 - /* variable-length parts of the blob */ - FieldBlob fields[]; - FunctionBlob methods[]; -#endif -} StructBlob; - -typedef struct -{ - guint16 blob_type; - guint deprecated : 1; - guint unregistered : 1; - guint discriminated : 1; - guint reserved :13; - guint32 name; - - guint32 gtype_name; - guint32 gtype_init; - - guint16 n_fields; - guint16 n_functions; - - gint32 discriminator_offset; - SimpleTypeBlob discriminator_type; - -#if 0 - FieldBlob fields[]; - FunctionBlob functions[]; - ConstantBlob discriminator_values[] -#endif -} UnionBlob; - -typedef struct -{ - guint16 blob_type; - - guint deprecated : 1; - guint unregistered : 1; - guint reserved :14; - - guint32 name; - - guint32 gtype_name; - guint32 gtype_init; - - guint16 n_values; - guint16 reserved2; - - ValueBlob values[]; -} EnumBlob; - -typedef struct -{ - guint32 name; - - guint deprecated : 1; - guint readable : 1; - guint writable : 1; - guint construct : 1; - guint construct_only : 1; - guint reserved :27; - - SimpleTypeBlob type; - -} PropertyBlob; - -typedef struct -{ - guint deprecated : 1; - guint run_first : 1; - guint run_last : 1; - guint run_cleanup : 1; - guint no_recurse : 1; - guint detailed : 1; - guint action : 1; - guint no_hooks : 1; - guint has_class_closure : 1; - guint true_stops_emit : 1; - guint reserved : 6; - - guint16 class_closure; - - guint32 name; - - guint32 signature; -} SignalBlob; - -typedef struct -{ - guint32 name; - - guint must_chain_up : 1; - guint must_be_implemented : 1; - guint must_not_be_implemented : 1; - guint class_closure : 1; - guint reserved :12; - guint16 signal; - - guint16 struct_offset; - guint16 reserved2; - guint32 signature; -} VFuncBlob; - -typedef struct -{ - guint16 blob_type; /* 7 */ - guint deprecated : 1; - guint reserved :15; - guint32 name; - - guint32 gtype_name; - guint32 gtype_init; - - guint16 parent; - - guint16 n_interfaces; - guint16 n_fields; - guint16 n_properties; - guint16 n_methods; - guint16 n_signals; - guint16 n_vfuncs; - guint16 n_constants; - - guint16 interfaces[]; - -#if 0 - /* variable-length parts of the blob */ - FieldBlob fields[]; - PropertyBlob properties[]; - FunctionBlob methods[]; - SignalBlob signals[]; - VFuncBlob vfuncs[]; - ConstantBlob constants[]; -#endif -} ObjectBlob; - -typedef struct -{ - guint16 blob_type; - guint deprecated : 1; - guint reserved :15; - guint32 name; - - guint32 gtype_name; - guint32 gtype_init; - - guint16 n_prerequisites; - guint16 n_properties; - guint16 n_methods; - guint16 n_signals; - guint16 n_vfuncs; - guint16 n_constants; - - guint16 prerequisites[]; - -#if 0 - /* variable-length parts of the blob */ - PropertyBlob properties[]; - FunctionBlob methods[]; - SignalBlob signals[]; - VFuncBlob vfuncs[]; - ConstantBlob constants[]; -#endif -} InterfaceBlob; - - -typedef struct -{ - guint16 blob_type; - guint deprecated : 1; - guint reserved :15; - guint32 name; - - SimpleTypeBlob type; - - guint32 size; - guint32 offset; -} ConstantBlob; - -typedef struct -{ - guint32 offset; - guint32 name; - guint32 value; -} AnnotationBlob; - - -struct _GMetadata { - guchar *data; - gsize len; - gboolean owns_memory; - GMappedFile *mfile; - GModule *module; -}; - -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, - G_METADATA_ERROR_INVALID_HEADER, - G_METADATA_ERROR_INVALID_DIRECTORY, - G_METADATA_ERROR_INVALID_ENTRY, - G_METADATA_ERROR_INVALID_BLOB -} GMetadataError; - -#define G_METADATA_ERROR (g_metadata_error_quark ()) - -GQuark g_metadata_error_quark (void); - -gboolean g_metadata_validate (GMetadata *metadata, - GError **error); - - -G_END_DECLS - -#endif /* __G_METADATA_H__ */ - diff --git a/girepository/gtypelib.c b/girepository/gtypelib.c new file mode 100644 index 00000000..3df1918b --- /dev/null +++ b/girepository/gtypelib.c @@ -0,0 +1,1959 @@ +/* GObject introspection: metadata validation, auxiliary functions + * related to the binary metadata format + * + * Copyright (C) 2005 Matthias Clasen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + +#include + +#include "gtypelib.h" + + +#define ALIGN_VALUE(this, boundary) \ + (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) + + +DirEntry * +g_typelib_get_dir_entry (GTypelib *metadata, + guint16 index) +{ + Header *header = (Header *)metadata->data; + + return (DirEntry *)&metadata->data[header->directory + (index - 1) * header->entry_blob_size]; +} + +void +g_typelib_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) +{ + return offset == ALIGN_VALUE (offset, 4); +} + +#define MAX_NAME_LEN 200 + +static gboolean +is_name (const guchar *data, guint32 offset) +{ + gchar *name; + + name = (gchar*)&data[offset]; + + if (!memchr (name, '\0', MAX_NAME_LEN)) + return FALSE; + + if (strspn (name, G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_") < strlen (name)) + return FALSE; + + return TRUE; +} + +static gboolean +validate_header (GTypelib *metadata, + GError **error) +{ + Header *header; + + if (metadata->len < sizeof (Header)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + header = (Header *)metadata->data; + + if (strncmp (header->magic, G_IDL_MAGIC, 16) != 0) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_HEADER, + "Magic string not found"); + return FALSE; + + } + + if (header->major_version != 1 || header->minor_version != 0) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_HEADER, + "Version mismatch"); + return FALSE; + + } + + if (header->n_entries < header->n_local_entries) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_HEADER, + "Inconsistent entry counts"); + return FALSE; + } + + if (header->size != metadata->len) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_HEADER, + "Metadata size mismatch"); + 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_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_HEADER, + "Blob size mismatch"); + return FALSE; + } + + if (!is_aligned (header->directory)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_HEADER, + "Misaligned directory"); + return FALSE; + } + + if (!is_aligned (header->annotations)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_HEADER, + "Misaligned annotations"); + return FALSE; + } + + if (header->annotations == 0 && header->n_annotations > 0) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_HEADER, + "Wrong number of annotations"); + return FALSE; + } + + if (!is_name (metadata->data, header->namespace)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_HEADER, + "Invalid namespace name"); + return FALSE; + } + + return TRUE; +} + +static gboolean validate_type_blob (GTypelib *metadata, + guint32 offset, + guint32 signature_offset, + gboolean return_type, + GError **error); + +static gboolean +validate_array_type_blob (GTypelib *metadata, + guint32 offset, + guint32 signature_offset, + gboolean return_type, + GError **error) +{ + ArrayTypeBlob *blob; + + blob = (ArrayTypeBlob*)&metadata->data[offset]; + + if (!blob->pointer) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Pointer type exected for tag %d", blob->tag); + return FALSE; + } + + /* FIXME validate length */ + + if (!validate_type_blob (metadata, + offset + G_STRUCT_OFFSET (ArrayTypeBlob, type), + 0, FALSE, error)) + return FALSE; + + return TRUE; +} + +static gboolean +validate_iface_type_blob (GTypelib *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_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid directory index %d", blob->interface); + return FALSE; + } + + return TRUE; +} + +static gboolean +validate_param_type_blob (GTypelib *metadata, + guint32 offset, + guint32 signature_offset, + gboolean return_type, + gint n_params, + GError **error) +{ + ParamTypeBlob *blob; + gint i; + + blob = (ParamTypeBlob*)&metadata->data[offset]; + + if (!blob->pointer) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Pointer type exected for tag %d", blob->tag); + return FALSE; + } + + if (blob->n_types != n_params) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Parameter type number mismatch"); + return FALSE; + } + + for (i = 0; i < n_params; i++) + { + if (!validate_type_blob (metadata, + offset + sizeof (ParamTypeBlob) + + i * sizeof (SimpleTypeBlob), + 0, FALSE, error)) + return FALSE; + } + + return TRUE; +} + +static gboolean +validate_error_type_blob (GTypelib *metadata, + guint32 offset, + guint32 signature_offset, + gboolean return_type, + GError **error) +{ + ErrorTypeBlob *blob; + Header *header; + gint i; + DirEntry *entry; + + blob = (ErrorTypeBlob*)&metadata->data[offset]; + + header = (Header *)metadata->data; + + if (!blob->pointer) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Pointer type exected for tag %d", blob->tag); + return FALSE; + } + + for (i = 0; i < blob->n_domains; i++) + { + if (blob->domains[i] == 0 || blob->domains[i] > header->n_entries) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid directory index %d", blob->domains[i]); + return FALSE; + } + + entry = g_typelib_get_dir_entry (metadata, blob->domains[i]); + + if (entry->blob_type != BLOB_TYPE_ERROR_DOMAIN && + (entry->local || entry->blob_type != BLOB_TYPE_INVALID)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Wrong blob type"); + return FALSE; + } + } + + return TRUE; +} + +static gboolean +validate_type_blob (GTypelib *metadata, + guint32 offset, + guint32 signature_offset, + gboolean return_type, + GError **error) +{ + SimpleTypeBlob *simple; + InterfaceTypeBlob *iface; + + simple = (SimpleTypeBlob *)&metadata->data[offset]; + + if (simple->reserved == 0 && + simple->reserved2 == 0) + { + if (simple->tag >= TYPE_TAG_ARRAY) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Wrong tag in simple type"); + return FALSE; + } + + if (simple->tag >= TYPE_TAG_UTF8 && + !simple->pointer) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Pointer type exected for tag %d", simple->tag); + return FALSE; + } + + return TRUE; + } + + 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_INTERFACE: + if (!validate_iface_type_blob (metadata, simple->offset, + signature_offset, return_type, error)) + return FALSE; + break; + case TYPE_TAG_LIST: + case TYPE_TAG_SLIST: + if (!validate_param_type_blob (metadata, simple->offset, + signature_offset, return_type, 1, error)) + return FALSE; + break; + case TYPE_TAG_HASH: + if (!validate_param_type_blob (metadata, simple->offset, + signature_offset, return_type, 2, error)) + return FALSE; + break; + case TYPE_TAG_ERROR: + if (!validate_error_type_blob (metadata, simple->offset, + signature_offset, return_type, error)) + return FALSE; + break; + default: + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Wrong tag in complex type"); + return FALSE; + } + + return TRUE; +} + +static gboolean +validate_arg_blob (GTypelib *metadata, + guint32 offset, + guint32 signature_offset, + GError **error) +{ + ArgBlob *blob; + + if (metadata->len < offset + sizeof (ArgBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (ArgBlob*) &metadata->data[offset]; + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid argument name"); + return FALSE; + } + + if (!validate_type_blob (metadata, + offset + G_STRUCT_OFFSET (ArgBlob, arg_type), + signature_offset, FALSE, error)) + return FALSE; + + return TRUE; +} + +static gboolean +validate_signature_blob (GTypelib *metadata, + guint32 offset, + GError **error) +{ + SignatureBlob *blob; + gint i; + + if (metadata->len < offset + sizeof (SignatureBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (SignatureBlob*) &metadata->data[offset]; + + if (blob->return_type.offset != 0) + { + if (!validate_type_blob (metadata, + offset + G_STRUCT_OFFSET (SignatureBlob, return_type), + offset, TRUE, error)) + return FALSE; + } + + for (i = 0; i < blob->n_arguments; i++) + { + if (!validate_arg_blob (metadata, + offset + sizeof (SignatureBlob) + + i * sizeof (ArgBlob), + offset, + error)) + return FALSE; + } + + /* FIXME check constraints on return_value */ + /* FIXME check array-length pairs */ + return TRUE; +} + +static gboolean +validate_function_blob (GTypelib *metadata, + guint32 offset, + guint16 container_type, + GError **error) +{ + FunctionBlob *blob; + + if (metadata->len < offset + sizeof (FunctionBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (FunctionBlob*) &metadata->data[offset]; + + if (blob->blob_type != BLOB_TYPE_FUNCTION) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Wrong blob type"); + return FALSE; + } + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid function name"); + return FALSE; + } + + if (!is_name (metadata->data, blob->symbol)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid function symbol"); + return FALSE; + } + + if (blob->constructor) + { + switch (container_type) + { + case BLOB_TYPE_BOXED: + case BLOB_TYPE_OBJECT: + case BLOB_TYPE_INTERFACE: + break; + default: + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Constructor not allowed"); + return FALSE; + } + } + + if (blob->setter || blob->getter || blob->wraps_vfunc) + { + switch (container_type) + { + case BLOB_TYPE_OBJECT: + case BLOB_TYPE_INTERFACE: + break; + default: + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Setter, getter or wrapper not allowed"); + return FALSE; + } + } + + if (blob->index) + { + if (!(blob->setter || blob->getter || blob->wraps_vfunc)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Must be setter, getter or wrapper"); + return FALSE; + } + } + + /* FIXME: validate index range */ + /* FIXME: validate "this" argument for methods */ + /* FIXME: validate return type for constructors */ + + if (!validate_signature_blob (metadata, blob->signature, error)) + return FALSE; + + return TRUE; +} + +static gboolean +validate_callback_blob (GTypelib *metadata, + guint32 offset, + GError **error) +{ + CallbackBlob *blob; + + if (metadata->len < offset + sizeof (CallbackBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (CallbackBlob*) &metadata->data[offset]; + + if (blob->blob_type != BLOB_TYPE_CALLBACK) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Wrong blob type"); + return FALSE; + } + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid callback name"); + return FALSE; + } + + if (!validate_signature_blob (metadata, blob->signature, error)) + return FALSE; + + return TRUE; +} + +static gboolean +validate_constant_blob (GTypelib *metadata, + guint32 offset, + GError **error) +{ + gint value_size[] = { + 0, 4, 1, 1, 2, 2, 4, 4, 8, 8, + sizeof (gint), sizeof (guint), + sizeof (glong), sizeof (gulong), + sizeof (gssize), sizeof (gsize), + sizeof (gfloat), sizeof (gdouble), + 0, 0 + }; + ConstantBlob *blob; + SimpleTypeBlob *type; + + if (metadata->len < offset + sizeof (ConstantBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (ConstantBlob*) &metadata->data[offset]; + + if (blob->blob_type != BLOB_TYPE_CONSTANT) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Wrong blob type"); + return FALSE; + } + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid constant name"); + return FALSE; + } + + if (!validate_type_blob (metadata, offset + G_STRUCT_OFFSET (ConstantBlob, type), + 0, FALSE, error)) + return FALSE; + + if (!is_aligned (blob->offset)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Misaligned constant value"); + return FALSE; + } + + type = (SimpleTypeBlob *)&metadata->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)]; + if (type->reserved == 0) + { + if (type->tag == 0) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Constant value type void"); + return FALSE; + } + + if (value_size[type->tag] != 0 && + blob->size != value_size[type->tag]) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Constant value size mismatch"); + return FALSE; + } + /* FIXME check string values */ + } + + return TRUE; +} + +static gboolean +validate_value_blob (GTypelib *metadata, + guint32 offset, + GError **error) +{ + ValueBlob *blob; + + if (metadata->len < offset + sizeof (ValueBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (ValueBlob*) &metadata->data[offset]; + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid value name"); + return FALSE; + } + + return TRUE; +} + +static gboolean +validate_field_blob (GTypelib *metadata, + guint32 offset, + GError **error) +{ + FieldBlob *blob; + + if (metadata->len < offset + sizeof (FieldBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (FieldBlob*) &metadata->data[offset]; + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid field name"); + return FALSE; + } + + if (!validate_type_blob (metadata, + offset + G_STRUCT_OFFSET (FieldBlob, type), + 0, FALSE, error)) + return FALSE; + + return TRUE; +} + +static gboolean +validate_property_blob (GTypelib *metadata, + guint32 offset, + GError **error) +{ + PropertyBlob *blob; + + if (metadata->len < offset + sizeof (PropertyBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (PropertyBlob*) &metadata->data[offset]; + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid property name"); + return FALSE; + } + + if (!validate_type_blob (metadata, + offset + G_STRUCT_OFFSET (PropertyBlob, type), + 0, FALSE, error)) + return FALSE; + + return TRUE; +} + +static gboolean +validate_signal_blob (GTypelib *metadata, + guint32 offset, + guint32 container_offset, + GError **error) +{ + SignalBlob *blob; + gint n_signals; + + if (metadata->len < offset + sizeof (SignalBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (SignalBlob*) &metadata->data[offset]; + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid signal name"); + return FALSE; + } + + if ((blob->run_first != 0) + + (blob->run_last != 0) + + (blob->run_cleanup != 0) != 1) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid signal run flags"); + return FALSE; + } + + if (blob->has_class_closure) + { + if (((CommonBlob*)&metadata->data[container_offset])->blob_type == BLOB_TYPE_OBJECT) + { + ObjectBlob *object; + + object = (ObjectBlob*)&metadata->data[container_offset]; + + n_signals = object->n_signals; + } + else + { + InterfaceBlob *iface; + + iface = (InterfaceBlob*)&metadata->data[container_offset]; + + n_signals = iface->n_signals; + } + + if (blob->class_closure >= n_signals) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid class closure index"); + return FALSE; + } + } + + if (!validate_signature_blob (metadata, blob->signature, error)) + return FALSE; + + return TRUE; +} + +static gboolean +validate_vfunc_blob (GTypelib *metadata, + guint32 offset, + guint32 container_offset, + GError **error) +{ + VFuncBlob *blob; + gint n_vfuncs; + + if (metadata->len < offset + sizeof (VFuncBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (VFuncBlob*) &metadata->data[offset]; + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid vfunc name"); + return FALSE; + } + + if (blob->class_closure) + { + if (((CommonBlob*)&metadata->data[container_offset])->blob_type == BLOB_TYPE_OBJECT) + { + ObjectBlob *object; + + object = (ObjectBlob*)&metadata->data[container_offset]; + + n_vfuncs = object->n_vfuncs; + } + else + { + InterfaceBlob *iface; + + iface = (InterfaceBlob*)&metadata->data[container_offset]; + + n_vfuncs = iface->n_vfuncs; + } + + if (blob->class_closure >= n_vfuncs) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid class closure index"); + return FALSE; + } + } + + if (!validate_signature_blob (metadata, blob->signature, error)) + return FALSE; + + return TRUE; +} + +static gboolean +validate_struct_blob (GTypelib *metadata, + guint32 offset, + guint16 blob_type, + GError **error) +{ + StructBlob *blob; + gint i; + + if (metadata->len < offset + sizeof (StructBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (StructBlob*) &metadata->data[offset]; + + if (blob->blob_type != blob_type) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Wrong blob type"); + return FALSE; + } + + if ((blob->blob_type == BLOB_TYPE_BOXED && blob->unregistered) || + (blob->blob_type == BLOB_TYPE_STRUCT && !blob->unregistered)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Registration/blob type mismatch"); + return FALSE; + } + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid struct name"); + return FALSE; + } + + if (blob_type == BLOB_TYPE_BOXED) + { + if (!is_name (metadata->data, blob->gtype_name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid boxed type name"); + return FALSE; + } + + if (!is_name (metadata->data, blob->gtype_init)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid boxed type init"); + return FALSE; + } + } + else + { + if (blob->gtype_name || blob->gtype_init) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Gtype data in struct"); + return FALSE; + } + } + + if (metadata->len < offset + sizeof (StructBlob) + + blob->n_fields * sizeof (FieldBlob) + + blob->n_methods * sizeof (FunctionBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + for (i = 0; i < blob->n_fields; i++) + { + if (!validate_field_blob (metadata, + offset + sizeof (StructBlob) + + i * sizeof (FieldBlob), + error)) + return FALSE; + } + + for (i = 0; i < blob->n_methods; i++) + { + if (!validate_function_blob (metadata, + offset + sizeof (StructBlob) + + blob->n_fields * sizeof (FieldBlob) + + i * sizeof (FunctionBlob), + blob_type, + error)) + return FALSE; + } + + return TRUE; +} + +static gboolean +validate_enum_blob (GTypelib *metadata, + guint32 offset, + guint16 blob_type, + GError **error) +{ + EnumBlob *blob; + ValueBlob *v1, *v2; + gint i, j; + + if (metadata->len < offset + sizeof (EnumBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (EnumBlob*) &metadata->data[offset]; + + if (blob->blob_type != blob_type) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Wrong blob type"); + return FALSE; + } + + if (!blob->unregistered) + { + if (!is_name (metadata->data, blob->gtype_name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid enum type name"); + return FALSE; + } + + if (!is_name (metadata->data, blob->gtype_init)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid enum type init"); + return FALSE; + } + } + else + { + if (blob->gtype_name || blob->gtype_init) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Gtype data in unregistered enum"); + return FALSE; + } + } + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid enum name"); + return FALSE; + } + + if (metadata->len < offset + sizeof (EnumBlob) + + blob->n_values * sizeof (ValueBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + for (i = 0; i < blob->n_values; i++) + { + if (!validate_value_blob (metadata, + offset + sizeof (EnumBlob) + + i * sizeof (ValueBlob), + error)) + return FALSE; + + v1 = (ValueBlob *)&metadata->data[offset + sizeof (EnumBlob) + + i * sizeof (ValueBlob)]; + for (j = 0; j < i; j++) + { + v2 = (ValueBlob *)&metadata->data[offset + sizeof (EnumBlob) + + j * sizeof (ValueBlob)]; + + if (v1->value == v2->value) + { + /* FIXME should this be an error ? */ + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Duplicate enum value"); + return FALSE; + } + } + } + + return TRUE; +} + +static gboolean +validate_object_blob (GTypelib *metadata, + guint32 offset, + GError **error) +{ + Header *header; + ObjectBlob *blob; + gint i; + guint32 offset2; + + header = (Header *)metadata->data; + + if (metadata->len < offset + sizeof (ObjectBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (ObjectBlob*) &metadata->data[offset]; + + if (blob->blob_type != BLOB_TYPE_OBJECT) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Wrong blob type"); + return FALSE; + } + + if (!is_name (metadata->data, blob->gtype_name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid object type name"); + return FALSE; + } + + if (!is_name (metadata->data, blob->gtype_init)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid object type init"); + return FALSE; + } + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid object name"); + return FALSE; + } + + if (blob->parent > header->n_entries) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid parent index"); + return FALSE; + } + + if (blob->parent != 0) + { + DirEntry *entry; + + entry = g_typelib_get_dir_entry (metadata, blob->parent); + if (entry->blob_type != BLOB_TYPE_OBJECT && + (entry->local || entry->blob_type != 0)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Parent not object"); + return FALSE; + } + } + + if (metadata->len < offset + sizeof (ObjectBlob) + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * sizeof (FieldBlob) + + blob->n_properties * sizeof (PropertyBlob) + + blob->n_methods * sizeof (FunctionBlob) + + blob->n_signals * sizeof (SignalBlob) + + blob->n_vfuncs * sizeof (VFuncBlob) + + blob->n_constants * sizeof (ConstantBlob)) + + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + offset2 = offset + sizeof (ObjectBlob); + + for (i = 0; i < blob->n_interfaces; i++, offset2 += 2) + { + guint16 iface; + DirEntry *entry; + + iface = *(guint16*)&metadata->data[offset2]; + if (iface == 0 || iface > header->n_entries) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid interface index"); + return FALSE; + } + + entry = g_typelib_get_dir_entry (metadata, iface); + + if (entry->blob_type != BLOB_TYPE_INTERFACE && + (entry->local || entry->blob_type != 0)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Not an interface"); + return FALSE; + } + } + + offset2 += 2 * (blob->n_interfaces %2); + + for (i = 0; i < blob->n_fields; i++, offset2 += sizeof (FieldBlob)) + { + if (!validate_field_blob (metadata, offset2, error)) + return FALSE; + } + + for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob)) + { + if (!validate_property_blob (metadata, offset2, error)) + return FALSE; + } + + for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob)) + { + if (!validate_function_blob (metadata, offset2, BLOB_TYPE_OBJECT, error)) + return FALSE; + } + + for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob)) + { + if (!validate_signal_blob (metadata, offset2, offset, error)) + return FALSE; + } + + for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob)) + { + if (!validate_vfunc_blob (metadata, offset2, offset, error)) + return FALSE; + } + + for (i = 0; i < blob->n_constants; i++, offset2 += sizeof (ConstantBlob)) + { + if (!validate_constant_blob (metadata, offset2, error)) + return FALSE; + } + + return TRUE; +} + +static gboolean +validate_interface_blob (GTypelib *metadata, + guint32 offset, + GError **error) +{ + Header *header; + InterfaceBlob *blob; + gint i; + guint32 offset2; + + header = (Header *)metadata->data; + + if (metadata->len < offset + sizeof (InterfaceBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (InterfaceBlob*) &metadata->data[offset]; + + if (blob->blob_type != BLOB_TYPE_INTERFACE) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Wrong blob type"); + return FALSE; + } + + if (!is_name (metadata->data, blob->gtype_name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid interface type name"); + return FALSE; + } + + if (!is_name (metadata->data, blob->gtype_init)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid interface type init"); + return FALSE; + } + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid interface name"); + return FALSE; + } + + if (metadata->len < offset + sizeof (InterfaceBlob) + + (blob->n_prerequisites + blob->n_prerequisites % 2) * 2 + + blob->n_properties * sizeof (PropertyBlob) + + blob->n_methods * sizeof (FunctionBlob) + + blob->n_signals * sizeof (SignalBlob) + + blob->n_vfuncs * sizeof (VFuncBlob) + + blob->n_constants * sizeof (ConstantBlob)) + + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + offset2 = offset + sizeof (InterfaceBlob); + + for (i = 0; i < blob->n_prerequisites; i++, offset2 += 2) + { + DirEntry *entry; + guint16 req; + + req = *(guint16*)&metadata->data[offset2]; + if (req == 0 || req > header->n_entries) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid prerequisite index"); + return FALSE; + } + + entry = g_typelib_get_dir_entry (metadata, req); + if (entry->blob_type != BLOB_TYPE_INTERFACE && + entry->blob_type != BLOB_TYPE_OBJECT && + (entry->local || entry->blob_type != 0)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Not an interface or object"); + return FALSE; + } + } + + offset2 += 2 * (blob->n_prerequisites % 2); + + for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob)) + { + if (!validate_property_blob (metadata, offset2, error)) + return FALSE; + } + + for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob)) + { + if (!validate_function_blob (metadata, offset2, BLOB_TYPE_INTERFACE, error)) + return FALSE; + } + + for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob)) + { + if (!validate_signal_blob (metadata, offset2, offset, error)) + return FALSE; + } + + for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob)) + { + if (!validate_vfunc_blob (metadata, offset2, offset, error)) + return FALSE; + } + + for (i = 0; i < blob->n_constants; i++, offset2 += sizeof (ConstantBlob)) + { + if (!validate_constant_blob (metadata, offset2, error)) + return FALSE; + } + + return TRUE; +} + +static gboolean +validate_errordomain_blob (GTypelib *metadata, + guint32 offset, + GError **error) +{ + return TRUE; +} + +static gboolean +validate_union_blob (GTypelib *metadata, + guint32 offset, + GError **error) +{ + return TRUE; +} + +static gboolean +validate_blob (GTypelib *metadata, + guint32 offset, + GError **error) +{ + CommonBlob *common; + + if (metadata->len < offset + sizeof (CommonBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + common = (CommonBlob*)&metadata->data[offset]; + + switch (common->blob_type) + { + case BLOB_TYPE_FUNCTION: + if (!validate_function_blob (metadata, offset, 0, error)) + return FALSE; + break; + case BLOB_TYPE_CALLBACK: + if (!validate_callback_blob (metadata, offset, error)) + return FALSE; + break; + case BLOB_TYPE_STRUCT: + case BLOB_TYPE_BOXED: + if (!validate_struct_blob (metadata, offset, common->blob_type, error)) + return FALSE; + break; + case BLOB_TYPE_ENUM: + case BLOB_TYPE_FLAGS: + if (!validate_enum_blob (metadata, offset, common->blob_type, error)) + return FALSE; + break; + case BLOB_TYPE_OBJECT: + if (!validate_object_blob (metadata, offset, error)) + return FALSE; + break; + case BLOB_TYPE_INTERFACE: + if (!validate_interface_blob (metadata, offset, error)) + return FALSE; + break; + case BLOB_TYPE_CONSTANT: + if (!validate_constant_blob (metadata, offset, error)) + return FALSE; + break; + case BLOB_TYPE_ERROR_DOMAIN: + if (!validate_errordomain_blob (metadata, offset, error)) + return FALSE; + break; + case BLOB_TYPE_UNION: + if (!validate_union_blob (metadata, offset, error)) + return FALSE; + break; + default: + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_ENTRY, + "Invalid blob type"); + return FALSE; + } + + return TRUE; +} + +static gboolean +validate_directory (GTypelib *metadata, + GError **error) +{ + Header *header = (Header *)metadata->data; + DirEntry *entry; + gint i; + + if (metadata->len < header->directory + header->n_entries * sizeof (DirEntry)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + for (i = 0; i < header->n_entries; i++) + { + entry = g_typelib_get_dir_entry (metadata, i + 1); + + if (!is_name (metadata->data, entry->name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_DIRECTORY, + "Invalid entry name"); + return FALSE; + } + + if ((entry->local && entry->blob_type == BLOB_TYPE_INVALID) || + entry->blob_type > BLOB_TYPE_UNION) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_DIRECTORY, + "Invalid entry type"); + return FALSE; + } + + if (i < header->n_local_entries) + { + if (!entry->local) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_DIRECTORY, + "Too few local directory entries"); + return FALSE; + } + + if (!is_aligned (entry->offset)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_DIRECTORY, + "Misaligned entry"); + return FALSE; + } + + if (!validate_blob (metadata, entry->offset, error)) + return FALSE; + } + else + { + if (entry->local) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_DIRECTORY, + "Too many local directory entries"); + return FALSE; + } + + if (!is_name (metadata->data, entry->offset)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_DIRECTORY, + "Invalid namespace name"); + return FALSE; + } + } + } + + return TRUE; +} + +static gboolean +validate_annotations (GTypelib *metadata, + GError **error) +{ + Header *header = (Header *)metadata->data; + + if (header->size < header->annotations + header->n_annotations * sizeof (AnnotationBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + return TRUE; +} + +gboolean +g_typelib_validate (GTypelib *metadata, + GError **error) +{ + if (!validate_header (metadata, error)) + return FALSE; + + if (!validate_directory (metadata, error)) + return FALSE; + + if (!validate_annotations (metadata, error)) + return FALSE; + + return TRUE; +} + +GQuark +g_typelib_error_quark (void) +{ + static GQuark quark = 0; + if (quark == 0) + quark = g_quark_from_static_string ("g-metadata-error-quark"); + return quark; +} + +static const char* +find_some_symbol (GTypelib *metadata) +{ + Header *header = (Header *) metadata->data; + gint i; + + for (i = 0; i < header->n_entries; i++) + { + DirEntry *entry; + + entry = g_typelib_get_dir_entry (metadata, i + 1); + + switch (entry->blob_type) + { + case BLOB_TYPE_FUNCTION: + { + FunctionBlob *blob = (FunctionBlob *) &metadata->data[entry->offset]; + + if (blob->symbol) + return g_typelib_get_string (metadata, blob->symbol); + } + break; + case BLOB_TYPE_OBJECT: + { + RegisteredTypeBlob *blob = (RegisteredTypeBlob *) &metadata->data[entry->offset]; + + if (blob->gtype_init) + return g_typelib_get_string (metadata, blob->gtype_init); + } + break; + default: + break; + } + } + + return NULL; +} + +static inline void +_g_typelib_init (GTypelib *metadata) +{ + Header *header; + + header = (Header *) metadata->data; + if (header->shared_library) + { + const gchar *shlib; + + shlib = g_typelib_get_string (metadata, header->shared_library); + /* note that NULL shlib means to open the main app, which is allowed */ + + /* If we do have a shared lib, first be sure the main app isn't already linked to it */ + if (shlib != NULL) + { + const char *symbol_in_module; + + symbol_in_module = find_some_symbol (metadata); + if (symbol_in_module != NULL) + { + metadata->module = g_module_open (NULL, G_MODULE_BIND_LAZY); + if (metadata->module == NULL) + { + g_warning ("Could not open main app as GModule: %s", + g_module_error ()); + } + else + { + void *sym; + if (!g_module_symbol (metadata->module, symbol_in_module, &sym)) + { + /* we will try opening the shlib, symbol is not in app already */ + g_module_close (metadata->module); + metadata->module = NULL; + } + } + } + else + { + g_warning ("Could not find any symbols in metadata"); + } + } + + if (metadata->module == NULL) + { + /* Glade's autoconnect feature and OpenGL's extension mechanism + * as used by Clutter rely on dlopen(NULL) to work as a means of + * accessing the app's symbols. This keeps us from using + * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well; + * in general libraries are not expecting multiple copies of + * themselves and are not expecting to be unloaded. So we just + * load modules globally for now. + */ + + metadata->module = g_module_open (shlib, G_MODULE_BIND_LAZY); + if (metadata->module == NULL) + g_warning ("Failed to load shared library referenced by the metadata: %s", + g_module_error ()); + } + } +} + +/** + * g_typelib_new_from_memory: + * @memory: address of memory chunk containing the metadata + * @len: length of memory chunk containing the metadata + * + * Creates a new #GTypelib from a memory location. The memory block + * pointed to by @metadata will be automatically g_free()d when the + * repository is destroyed. + * + * Return value: the new #GTypelib + **/ +GTypelib * +g_typelib_new_from_memory (guchar *memory, gsize len) +{ + GTypelib *meta; + + meta = g_new0 (GTypelib, 1); + meta->data = memory; + meta->len = len; + meta->owns_memory = TRUE; + _g_typelib_init (meta); + return meta; +} + +/** + * g_typelib_new_from_const_memory: + * @memory: address of memory chunk containing the metadata + * @len: length of memory chunk containing the metadata + * + * Creates a new #GTypelib from a memory location. + * + * Return value: the new #GTypelib + **/ +GTypelib * +g_typelib_new_from_const_memory (const guchar *memory, gsize len) +{ + GTypelib *meta; + + meta = g_new0 (GTypelib, 1); + meta->data = (guchar *) memory; + meta->len = len; + meta->owns_memory = FALSE; + _g_typelib_init (meta); + return meta; +} + +/** + * g_typelib_new_from_mapped_file: + * @mfile: a #GMappedFile, that will be free'd when the repository is destroyed + * + * Creates a new #GTypelib from a #GMappedFile. + * + * Return value: the new #GTypelib + **/ +GTypelib * +g_typelib_new_from_mapped_file (GMappedFile *mfile) +{ + GTypelib *meta; + + meta = g_new0 (GTypelib, 1); + meta->mfile = mfile; + meta->owns_memory = FALSE; + meta->data = (guchar *) g_mapped_file_get_contents (mfile); + meta->len = g_mapped_file_get_length (mfile); + _g_typelib_init (meta); + return meta; +} + +/** + * g_typelib_free: + * @metadata: a #GTypelib + * + * Free a #GTypelib. + **/ +void +g_typelib_free (GTypelib *metadata) +{ + if (metadata->mfile) + g_mapped_file_free (metadata->mfile); + else + if (metadata->owns_memory) + g_free (metadata->data); + if (metadata->module) + g_module_close (metadata->module); + g_free (metadata); +} + +/** + * g_typelib_set_module: + * @metadata: a #GTypelib instance + * @module: a #GModule; takes ownership of this module + * + * Sets the target module for all symbols referenced by the metadata. + **/ +void +g_typelib_set_module (GTypelib *metadata, GModule *module) +{ + if (metadata->module) + g_module_close (metadata->module); + metadata->module = module; +} + +const gchar * +g_typelib_get_namespace(GTypelib *metadata) +{ + return g_typelib_get_string (metadata, ((Header *) metadata->data)->namespace); +} diff --git a/girepository/gtypelib.h b/girepository/gtypelib.h new file mode 100644 index 00000000..352c3a8e --- /dev/null +++ b/girepository/gtypelib.h @@ -0,0 +1,549 @@ +/* GObject introspection: struct definitions for the binary + * metadata format, validation + * + * Copyright (C) 2005 Matthias Clasen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __G_TYPELIB_H__ +#define __G_TYPELIB_H__ + +#include +#include "girepository.h" + +G_BEGIN_DECLS + +#define G_IDL_MAGIC "GOBJ\nMETADATA\r\n\032" + +enum +{ + BLOB_TYPE_INVALID, + BLOB_TYPE_FUNCTION, + BLOB_TYPE_CALLBACK, + BLOB_TYPE_STRUCT, + BLOB_TYPE_BOXED, + BLOB_TYPE_ENUM, + BLOB_TYPE_FLAGS, + BLOB_TYPE_OBJECT, + BLOB_TYPE_INTERFACE, + BLOB_TYPE_CONSTANT, + BLOB_TYPE_ERROR_DOMAIN, + BLOB_TYPE_UNION +}; + +typedef struct +{ + gchar magic[16]; + guint8 major_version; + guint8 minor_version; + guint16 reserved; + guint16 n_entries; + guint16 n_local_entries; + guint32 directory; + guint32 n_annotations; + guint32 annotations; + + guint32 size; + guint32 namespace; + guint32 shared_library; + + guint16 entry_blob_size; + guint16 function_blob_size; + guint16 callback_blob_size; + guint16 signal_blob_size; + guint16 vfunc_blob_size; + guint16 arg_blob_size; + guint16 property_blob_size; + guint16 field_blob_size; + guint16 value_blob_size; + guint16 annotation_blob_size; + guint16 constant_blob_size; + guint16 error_domain_blob_size; + + guint16 signature_blob_size; + guint16 enum_blob_size; + guint16 struct_blob_size; + guint16 object_blob_size; + guint16 interface_blob_size; + guint16 union_blob_size; + + guint16 padding[7]; +} Header; + +typedef struct +{ + guint16 blob_type; + + guint local : 1; + guint reserved :15; + + guint32 name; + guint32 offset; +} DirEntry; + + +#define TYPE_POINTER_MASK 1 << 7 +#define TYPE_TAG_MASK 63 + +typedef enum +{ + TYPE_TAG_VOID = 0, + TYPE_TAG_BOOLEAN = 1, + TYPE_TAG_INT8 = 2, + TYPE_TAG_UINT8 = 3, + TYPE_TAG_INT16 = 4, + TYPE_TAG_UINT16 = 5, + TYPE_TAG_INT32 = 6, + TYPE_TAG_UINT32 = 7, + TYPE_TAG_INT64 = 8, + TYPE_TAG_UINT64 = 9, + TYPE_TAG_INT = 10, + TYPE_TAG_UINT = 11, + TYPE_TAG_LONG = 12, + TYPE_TAG_ULONG = 13, + TYPE_TAG_SSIZE = 14, + TYPE_TAG_SIZE = 15, + TYPE_TAG_FLOAT = 16, + TYPE_TAG_DOUBLE = 17, + TYPE_TAG_UTF8 = 18, + TYPE_TAG_FILENAME = 19, + 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 union +{ + struct + { + guint reserved : 8; + guint reserved2 :16; + guint pointer : 1; + guint reserved3 : 2; + guint tag : 5; + }; + guint32 offset; +} SimpleTypeBlob; + + +typedef struct +{ + guint32 name; + + guint in : 1; + guint out : 1; + guint dipper : 1; + guint null_ok : 1; + guint optional : 1; + guint transfer_ownership : 1; + guint transfer_container_ownership : 1; + guint return_value : 1; + guint reserved :24; + + SimpleTypeBlob arg_type; +} ArgBlob; + +typedef struct +{ + SimpleTypeBlob return_type; + + guint may_return_null : 1; + guint caller_owns_return_value : 1; + guint caller_owns_return_container : 1; + guint reserved :13; + + guint16 n_arguments; + + ArgBlob arguments[]; +} SignatureBlob; + +typedef struct +{ + guint16 blob_type; /* 1 */ + + guint deprecated : 1; + guint reserved :15; + + guint32 name; +} CommonBlob; + +typedef struct +{ + guint16 blob_type; /* 1 */ + + guint deprecated : 1; + guint setter : 1; + guint getter : 1; + guint constructor : 1; + guint wraps_vfunc : 1; + guint reserved : 1; + guint index :10; + + guint32 name; + guint32 symbol; + guint32 signature; +} FunctionBlob; + +typedef struct +{ + guint16 blob_type; /* 2 */ + + guint deprecated : 1; + guint reserved :15; + + guint32 name; + guint32 signature; +} CallbackBlob; + +typedef struct +{ + guint pointer :1; + guint reserved :2; + guint tag :5; + guint8 reserved2; + guint16 interface; +} InterfaceTypeBlob; + +typedef struct +{ + guint pointer :1; + guint reserved :2; + guint tag :5; + + guint zero_terminated :1; + guint has_length :1; + guint reserved2 :6; + + guint16 length; + + SimpleTypeBlob type; +} ArrayTypeBlob; + +typedef struct +{ + guint pointer :1; + guint reserved :2; + guint tag :5; + + guint8 reserved2; + guint16 n_types; + + SimpleTypeBlob type[]; +} ParamTypeBlob; + +typedef struct +{ + guint pointer :1; + guint reserved :2; + guint tag :5; + + guint8 reserved2; + guint16 n_domains; + + guint16 domains[]; +} ErrorTypeBlob; + +typedef struct +{ + guint16 blob_type; /* 10 */ + + guint deprecated : 1; + guint reserved :15; + + guint32 name; + + guint32 get_quark; + guint16 error_codes; + guint16 reserved2; +} ErrorDomainBlob; + +typedef struct +{ + guint deprecated : 1; + guint reserved :31; + guint32 name; + guint32 value; +} ValueBlob; + +typedef struct +{ + guint32 name; + + guint readable : 1; + guint writable : 1; + guint reserved : 6; + guint8 bits; + + guint16 struct_offset; + + SimpleTypeBlob type; +} FieldBlob; + +typedef struct +{ + guint16 blob_type; + guint deprecated : 1; + guint unregistered :15; + guint32 name; + + guint32 gtype_name; + guint32 gtype_init; +} RegisteredTypeBlob; + +typedef struct +{ + guint16 blob_type; + + guint deprecated : 1; + guint unregistered : 1; + guint reserved :14; + + guint32 name; + + guint32 gtype_name; + guint32 gtype_init; + + guint16 n_fields; + guint16 n_methods; + +#if 0 + /* variable-length parts of the blob */ + FieldBlob fields[]; + FunctionBlob methods[]; +#endif +} StructBlob; + +typedef struct +{ + guint16 blob_type; + guint deprecated : 1; + guint unregistered : 1; + guint discriminated : 1; + guint reserved :13; + guint32 name; + + guint32 gtype_name; + guint32 gtype_init; + + guint16 n_fields; + guint16 n_functions; + + gint32 discriminator_offset; + SimpleTypeBlob discriminator_type; + +#if 0 + FieldBlob fields[]; + FunctionBlob functions[]; + ConstantBlob discriminator_values[] +#endif +} UnionBlob; + +typedef struct +{ + guint16 blob_type; + + guint deprecated : 1; + guint unregistered : 1; + guint reserved :14; + + guint32 name; + + guint32 gtype_name; + guint32 gtype_init; + + guint16 n_values; + guint16 reserved2; + + ValueBlob values[]; +} EnumBlob; + +typedef struct +{ + guint32 name; + + guint deprecated : 1; + guint readable : 1; + guint writable : 1; + guint construct : 1; + guint construct_only : 1; + guint reserved :27; + + SimpleTypeBlob type; + +} PropertyBlob; + +typedef struct +{ + guint deprecated : 1; + guint run_first : 1; + guint run_last : 1; + guint run_cleanup : 1; + guint no_recurse : 1; + guint detailed : 1; + guint action : 1; + guint no_hooks : 1; + guint has_class_closure : 1; + guint true_stops_emit : 1; + guint reserved : 6; + + guint16 class_closure; + + guint32 name; + + guint32 signature; +} SignalBlob; + +typedef struct +{ + guint32 name; + + guint must_chain_up : 1; + guint must_be_implemented : 1; + guint must_not_be_implemented : 1; + guint class_closure : 1; + guint reserved :12; + guint16 signal; + + guint16 struct_offset; + guint16 reserved2; + guint32 signature; +} VFuncBlob; + +typedef struct +{ + guint16 blob_type; /* 7 */ + guint deprecated : 1; + guint reserved :15; + guint32 name; + + guint32 gtype_name; + guint32 gtype_init; + + guint16 parent; + + guint16 n_interfaces; + guint16 n_fields; + guint16 n_properties; + guint16 n_methods; + guint16 n_signals; + guint16 n_vfuncs; + guint16 n_constants; + + guint16 interfaces[]; + +#if 0 + /* variable-length parts of the blob */ + FieldBlob fields[]; + PropertyBlob properties[]; + FunctionBlob methods[]; + SignalBlob signals[]; + VFuncBlob vfuncs[]; + ConstantBlob constants[]; +#endif +} ObjectBlob; + +typedef struct +{ + guint16 blob_type; + guint deprecated : 1; + guint reserved :15; + guint32 name; + + guint32 gtype_name; + guint32 gtype_init; + + guint16 n_prerequisites; + guint16 n_properties; + guint16 n_methods; + guint16 n_signals; + guint16 n_vfuncs; + guint16 n_constants; + + guint16 prerequisites[]; + +#if 0 + /* variable-length parts of the blob */ + PropertyBlob properties[]; + FunctionBlob methods[]; + SignalBlob signals[]; + VFuncBlob vfuncs[]; + ConstantBlob constants[]; +#endif +} InterfaceBlob; + + +typedef struct +{ + guint16 blob_type; + guint deprecated : 1; + guint reserved :15; + guint32 name; + + SimpleTypeBlob type; + + guint32 size; + guint32 offset; +} ConstantBlob; + +typedef struct +{ + guint32 offset; + guint32 name; + guint32 value; +} AnnotationBlob; + + +struct _GTypelib { + guchar *data; + gsize len; + gboolean owns_memory; + GMappedFile *mfile; + GModule *module; +}; + +DirEntry *g_typelib_get_dir_entry (GTypelib *metadata, + guint16 index); + +void g_typelib_check_sanity (void); + +#define g_typelib_get_string(metadata,offset) ((const gchar*)&(metadata->data)[(offset)]) + + +typedef enum +{ + G_TYPELIB_ERROR_INVALID, + G_TYPELIB_ERROR_INVALID_HEADER, + G_TYPELIB_ERROR_INVALID_DIRECTORY, + G_TYPELIB_ERROR_INVALID_ENTRY, + G_TYPELIB_ERROR_INVALID_BLOB +} GTypelibError; + +#define G_TYPELIB_ERROR (g_typelib_error_quark ()) + +GQuark g_typelib_error_quark (void); + +gboolean g_typelib_validate (GTypelib *metadata, + GError **error); + + +G_END_DECLS + +#endif /* __G_TYPELIB_H__ */ + diff --git a/tools/compiler.c b/tools/compiler.c index 6ab0fa54..68fc3cae 100644 --- a/tools/compiler.c +++ b/tools/compiler.c @@ -27,7 +27,7 @@ #include "gidlmodule.h" #include "gidlnode.h" #include "gidlparser.h" -#include "gmetadata.h" +#include "gtypelib.h" gboolean raw = FALSE; gboolean no_init = FALSE; @@ -39,7 +39,7 @@ gboolean debug = FALSE; gboolean verbose = FALSE; static gchar * -format_output (GMetadata *metadata) +format_output (GTypelib *metadata) { GString *result; gint i; @@ -49,7 +49,7 @@ format_output (GMetadata *metadata) g_string_append_printf (result, "#include \n"); g_string_append_printf (result, "#include \n\n"); - g_string_append_printf (result, "const unsigned char _G_METADATA[] = \n{"); + g_string_append_printf (result, "const unsigned char _G_TYPELIB[] = \n{"); for (i = 0; i < metadata->len; i++) { @@ -63,7 +63,7 @@ format_output (GMetadata *metadata) } g_string_append_printf (result, "\n};\n\n"); - g_string_append_printf (result, "const gsize _G_METADATA_SIZE = %u;\n\n", + g_string_append_printf (result, "const gsize _G_TYPELIB_SIZE = %u;\n\n", (guint)metadata->len); if (!no_init) @@ -72,8 +72,8 @@ format_output (GMetadata *metadata) "__attribute__((constructor)) void\n" "register_metadata (void)\n" "{\n" - "\tGMetadata *metadata;\n" - "\tmetadata = g_metadata_new_from_const_memory (_G_METADATA, _G_METADATA_SIZE);\n" + "\tGTypelib *metadata;\n" + "\tmetadata = g_typelib_new_from_const_memory (_G_TYPELIB, _G_TYPELIB_SIZE);\n" "\tg_irepository_register (NULL, metadata);\n" "}\n\n"); @@ -83,7 +83,7 @@ format_output (GMetadata *metadata) "{\n" "\tg_irepository_unregister (NULL, \"%s\");\n" "}\n", - g_metadata_get_namespace (metadata)); + g_typelib_get_namespace (metadata)); } return g_string_free (result, FALSE); @@ -91,7 +91,7 @@ format_output (GMetadata *metadata) static void write_out_metadata (gchar *prefix, - GMetadata *metadata) + GTypelib *metadata) { FILE *file; @@ -167,7 +167,7 @@ main (int argc, char ** argv) GError *error = NULL; GList *c, *m, *modules; gint i; - g_metadata_check_sanity (); + g_typelib_check_sanity (); context = g_option_context_new (""); g_option_context_add_main_entries (context, options, NULL); @@ -210,7 +210,7 @@ main (int argc, char ** argv) { GIdlModule *module = m->data; gchar *prefix; - GMetadata *metadata; + GTypelib *metadata; if (mname && strcmp (mname, module->name) != 0) continue; @@ -227,7 +227,7 @@ main (int argc, char ** argv) continue; } - if (!g_metadata_validate (metadata, &error)) + if (!g_typelib_validate (metadata, &error)) g_error ("Invalid metadata for module '%s': %s", module->name, error->message); @@ -237,7 +237,7 @@ main (int argc, char ** argv) prefix = NULL; write_out_metadata (prefix, metadata); - g_metadata_free (metadata); + g_typelib_free (metadata); metadata = NULL; /* when writing to stdout, stop after the first module */ diff --git a/tools/generate.c b/tools/generate.c index 8c5c3b3b..3e057ef1 100644 --- a/tools/generate.c +++ b/tools/generate.c @@ -28,7 +28,7 @@ #include #include "girepository.h" -#include "gmetadata.h" +#include "gtypelib.h" /* FIXME: Avoid global */ static gchar *output = NULL; @@ -1103,14 +1103,14 @@ load_metadata (const gchar *filename, GModule *handle; handle = g_module_open (filename, G_MODULE_BIND_LOCAL|G_MODULE_BIND_LAZY); - if (!g_module_symbol (handle, "_G_METADATA", (gpointer *) &metadata)) + if (!g_module_symbol (handle, "_G_TYPELIB", (gpointer *) &metadata)) { g_printerr ("Could not load metadata from '%s': %s\n", filename, g_module_error ()); return NULL; } - if (!g_module_symbol (handle, "_G_METADATA_SIZE", (gpointer *) &metadata_size)) + if (!g_module_symbol (handle, "_G_TYPELIB_SIZE", (gpointer *) &metadata_size)) { g_printerr ("Could not load metadata from '%s': %s\n", filename, g_module_error ()); @@ -1134,7 +1134,7 @@ main (int argc, char *argv[]) GError *error = NULL; gboolean needs_prefix; gint i; - GMetadata *data; + GTypelib *data; GOptionEntry options[] = { { "raw", 0, 0, G_OPTION_ARG_NONE, &raw, "handle raw metadata", NULL }, @@ -1145,7 +1145,7 @@ main (int argc, char *argv[]) g_type_init (); - g_metadata_check_sanity (); + g_typelib_check_sanity (); context = g_option_context_new (""); g_option_context_add_main_entries (context, options, NULL); @@ -1190,10 +1190,10 @@ main (int argc, char *argv[]) else needs_prefix = FALSE; - data = g_metadata_new_from_const_memory (metadata, len); + data = g_typelib_new_from_const_memory (metadata, len); { GError *error = NULL; - if (!g_metadata_validate (data, &error)) { + if (!g_typelib_validate (data, &error)) { g_printerr ("metadata not valid: %s\n", error->message); g_clear_error (&error); } @@ -1201,7 +1201,7 @@ main (int argc, char *argv[]) g_irepository_register (g_irepository_get_default (), data); write_repository (g_irepository_get_default (), needs_prefix); g_irepository_unregister (g_irepository_get_default (), - g_metadata_get_namespace (data)); + g_typelib_get_namespace (data)); if (dlhandle) { diff --git a/tools/gidlmodule.c b/tools/gidlmodule.c index d17a249a..d543346b 100644 --- a/tools/gidlmodule.c +++ b/tools/gidlmodule.c @@ -60,7 +60,7 @@ g_idl_module_free (GIdlModule *module) g_free (module); } -GMetadata * +GTypelib * g_idl_module_build_metadata (GIdlModule *module, GList *modules) { @@ -210,6 +210,6 @@ g_idl_module_build_metadata (GIdlModule *module, metadata = g_realloc (data, offset2); length = header->size = offset2; - return g_metadata_new_from_memory (metadata, length); + return g_typelib_new_from_memory (metadata, length); } diff --git a/tools/gidlmodule.h b/tools/gidlmodule.h index 3564a75f..0814ed51 100644 --- a/tools/gidlmodule.h +++ b/tools/gidlmodule.h @@ -22,7 +22,7 @@ #define __G_IDL_MODULE_H__ #include -#include "gmetadata.h" +#include "gtypelib.h" G_BEGIN_DECLS @@ -40,7 +40,7 @@ GIdlModule *g_idl_module_new (const gchar *name, const gchar *module_filename); void g_idl_module_free (GIdlModule *module); -GMetadata * g_idl_module_build_metadata (GIdlModule *module, +GTypelib * g_idl_module_build_metadata (GIdlModule *module, GList *modules); G_END_DECLS diff --git a/tools/gidlnode.c b/tools/gidlnode.c index 0e240b2b..09f3f072 100644 --- a/tools/gidlnode.c +++ b/tools/gidlnode.c @@ -24,7 +24,7 @@ #include "gidlmodule.h" #include "gidlnode.h" -#include "gmetadata.h" +#include "gtypelib.h" static gulong string_count = 0; static gulong unique_string_count = 0; diff --git a/tools/gidlparser.c b/tools/gidlparser.c index 6a76b2ca..52b3d788 100644 --- a/tools/gidlparser.c +++ b/tools/gidlparser.c @@ -25,7 +25,7 @@ #include #include "gidlmodule.h" #include "gidlnode.h" -#include "gmetadata.h" +#include "gtypelib.h" typedef enum { -- cgit v1.2.1