(root)/
glib-2.79.0/
girepository/
gitypelib.c
       1  /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
       2   * GObject introspection: typelib validation, auxiliary functions
       3   * related to the binary typelib format
       4   *
       5   * Copyright (C) 2005 Matthias Clasen
       6   *
       7   * SPDX-License-Identifier: LGPL-2.1-or-later
       8   *
       9   * This library is free software; you can redistribute it and/or
      10   * modify it under the terms of the GNU Lesser General Public
      11   * License as published by the Free Software Foundation; either
      12   * version 2 of the License, or (at your option) any later version.
      13   *
      14   * This library is distributed in the hope that it will be useful,
      15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17   * Lesser General Public License for more details.
      18   *
      19   * You should have received a copy of the GNU Lesser General Public
      20   * License along with this library; if not, write to the
      21   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      22   * Boston, MA 02111-1307, USA.
      23   */
      24  
      25  #include "config.h"
      26  
      27  #include <stdlib.h>
      28  #include <string.h>
      29  
      30  #include <glib.h>
      31  
      32  #include "gitypelib-internal.h"
      33  #include "gitypelib.h"
      34  
      35  /**
      36   * GITypelib:
      37   *
      38   * `GITypelib` represents a loaded `.typelib` file, which contains a description
      39   * of a single module’s API.
      40   *
      41   * Since: 2.80
      42   */
      43  
      44  typedef struct {
      45    GITypelib *typelib;
      46    GSList *context_stack;
      47  } ValidateContext;
      48  
      49  #define ALIGN_VALUE(this, boundary) \
      50    (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
      51  
      52  static void
      53  push_context (ValidateContext *ctx, const char *name)
      54  {
      55    ctx->context_stack = g_slist_prepend (ctx->context_stack, (char*)name);
      56  }
      57  
      58  static void
      59  pop_context (ValidateContext *ctx)
      60  {
      61    g_assert (ctx->context_stack != NULL);
      62    ctx->context_stack = g_slist_delete_link (ctx->context_stack,
      63  					    ctx->context_stack);
      64  }
      65  
      66  static gboolean
      67  validate_interface_blob (ValidateContext *ctx,
      68  			 guint32        offset,
      69  			 GError       **error);
      70  
      71  static DirEntry *
      72  get_dir_entry_checked (GITypelib *typelib,
      73  		       guint16    index,
      74  		       GError   **error)
      75  {
      76    Header *header = (Header *)typelib->data;
      77    guint32 offset;
      78  
      79    if (index == 0 || index > header->n_entries)
      80      {
      81        g_set_error (error,
      82  		   GI_TYPELIB_ERROR,
      83  		   GI_TYPELIB_ERROR_INVALID_BLOB,
      84  		   "Invalid directory index %d", index);
      85        return FALSE;
      86      }
      87  
      88    offset = header->directory + (index - 1) * header->entry_blob_size;
      89  
      90    if (typelib->len < offset + sizeof (DirEntry))
      91      {
      92        g_set_error (error,
      93  		   GI_TYPELIB_ERROR,
      94  		   GI_TYPELIB_ERROR_INVALID,
      95  		   "The buffer is too short");
      96        return FALSE;
      97      }
      98  
      99    return (DirEntry *)&typelib->data[offset];
     100  }
     101  
     102  
     103  static CommonBlob *
     104  get_blob (GITypelib *typelib,
     105  	  guint32   offset,
     106  	  GError  **error)
     107  {
     108    if (typelib->len < offset + sizeof (CommonBlob))
     109      {
     110        g_set_error (error,
     111  		   GI_TYPELIB_ERROR,
     112  		   GI_TYPELIB_ERROR_INVALID,
     113  		   "The buffer is too short");
     114        return FALSE;
     115      }
     116    return (CommonBlob *)&typelib->data[offset];
     117  }
     118  
     119  static InterfaceTypeBlob *
     120  get_type_blob (GITypelib *typelib,
     121  	       SimpleTypeBlob *simple,
     122  	       GError  **error)
     123  {
     124    if (simple->offset == 0)
     125      {
     126        g_set_error (error,
     127  		   GI_TYPELIB_ERROR,
     128  		   GI_TYPELIB_ERROR_INVALID,
     129  		   "Expected blob for type");
     130        return FALSE;
     131      }
     132  
     133    if (simple->flags.reserved == 0 && simple->flags.reserved2 == 0)
     134      {
     135        g_set_error (error,
     136  		   GI_TYPELIB_ERROR,
     137  		   GI_TYPELIB_ERROR_INVALID,
     138  		   "Expected non-basic type but got %d",
     139  		   simple->flags.tag);
     140        return FALSE;
     141      }
     142  
     143    return (InterfaceTypeBlob*) get_blob (typelib, simple->offset, error);
     144  }
     145  
     146  /**
     147   * gi_typelib_get_dir_entry:
     148   * @typelib: a #GITypelib
     149   * @index: index to retrieve
     150   *
     151   * Get the typelib directory entry at the given @index.
     152   *
     153   * Returns: (transfer none): a `DirEntry`
     154   * Since: 2.80
     155   */
     156  DirEntry *
     157  gi_typelib_get_dir_entry (GITypelib *typelib,
     158                            guint16    index)
     159  {
     160    Header *header = (Header *)typelib->data;
     161  
     162    return (DirEntry *)&typelib->data[header->directory + (index - 1) * header->entry_blob_size];
     163  }
     164  
     165  static Section *
     166  get_section_by_id (GITypelib   *typelib,
     167  		   SectionType  section_type)
     168  {
     169    Header *header = (Header *)typelib->data;
     170    Section *section;
     171  
     172    if (header->sections == 0)
     173      return NULL;
     174  
     175    for (section = (Section*)&typelib->data[header->sections];
     176         section->id != GI_SECTION_END;
     177         section++)
     178      {
     179        if (section->id == section_type)
     180  	return section;
     181      }
     182    return NULL;
     183  }
     184  
     185  /**
     186   * gi_typelib_get_dir_entry_by_name:
     187   * @typelib: a #GITypelib
     188   * @name: name to look up
     189   *
     190   * Get the typelib directory entry which has @name.
     191   *
     192   * Returns: (transfer none) (nullable): entry corresponding to @name, or `NULL`
     193   *   if none was found
     194   * Since: 2.80
     195   */
     196  DirEntry *
     197  gi_typelib_get_dir_entry_by_name (GITypelib  *typelib,
     198                                    const char *name)
     199  {
     200    Section *dirindex;
     201    gint i, n_entries;
     202    const char *entry_name;
     203    DirEntry *entry;
     204  
     205    dirindex = get_section_by_id (typelib, GI_SECTION_DIRECTORY_INDEX);
     206    n_entries = ((Header *)typelib->data)->n_local_entries;
     207  
     208    if (dirindex == NULL)
     209      {
     210        for (i = 1; i <= n_entries; i++)
     211  	{
     212  	  entry = gi_typelib_get_dir_entry (typelib, i);
     213  	  entry_name = gi_typelib_get_string (typelib, entry->name);
     214  	  if (strcmp (name, entry_name) == 0)
     215  	    return entry;
     216  	}
     217        return NULL;
     218      }
     219    else
     220      {
     221        guint8 *hash = (guint8*) &typelib->data[dirindex->offset];
     222        guint16 index;
     223  
     224        index = gi_typelib_hash_search (hash, name, n_entries);
     225        entry = gi_typelib_get_dir_entry (typelib, index + 1);
     226        entry_name = gi_typelib_get_string (typelib, entry->name);
     227        if (strcmp (name, entry_name) == 0)
     228  	return entry;
     229        return NULL;
     230      }
     231  }
     232  
     233  /**
     234   * gi_typelib_get_dir_entry_by_gtype_name:
     235   * @typelib: a #GITypelib
     236   * @gtype_name: name of a [type@GObject.Type] to look up
     237   *
     238   * Get the typelib directory entry for the [type@GObject.Type] with the given
     239   * @gtype_name.
     240   *
     241   * Returns: (transfer none) (nullable): entry corresponding to @gtype_name, or
     242   *   `NULL` if none was found
     243   * Since: 2.80
     244   */
     245  DirEntry *
     246  gi_typelib_get_dir_entry_by_gtype_name (GITypelib   *typelib,
     247                                          const gchar *gtype_name)
     248  {
     249    Header *header = (Header *)typelib->data;
     250    guint i;
     251  
     252    for (i = 1; i <= header->n_local_entries; i++)
     253      {
     254        RegisteredTypeBlob *blob;
     255        const char *type;
     256        DirEntry *entry = gi_typelib_get_dir_entry (typelib, i);
     257        if (!BLOB_IS_REGISTERED_TYPE (entry))
     258  	continue;
     259  
     260        blob = (RegisteredTypeBlob *)(&typelib->data[entry->offset]);
     261        if (!blob->gtype_name)
     262  	continue;
     263  
     264        type = gi_typelib_get_string (typelib, blob->gtype_name);
     265        if (strcmp (type, gtype_name) == 0)
     266  	return entry;
     267      }
     268    return NULL;
     269  }
     270  
     271  typedef struct {
     272    const char *s;
     273    const char *separator;
     274    gsize sep_len;
     275    GString buf;
     276  } StrSplitIter;
     277  
     278  static void
     279  strsplit_iter_init (StrSplitIter  *iter,
     280                      const char    *s,
     281                      const char    *separator)
     282  {
     283    iter->s = s;
     284    iter->separator = separator;
     285    iter->sep_len = strlen (separator);
     286    iter->buf.str = NULL;
     287    iter->buf.len = 0;
     288    iter->buf.allocated_len = 0;
     289  }
     290  
     291  static gboolean
     292  strsplit_iter_next (StrSplitIter  *iter,
     293                      const char   **out_val)
     294  {
     295    const char *s = iter->s;
     296    const char *next;
     297    gsize len;
     298  
     299    if (!s)
     300      return FALSE;
     301    next = strstr (s, iter->separator);
     302    if (next)
     303      {
     304        iter->s = next + iter->sep_len;
     305        len = next - s;
     306      }
     307    else
     308      {
     309        iter->s = NULL;
     310        len = strlen (s);
     311      }
     312    if (len == 0)
     313      {
     314        *out_val = "";
     315      }
     316    else
     317      {
     318        g_string_overwrite_len (&iter->buf, 0, s, (gssize)len);
     319        *out_val = iter->buf.str;
     320      }
     321    return TRUE;
     322  }
     323  
     324  static void
     325  strsplit_iter_clear (StrSplitIter  *iter)
     326  {
     327    g_free (iter->buf.str);
     328  }
     329  
     330  /**
     331   * gi_typelib_matches_gtype_name_prefix:
     332   * @typelib: a #GITypelib
     333   * @gtype_name: name of a [type@GObject.Type]
     334   *
     335   * Check whether the symbol prefix for @typelib is a prefix of the given
     336   * @gtype_name.
     337   *
     338   * Returns: `TRUE` if the prefix for @typelib prefixes @gtype_name
     339   * Since: 2.80
     340   */
     341  gboolean
     342  gi_typelib_matches_gtype_name_prefix (GITypelib   *typelib,
     343                                        const gchar *gtype_name)
     344  {
     345    Header *header = (Header *)typelib->data;
     346    const char *c_prefix;
     347    const gchar *prefix;
     348    gboolean ret = FALSE;
     349    StrSplitIter split_iter;
     350    gsize gtype_name_len;
     351  
     352    c_prefix = gi_typelib_get_string (typelib, header->c_prefix);
     353    if (c_prefix == NULL || strlen (c_prefix) == 0)
     354      return FALSE;
     355  
     356    gtype_name_len = strlen (gtype_name);
     357  
     358    /* c_prefix is a comma separated string of supported prefixes
     359     * in the typelib.
     360     * We match the specified gtype_name if the gtype_name starts
     361     * with the prefix, and is followed by a capital letter.
     362     * For example, a typelib offering the 'Gdk' prefix does match
     363     * GdkX11Cursor, however a typelib offering the 'G' prefix does not.
     364     */
     365    strsplit_iter_init (&split_iter, c_prefix, ",");
     366    while (strsplit_iter_next (&split_iter, &prefix))
     367      {
     368        size_t len = strlen (prefix);
     369  
     370        if (gtype_name_len < len)
     371          continue;
     372  
     373        if (strncmp (prefix, gtype_name, len) != 0)
     374          continue;
     375  
     376        if (g_ascii_isupper (gtype_name[len]))
     377          {
     378            ret = TRUE;
     379            break;
     380          }
     381      }
     382    strsplit_iter_clear (&split_iter);
     383    return ret;
     384  }
     385  
     386  /**
     387   * gi_typelib_get_dir_entry_by_error_domain:
     388   * @typelib: a #GITypelib
     389   * @error_domain: name of a [type@GLib.Error] domain to look up
     390   *
     391   * Get the typelib directory entry for the [type@GLib.Error] domain with the
     392   * given @error_domain name.
     393   *
     394   * Returns: (transfer none) (nullable): entry corresponding to @error_domain, or
     395   *   `NULL` if none was found
     396   * Since: 2.80
     397   */
     398  DirEntry *
     399  gi_typelib_get_dir_entry_by_error_domain (GITypelib *typelib,
     400                                            GQuark     error_domain)
     401  {
     402    Header *header = (Header *)typelib->data;
     403    guint n_entries = header->n_local_entries;
     404    const char *domain_string = g_quark_to_string (error_domain);
     405    DirEntry *entry;
     406    guint i;
     407  
     408    for (i = 1; i <= n_entries; i++)
     409      {
     410        EnumBlob *blob;
     411        const char *enum_domain_string;
     412  
     413        entry = gi_typelib_get_dir_entry (typelib, i);
     414        if (entry->blob_type != BLOB_TYPE_ENUM)
     415  	continue;
     416  
     417        blob = (EnumBlob *)(&typelib->data[entry->offset]);
     418        if (!blob->error_domain)
     419  	continue;
     420  
     421        enum_domain_string = gi_typelib_get_string (typelib, blob->error_domain);
     422        if (strcmp (domain_string, enum_domain_string) == 0)
     423  	return entry;
     424      }
     425    return NULL;
     426  }
     427  
     428  /**
     429   * gi_typelib_check_sanity:
     430   *
     431   * Check compile-time sizes of various typelib file format types are as
     432   * expected.
     433   *
     434   * Since: 2.80
     435   */
     436  void
     437  gi_typelib_check_sanity (void)
     438  {
     439  #ifndef G_DISABLE_ASSERT
     440    /* Check that struct layout is as we expect */
     441  
     442    gboolean size_check_ok = TRUE;
     443  
     444  #define CHECK_SIZE(s,n) \
     445    if (sizeof(s) != n) \
     446      { \
     447        g_printerr ("sizeof("#s") is expected to be %d but is %"G_GSIZE_FORMAT".\n", \
     448  		  n, sizeof (s));					\
     449        size_check_ok = FALSE; \
     450      }
     451  
     452    /* When changing the size of a typelib structure, you are required to update
     453     * the hardcoded size here.  Do NOT change these to use sizeof(); these
     454     * should match whatever is defined in the text specification and serve as
     455     * a sanity check on structure modifications.
     456     *
     457     * Everything else in the code however should be using sizeof().
     458     */
     459  
     460    CHECK_SIZE (Header, 112);
     461    CHECK_SIZE (DirEntry, 12);
     462    CHECK_SIZE (SimpleTypeBlob, 4);
     463    CHECK_SIZE (ArgBlob, 16);
     464    CHECK_SIZE (SignatureBlob, 8);
     465    CHECK_SIZE (CommonBlob, 8);
     466    CHECK_SIZE (FunctionBlob, 20);
     467    CHECK_SIZE (CallbackBlob, 12);
     468    CHECK_SIZE (InterfaceTypeBlob, 4);
     469    CHECK_SIZE (ArrayTypeBlob, 8);
     470    CHECK_SIZE (ParamTypeBlob, 4);
     471    CHECK_SIZE (ErrorTypeBlob, 4);
     472    CHECK_SIZE (ValueBlob, 12);
     473    CHECK_SIZE (FieldBlob, 16);
     474    CHECK_SIZE (RegisteredTypeBlob, 16);
     475    CHECK_SIZE (StructBlob, 32);
     476    CHECK_SIZE (EnumBlob, 24);
     477    CHECK_SIZE (PropertyBlob, 16);
     478    CHECK_SIZE (SignalBlob, 16);
     479    CHECK_SIZE (VFuncBlob, 20);
     480    CHECK_SIZE (ObjectBlob, 60);
     481    CHECK_SIZE (InterfaceBlob, 40);
     482    CHECK_SIZE (ConstantBlob, 24);
     483    CHECK_SIZE (AttributeBlob, 12);
     484    CHECK_SIZE (UnionBlob, 40);
     485  #undef CHECK_SIZE
     486  
     487    g_assert (size_check_ok);
     488  #endif  /* !G_DISABLE_ASSERT */
     489  }
     490  
     491  
     492  static gboolean
     493  is_aligned (guint32 offset)
     494  {
     495    return offset == ALIGN_VALUE (offset, 4);
     496  }
     497  
     498  #define MAX_NAME_LEN 2048
     499  
     500  static const char *
     501  get_string (GITypelib *typelib, guint32 offset, GError **error)
     502  {
     503    if (typelib->len < offset)
     504      {
     505        g_set_error (error,
     506  		   GI_TYPELIB_ERROR,
     507  		   GI_TYPELIB_ERROR_INVALID,
     508  		   "Buffer is too short while looking up name");
     509        return NULL;
     510      }
     511  
     512    return (const char*)&typelib->data[offset];
     513  }
     514  
     515  static const char *
     516  get_string_nofail (GITypelib *typelib, guint32 offset)
     517  {
     518    const char *ret = get_string (typelib, offset, NULL);
     519    g_assert (ret);
     520    return ret;
     521  }
     522  
     523  static gboolean
     524  validate_name (GITypelib   *typelib,
     525  	       const char *msg,
     526  	       const guchar *data, guint32 offset,
     527  	       GError **error)
     528  {
     529    const char *name;
     530  
     531    name = get_string (typelib, offset, error);
     532    if (!name)
     533      return FALSE;
     534  
     535    if (!memchr (name, '\0', MAX_NAME_LEN))
     536      {
     537        g_set_error (error,
     538  		   GI_TYPELIB_ERROR,
     539  		   GI_TYPELIB_ERROR_INVALID,
     540  		   "The %s is too long: %s",
     541  		   msg, name);
     542        return FALSE;
     543      }
     544  
     545    if (strspn (name, G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_") < strlen (name))
     546      {
     547        g_set_error (error,
     548  		   GI_TYPELIB_ERROR,
     549  		   GI_TYPELIB_ERROR_INVALID,
     550  		   "The %s contains invalid characters: '%s'",
     551  		   msg, name);
     552        return FALSE;
     553      }
     554  
     555    return TRUE;
     556  }
     557  
     558  /* Fast path sanity check, operates on a memory blob */
     559  static gboolean
     560  validate_header_basic (const guint8   *memory,
     561  		       gsize           len,
     562  		       GError        **error)
     563  {
     564    Header *header = (Header *)memory;
     565  
     566    if (len < sizeof (Header))
     567      {
     568        g_set_error (error,
     569  		   GI_TYPELIB_ERROR,
     570  		   GI_TYPELIB_ERROR_INVALID,
     571  		   "The specified typelib length %" G_GSIZE_FORMAT " is too short",
     572  		   len);
     573        return FALSE;
     574      }
     575  
     576    if (strncmp (header->magic, GI_IR_MAGIC, 16) != 0)
     577      {
     578        g_set_error (error,
     579  		   GI_TYPELIB_ERROR,
     580  		   GI_TYPELIB_ERROR_INVALID_HEADER,
     581  		   "Invalid magic header");
     582        return FALSE;
     583  
     584      }
     585  
     586    if (header->major_version != 4)
     587      {
     588        g_set_error (error,
     589  		   GI_TYPELIB_ERROR,
     590  		   GI_TYPELIB_ERROR_INVALID_HEADER,
     591  		   "Typelib version mismatch; expected 4, found %d",
     592  		   header->major_version);
     593        return FALSE;
     594  
     595      }
     596  
     597    if (header->n_entries < header->n_local_entries)
     598      {
     599        g_set_error (error,
     600  		   GI_TYPELIB_ERROR,
     601  		   GI_TYPELIB_ERROR_INVALID_HEADER,
     602  		   "Inconsistent entry counts");
     603        return FALSE;
     604      }
     605  
     606    if (header->size != len)
     607      {
     608        g_set_error (error,
     609  		   GI_TYPELIB_ERROR,
     610  		   GI_TYPELIB_ERROR_INVALID_HEADER,
     611  		   "Typelib size %" G_GSIZE_FORMAT " does not match %" G_GSIZE_FORMAT,
     612  		   (gsize) header->size, len);
     613        return FALSE;
     614      }
     615  
     616    /* This is a sanity check for a specific typelib; it
     617     * prevents us from loading an incompatible typelib.
     618     *
     619     * The hardcoded checks in gi_typelib_check_sanity to
     620     * protect against inadvertent or buggy changes to the typelib format
     621     * itself.
     622     */
     623  
     624    if (header->entry_blob_size != sizeof (DirEntry) ||
     625        header->function_blob_size != sizeof (FunctionBlob) ||
     626        header->callback_blob_size != sizeof (CallbackBlob) ||
     627        header->signal_blob_size != sizeof (SignalBlob) ||
     628        header->vfunc_blob_size != sizeof (VFuncBlob) ||
     629        header->arg_blob_size != sizeof (ArgBlob) ||
     630        header->property_blob_size != sizeof (PropertyBlob) ||
     631        header->field_blob_size != sizeof (FieldBlob) ||
     632        header->value_blob_size != sizeof (ValueBlob) ||
     633        header->constant_blob_size != sizeof (ConstantBlob) ||
     634        header->attribute_blob_size != sizeof (AttributeBlob) ||
     635        header->signature_blob_size != sizeof (SignatureBlob) ||
     636        header->enum_blob_size != sizeof (EnumBlob) ||
     637        header->struct_blob_size != sizeof (StructBlob) ||
     638        header->object_blob_size != sizeof(ObjectBlob) ||
     639        header->interface_blob_size != sizeof (InterfaceBlob) ||
     640        header->union_blob_size != sizeof (UnionBlob))
     641      {
     642        g_set_error (error,
     643  		   GI_TYPELIB_ERROR,
     644  		   GI_TYPELIB_ERROR_INVALID_HEADER,
     645  		   "Blob size mismatch");
     646        return FALSE;
     647      }
     648  
     649    if (!is_aligned (header->directory))
     650      {
     651        g_set_error (error,
     652  		   GI_TYPELIB_ERROR,
     653  		   GI_TYPELIB_ERROR_INVALID_HEADER,
     654  		   "Misaligned directory");
     655        return FALSE;
     656      }
     657  
     658    if (!is_aligned (header->attributes))
     659      {
     660        g_set_error (error,
     661  		   GI_TYPELIB_ERROR,
     662  		   GI_TYPELIB_ERROR_INVALID_HEADER,
     663  		   "Misaligned attributes");
     664        return FALSE;
     665      }
     666  
     667    if (header->attributes == 0 && header->n_attributes > 0)
     668      {
     669        g_set_error (error,
     670  		   GI_TYPELIB_ERROR,
     671  		   GI_TYPELIB_ERROR_INVALID_HEADER,
     672  		   "Wrong number of attributes");
     673        return FALSE;
     674      }
     675  
     676    return TRUE;
     677  }
     678  
     679  static gboolean
     680  validate_header (ValidateContext  *ctx,
     681  		 GError          **error)
     682  {
     683    GITypelib *typelib = ctx->typelib;
     684    
     685    if (!validate_header_basic (typelib->data, typelib->len, error))
     686      return FALSE;
     687  
     688    {
     689      Header *header = (Header*)typelib->data;
     690      if (!validate_name (typelib, "namespace", typelib->data, header->namespace, error))
     691        return FALSE;
     692    }
     693  
     694    return TRUE;
     695  }
     696  
     697  static gboolean validate_type_blob (GITypelib     *typelib,
     698  				    guint32        offset,
     699  				    guint32        signature_offset,
     700  				    gboolean       return_type,
     701  				    GError       **error);
     702  
     703  static gboolean
     704  validate_array_type_blob (GITypelib     *typelib,
     705  			  guint32        offset,
     706  			  guint32        signature_offset,
     707  			  gboolean       return_type,
     708  			  GError       **error)
     709  {
     710    /* FIXME validate length */
     711  
     712    if (!validate_type_blob (typelib,
     713  			   offset + G_STRUCT_OFFSET (ArrayTypeBlob, type),
     714  			   0, FALSE, error))
     715      return FALSE;
     716  
     717    return TRUE;
     718  }
     719  
     720  static gboolean
     721  validate_iface_type_blob (GITypelib     *typelib,
     722  			  guint32        offset,
     723  			  guint32        signature_offset,
     724  			  gboolean       return_type,
     725  			  GError       **error)
     726  {
     727    InterfaceTypeBlob *blob;
     728    InterfaceBlob *target;
     729  
     730    blob = (InterfaceTypeBlob*)&typelib->data[offset];
     731  
     732    target = (InterfaceBlob*) get_dir_entry_checked (typelib, blob->interface, error);
     733  
     734    if (!target)
     735      return FALSE;
     736    if (target->blob_type == 0) /* non-local */
     737      return TRUE;
     738  
     739    return TRUE;
     740  }
     741  
     742  static gboolean
     743  validate_param_type_blob (GITypelib     *typelib,
     744  			  guint32        offset,
     745  			  guint32        signature_offset,
     746  			  gboolean       return_type,
     747  			  gint           n_params,
     748  			  GError       **error)
     749  {
     750    ParamTypeBlob *blob;
     751    gint i;
     752  
     753    blob = (ParamTypeBlob*)&typelib->data[offset];
     754  
     755    if (!blob->pointer)
     756      {
     757        g_set_error (error,
     758  		   GI_TYPELIB_ERROR,
     759  		   GI_TYPELIB_ERROR_INVALID_BLOB,
     760  		   "Pointer type exected for tag %d", blob->tag);
     761        return FALSE;
     762      }
     763  
     764    if (blob->n_types != n_params)
     765      {
     766        g_set_error (error,
     767  		   GI_TYPELIB_ERROR,
     768  		   GI_TYPELIB_ERROR_INVALID_BLOB,
     769  		   "Parameter type number mismatch");
     770        return FALSE;
     771      }
     772  
     773    for (i = 0; i < n_params; i++)
     774      {
     775        if (!validate_type_blob (typelib,
     776  			       offset + sizeof (ParamTypeBlob) +
     777  			       i * sizeof (SimpleTypeBlob),
     778  			       0, FALSE, error))
     779  	return FALSE;
     780      }
     781  
     782    return TRUE;
     783  }
     784  
     785  static gboolean
     786  validate_error_type_blob (GITypelib     *typelib,
     787  			  guint32        offset,
     788  			  guint32        signature_offset,
     789  			  gboolean       return_type,
     790  			  GError       **error)
     791  {
     792    ErrorTypeBlob *blob;
     793  
     794    blob = (ErrorTypeBlob*)&typelib->data[offset];
     795  
     796    if (!blob->pointer)
     797      {
     798        g_set_error (error,
     799  		   GI_TYPELIB_ERROR,
     800  		   GI_TYPELIB_ERROR_INVALID_BLOB,
     801  		   "Pointer type exected for tag %d", blob->tag);
     802        return FALSE;
     803      }
     804  
     805    return TRUE;
     806  }
     807  
     808  static gboolean
     809  validate_type_blob (GITypelib     *typelib,
     810  		    guint32        offset,
     811  		    guint32        signature_offset,
     812  		    gboolean       return_type,
     813  		    GError       **error)
     814  {
     815    SimpleTypeBlob *simple;
     816    InterfaceTypeBlob *iface;
     817  
     818    simple = (SimpleTypeBlob *)&typelib->data[offset];
     819  
     820    if (simple->flags.reserved == 0 &&
     821        simple->flags.reserved2 == 0)
     822      {
     823        if (!GI_TYPE_TAG_IS_BASIC(simple->flags.tag))
     824  	{
     825  	  g_set_error (error,
     826  		       GI_TYPELIB_ERROR,
     827  		       GI_TYPELIB_ERROR_INVALID_BLOB,
     828  		       "Invalid non-basic tag %d in simple type", simple->flags.tag);
     829  	  return FALSE;
     830  	}
     831  
     832        if (simple->flags.tag >= GI_TYPE_TAG_UTF8 &&
     833  	  simple->flags.tag != GI_TYPE_TAG_UNICHAR &&
     834  	  !simple->flags.pointer)
     835  	{
     836  	  g_set_error (error,
     837  		       GI_TYPELIB_ERROR,
     838  		       GI_TYPELIB_ERROR_INVALID_BLOB,
     839  		       "Pointer type exected for tag %d", simple->flags.tag);
     840  	  return FALSE;
     841  	}
     842  
     843        return TRUE;
     844      }
     845  
     846    iface = (InterfaceTypeBlob*)&typelib->data[simple->offset];
     847  
     848    switch (iface->tag)
     849      {
     850      case GI_TYPE_TAG_ARRAY:
     851        if (!validate_array_type_blob (typelib, simple->offset,
     852  				     signature_offset, return_type, error))
     853  	return FALSE;
     854        break;
     855      case GI_TYPE_TAG_INTERFACE:
     856        if (!validate_iface_type_blob (typelib, simple->offset,
     857  				     signature_offset, return_type, error))
     858  	return FALSE;
     859        break;
     860      case GI_TYPE_TAG_GLIST:
     861      case GI_TYPE_TAG_GSLIST:
     862        if (!validate_param_type_blob (typelib, simple->offset,
     863  				     signature_offset, return_type, 1, error))
     864  	return FALSE;
     865        break;
     866      case GI_TYPE_TAG_GHASH:
     867        if (!validate_param_type_blob (typelib, simple->offset,
     868  				     signature_offset, return_type, 2, error))
     869  	return FALSE;
     870        break;
     871      case GI_TYPE_TAG_ERROR:
     872        if (!validate_error_type_blob (typelib, simple->offset,
     873  				     signature_offset, return_type, error))
     874  	return FALSE;
     875        break;
     876      default:
     877        g_set_error (error,
     878  		   GI_TYPELIB_ERROR,
     879  		   GI_TYPELIB_ERROR_INVALID_BLOB,
     880  		   "Wrong tag in complex type");
     881        return FALSE;
     882      }
     883  
     884    return TRUE;
     885  }
     886  
     887  static gboolean
     888  validate_arg_blob (GITypelib     *typelib,
     889  		   guint32        offset,
     890  		   guint32        signature_offset,
     891  		   GError       **error)
     892  {
     893    ArgBlob *blob;
     894  
     895    if (typelib->len < offset + sizeof (ArgBlob))
     896      {
     897        g_set_error (error,
     898  		   GI_TYPELIB_ERROR,
     899  		   GI_TYPELIB_ERROR_INVALID,
     900  		   "The buffer is too short");
     901        return FALSE;
     902      }
     903  
     904    blob = (ArgBlob*) &typelib->data[offset];
     905  
     906    if (!validate_name (typelib, "argument", typelib->data, blob->name, error))
     907      return FALSE;
     908  
     909    if (!validate_type_blob (typelib,
     910  			   offset + G_STRUCT_OFFSET (ArgBlob, arg_type),
     911  			   signature_offset, FALSE, error))
     912      return FALSE;
     913  
     914    return TRUE;
     915  }
     916  
     917  static SimpleTypeBlob *
     918  return_type_from_signature (GITypelib *typelib,
     919  			    guint32   offset,
     920  			    GError  **error)
     921  {
     922    SignatureBlob *blob;
     923    if (typelib->len < offset + sizeof (SignatureBlob))
     924      {
     925        g_set_error (error,
     926  		   GI_TYPELIB_ERROR,
     927  		   GI_TYPELIB_ERROR_INVALID,
     928  		   "The buffer is too short");
     929        return NULL;
     930      }
     931  
     932    blob = (SignatureBlob*) &typelib->data[offset];
     933    if (blob->return_type.offset == 0)
     934      {
     935        g_set_error (error,
     936  		   GI_TYPELIB_ERROR,
     937  		   GI_TYPELIB_ERROR_INVALID,
     938  		   "No return type found in signature");
     939        return NULL;
     940      }
     941  
     942    return (SimpleTypeBlob *)&typelib->data[offset + G_STRUCT_OFFSET (SignatureBlob, return_type)];
     943  }
     944  
     945  static gboolean
     946  validate_signature_blob (GITypelib     *typelib,
     947  			 guint32        offset,
     948  			 GError       **error)
     949  {
     950    SignatureBlob *blob;
     951    gint i;
     952  
     953    if (typelib->len < offset + sizeof (SignatureBlob))
     954      {
     955        g_set_error (error,
     956  		   GI_TYPELIB_ERROR,
     957  		   GI_TYPELIB_ERROR_INVALID,
     958  		   "The buffer is too short");
     959        return FALSE;
     960      }
     961  
     962    blob = (SignatureBlob*) &typelib->data[offset];
     963  
     964    if (blob->return_type.offset != 0)
     965      {
     966        if (!validate_type_blob (typelib,
     967  			       offset + G_STRUCT_OFFSET (SignatureBlob, return_type),
     968  			       offset, TRUE, error))
     969  	return FALSE;
     970      }
     971  
     972    for (i = 0; i < blob->n_arguments; i++)
     973      {
     974        if (!validate_arg_blob (typelib,
     975  			      offset + sizeof (SignatureBlob) +
     976  			      i * sizeof (ArgBlob),
     977  			      offset,
     978  			      error))
     979  	return FALSE;
     980      }
     981  
     982    /* FIXME check constraints on return_value */
     983    /* FIXME check array-length pairs */
     984    return TRUE;
     985  }
     986  
     987  static gboolean
     988  validate_function_blob (ValidateContext *ctx,
     989  			guint32        offset,
     990  			guint16        container_type,
     991  			GError       **error)
     992  {
     993    GITypelib *typelib = ctx->typelib;
     994    FunctionBlob *blob;
     995  
     996    if (typelib->len < offset + sizeof (FunctionBlob))
     997      {
     998        g_set_error (error,
     999  		   GI_TYPELIB_ERROR,
    1000  		   GI_TYPELIB_ERROR_INVALID,
    1001  		   "The buffer is too short");
    1002        return FALSE;
    1003      }
    1004  
    1005    blob = (FunctionBlob*) &typelib->data[offset];
    1006  
    1007    if (blob->blob_type != BLOB_TYPE_FUNCTION)
    1008      {
    1009        g_set_error (error,
    1010  		   GI_TYPELIB_ERROR,
    1011  		   GI_TYPELIB_ERROR_INVALID_BLOB,
    1012  		   "Wrong blob type %d, expected function", blob->blob_type);
    1013        return FALSE;
    1014      }
    1015  
    1016    if (!validate_name (typelib, "function", typelib->data, blob->name, error))
    1017      return FALSE;
    1018  
    1019    push_context (ctx, get_string_nofail (typelib, blob->name));
    1020  
    1021    if (!validate_name (typelib, "function symbol", typelib->data, blob->symbol, error))
    1022      return FALSE;
    1023  
    1024    if (blob->constructor)
    1025      {
    1026        switch (container_type)
    1027  	{
    1028  	case BLOB_TYPE_BOXED:
    1029  	case BLOB_TYPE_STRUCT:
    1030  	case BLOB_TYPE_UNION:
    1031  	case BLOB_TYPE_OBJECT:
    1032  	case BLOB_TYPE_INTERFACE:
    1033  	  break;
    1034  	default:
    1035  	  g_set_error (error,
    1036  		       GI_TYPELIB_ERROR,
    1037  		       GI_TYPELIB_ERROR_INVALID_BLOB,
    1038  		       "Constructor not allowed");
    1039  	  return FALSE;
    1040  	}
    1041      }
    1042  
    1043    if (blob->setter || blob->getter || blob->wraps_vfunc)
    1044      {
    1045        switch (container_type)
    1046  	{
    1047  	case BLOB_TYPE_OBJECT:
    1048  	case BLOB_TYPE_INTERFACE:
    1049  	  break;
    1050  	default:
    1051  	  g_set_error (error,
    1052  		       GI_TYPELIB_ERROR,
    1053  		       GI_TYPELIB_ERROR_INVALID_BLOB,
    1054  		       "Setter, getter or wrapper not allowed");
    1055  	  return FALSE;
    1056  	}
    1057      }
    1058  
    1059    if (blob->index)
    1060      {
    1061        if (!(blob->setter || blob->getter || blob->wraps_vfunc))
    1062  	{
    1063  	  g_set_error (error,
    1064  		       GI_TYPELIB_ERROR,
    1065  		       GI_TYPELIB_ERROR_INVALID_BLOB,
    1066  		       "Must be setter, getter or wrapper");
    1067  	  return FALSE;
    1068  	}
    1069      }
    1070  
    1071    /* FIXME: validate index range */
    1072  
    1073    if (!validate_signature_blob (typelib, blob->signature, error))
    1074      return FALSE;
    1075  
    1076    if (blob->constructor)
    1077      {
    1078        SimpleTypeBlob *simple = return_type_from_signature (typelib,
    1079  							   blob->signature,
    1080  							   error);
    1081        InterfaceTypeBlob *iface_type;
    1082  
    1083        if (!simple)
    1084  	return FALSE;
    1085        iface_type = get_type_blob (typelib, simple, error);
    1086        if (!iface_type)
    1087  	return FALSE;
    1088        if (iface_type->tag != GI_TYPE_TAG_INTERFACE &&
    1089            (container_type == BLOB_TYPE_OBJECT ||
    1090             container_type == BLOB_TYPE_INTERFACE))
    1091  	{
    1092  	  g_set_error (error,
    1093  		       GI_TYPELIB_ERROR,
    1094  		       GI_TYPELIB_ERROR_INVALID,
    1095  		       "Invalid return type '%s' for constructor '%s'",
    1096  		       gi_type_tag_to_string (iface_type->tag),
    1097  		       get_string_nofail (typelib, blob->symbol));
    1098  	  return FALSE;
    1099  	}
    1100      }
    1101  
    1102    pop_context (ctx);
    1103  
    1104    return TRUE;
    1105  }
    1106  
    1107  static gboolean
    1108  validate_callback_blob (ValidateContext *ctx,
    1109  			guint32        offset,
    1110  			GError       **error)
    1111  {
    1112    GITypelib *typelib = ctx->typelib;
    1113    CallbackBlob *blob;
    1114  
    1115    if (typelib->len < offset + sizeof (CallbackBlob))
    1116      {
    1117        g_set_error (error,
    1118  		   GI_TYPELIB_ERROR,
    1119  		   GI_TYPELIB_ERROR_INVALID,
    1120  		   "The buffer is too short");
    1121        return FALSE;
    1122      }
    1123  
    1124    blob = (CallbackBlob*) &typelib->data[offset];
    1125  
    1126    if (blob->blob_type != BLOB_TYPE_CALLBACK)
    1127      {
    1128        g_set_error (error,
    1129  		   GI_TYPELIB_ERROR,
    1130  		   GI_TYPELIB_ERROR_INVALID_BLOB,
    1131  		   "Wrong blob type");
    1132        return FALSE;
    1133      }
    1134  
    1135    if (!validate_name (typelib, "callback", typelib->data, blob->name, error))
    1136      return FALSE;
    1137  
    1138    push_context (ctx, get_string_nofail (typelib, blob->name));
    1139  
    1140    if (!validate_signature_blob (typelib, blob->signature, error))
    1141      return FALSE;
    1142  
    1143    pop_context (ctx);
    1144  
    1145    return TRUE;
    1146  }
    1147  
    1148  static gboolean
    1149  validate_constant_blob (GITypelib     *typelib,
    1150  			guint32        offset,
    1151  			GError       **error)
    1152  {
    1153    guint value_size[] = {
    1154      0, /* VOID */
    1155      4, /* BOOLEAN */
    1156      1, /* INT8 */
    1157      1, /* UINT8 */
    1158      2, /* INT16 */
    1159      2, /* UINT16 */
    1160      4, /* INT32 */
    1161      4, /* UINT32 */
    1162      8, /* INT64 */
    1163      8, /* UINT64 */
    1164      sizeof (gfloat),
    1165      sizeof (gdouble),
    1166      0, /* GTYPE */
    1167      0, /* UTF8 */
    1168      0, /* FILENAME */
    1169      0, /* ARRAY */
    1170      0, /* INTERFACE */
    1171      0, /* GLIST */
    1172      0, /* GSLIST */
    1173      0, /* GHASH */
    1174      0, /* ERROR */
    1175      4 /* UNICHAR */
    1176    };
    1177    ConstantBlob *blob;
    1178    SimpleTypeBlob *type;
    1179  
    1180    g_assert (G_N_ELEMENTS (value_size) == GI_TYPE_TAG_N_TYPES);
    1181  
    1182    if (typelib->len < offset + sizeof (ConstantBlob))
    1183      {
    1184        g_set_error (error,
    1185  		   GI_TYPELIB_ERROR,
    1186  		   GI_TYPELIB_ERROR_INVALID,
    1187  		   "The buffer is too short");
    1188        return FALSE;
    1189      }
    1190  
    1191    blob = (ConstantBlob*) &typelib->data[offset];
    1192  
    1193    if (blob->blob_type != BLOB_TYPE_CONSTANT)
    1194      {
    1195        g_set_error (error,
    1196  		   GI_TYPELIB_ERROR,
    1197  		   GI_TYPELIB_ERROR_INVALID_BLOB,
    1198  		   "Wrong blob type");
    1199        return FALSE;
    1200      }
    1201  
    1202    if (!validate_name (typelib, "constant", typelib->data, blob->name, error))
    1203      return FALSE;
    1204  
    1205    if (!validate_type_blob (typelib, offset + G_STRUCT_OFFSET (ConstantBlob, type),
    1206  			   0, FALSE, error))
    1207      return FALSE;
    1208  
    1209    if (!is_aligned (blob->offset))
    1210      {
    1211        g_set_error (error,
    1212  		   GI_TYPELIB_ERROR,
    1213  		   GI_TYPELIB_ERROR_INVALID_BLOB,
    1214  		   "Misaligned constant value");
    1215        return FALSE;
    1216      }
    1217  
    1218    type = (SimpleTypeBlob *)&typelib->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)];
    1219    if (type->flags.reserved == 0 && type->flags.reserved2 == 0)
    1220      {
    1221        if (type->flags.tag == 0)
    1222  	{
    1223  	  g_set_error (error,
    1224  		       GI_TYPELIB_ERROR,
    1225  		       GI_TYPELIB_ERROR_INVALID_BLOB,
    1226  		       "Constant value type void");
    1227  	  return FALSE;
    1228  	}
    1229  
    1230        if (value_size[type->flags.tag] != 0 &&
    1231  	  blob->size != value_size[type->flags.tag])
    1232  	{
    1233  	  g_set_error (error,
    1234  		       GI_TYPELIB_ERROR,
    1235  		       GI_TYPELIB_ERROR_INVALID_BLOB,
    1236  		       "Constant value size mismatch");
    1237  	  return FALSE;
    1238  	}
    1239        /* FIXME check string values */
    1240      }
    1241  
    1242    return TRUE;
    1243  }
    1244  
    1245  static gboolean
    1246  validate_value_blob (GITypelib     *typelib,
    1247  		     guint32        offset,
    1248  		     GError       **error)
    1249  {
    1250    ValueBlob *blob;
    1251  
    1252    if (typelib->len < offset + sizeof (ValueBlob))
    1253      {
    1254        g_set_error (error,
    1255  		   GI_TYPELIB_ERROR,
    1256  		   GI_TYPELIB_ERROR_INVALID,
    1257  		   "The buffer is too short");
    1258        return FALSE;
    1259      }
    1260  
    1261    blob = (ValueBlob*) &typelib->data[offset];
    1262  
    1263    if (!validate_name (typelib, "value", typelib->data, blob->name, error))
    1264      return FALSE;
    1265  
    1266    return TRUE;
    1267  }
    1268  
    1269  static gboolean
    1270  validate_field_blob (ValidateContext *ctx,
    1271  		     guint32        offset,
    1272  		     GError       **error)
    1273  {
    1274    GITypelib *typelib = ctx->typelib;
    1275    Header *header = (Header *)typelib->data;
    1276    FieldBlob *blob;
    1277  
    1278    if (typelib->len < offset + sizeof (FieldBlob))
    1279      {
    1280        g_set_error (error,
    1281  		   GI_TYPELIB_ERROR,
    1282  		   GI_TYPELIB_ERROR_INVALID,
    1283  		   "The buffer is too short");
    1284        return FALSE;
    1285      }
    1286  
    1287    blob = (FieldBlob*) &typelib->data[offset];
    1288  
    1289    if (!validate_name (typelib, "field", typelib->data, blob->name, error))
    1290      return FALSE;
    1291  
    1292    if (blob->has_embedded_type)
    1293      {
    1294        if (!validate_callback_blob (ctx, offset + header->field_blob_size, error))
    1295          return FALSE;
    1296      }
    1297    else if (!validate_type_blob (typelib,
    1298  			        offset + G_STRUCT_OFFSET (FieldBlob, type),
    1299  			        0, FALSE, error))
    1300      return FALSE;
    1301  
    1302    return TRUE;
    1303  }
    1304  
    1305  static gboolean
    1306  validate_property_blob (GITypelib     *typelib,
    1307  			guint32        offset,
    1308  			GError       **error)
    1309  {
    1310    PropertyBlob *blob;
    1311  
    1312    if (typelib->len < offset + sizeof (PropertyBlob))
    1313      {
    1314        g_set_error (error,
    1315  		   GI_TYPELIB_ERROR,
    1316  		   GI_TYPELIB_ERROR_INVALID,
    1317  		   "The buffer is too short");
    1318        return FALSE;
    1319      }
    1320  
    1321    blob = (PropertyBlob*) &typelib->data[offset];
    1322  
    1323    if (!validate_name (typelib, "property", typelib->data, blob->name, error))
    1324      return FALSE;
    1325  
    1326    if (!validate_type_blob (typelib,
    1327  			   offset + G_STRUCT_OFFSET (PropertyBlob, type),
    1328  			   0, FALSE, error))
    1329      return FALSE;
    1330  
    1331    return TRUE;
    1332  }
    1333  
    1334  static gboolean
    1335  validate_signal_blob (GITypelib     *typelib,
    1336  		      guint32        offset,
    1337  		      guint32        container_offset,
    1338  		      GError       **error)
    1339  {
    1340    SignalBlob *blob;
    1341    gint n_signals;
    1342  
    1343    if (typelib->len < offset + sizeof (SignalBlob))
    1344      {
    1345        g_set_error (error,
    1346  		   GI_TYPELIB_ERROR,
    1347  		   GI_TYPELIB_ERROR_INVALID,
    1348  		   "The buffer is too short");
    1349        return FALSE;
    1350      }
    1351  
    1352    blob = (SignalBlob*) &typelib->data[offset];
    1353  
    1354    if (!validate_name (typelib, "signal", typelib->data, blob->name, error))
    1355      return FALSE;
    1356  
    1357    if ((blob->run_first != 0) +
    1358        (blob->run_last != 0) +
    1359        (blob->run_cleanup != 0) != 1)
    1360      {
    1361        g_set_error (error,
    1362  		   GI_TYPELIB_ERROR,
    1363  		   GI_TYPELIB_ERROR_INVALID_BLOB,
    1364  		   "Invalid signal run flags");
    1365        return FALSE;
    1366      }
    1367  
    1368    if (blob->has_class_closure)
    1369      {
    1370        if (((CommonBlob*)&typelib->data[container_offset])->blob_type == BLOB_TYPE_OBJECT)
    1371  	{
    1372  	  ObjectBlob *object;
    1373  
    1374  	  object = (ObjectBlob*)&typelib->data[container_offset];
    1375  
    1376  	  n_signals = object->n_signals;
    1377  	}
    1378        else
    1379  	{
    1380  	  InterfaceBlob *iface;
    1381  
    1382  	  iface = (InterfaceBlob*)&typelib->data[container_offset];
    1383  
    1384  	  n_signals = iface->n_signals;
    1385  	}
    1386  
    1387        if (blob->class_closure >= n_signals)
    1388  	{
    1389  	  g_set_error (error,
    1390  		       GI_TYPELIB_ERROR,
    1391  		       GI_TYPELIB_ERROR_INVALID_BLOB,
    1392  		       "Invalid class closure index");
    1393  	  return FALSE;
    1394  	}
    1395      }
    1396  
    1397    if (!validate_signature_blob (typelib, blob->signature, error))
    1398      return FALSE;
    1399  
    1400    return TRUE;
    1401  }
    1402  
    1403  static gboolean
    1404  validate_vfunc_blob (GITypelib     *typelib,
    1405  		     guint32        offset,
    1406  		     guint32        container_offset,
    1407  		     GError       **error)
    1408  {
    1409    VFuncBlob *blob;
    1410    gint n_vfuncs;
    1411  
    1412    if (typelib->len < offset + sizeof (VFuncBlob))
    1413      {
    1414        g_set_error (error,
    1415  		   GI_TYPELIB_ERROR,
    1416  		   GI_TYPELIB_ERROR_INVALID,
    1417  		   "The buffer is too short");
    1418        return FALSE;
    1419      }
    1420  
    1421    blob = (VFuncBlob*) &typelib->data[offset];
    1422  
    1423    if (!validate_name (typelib, "vfunc", typelib->data, blob->name, error))
    1424      return FALSE;
    1425  
    1426    if (blob->class_closure)
    1427      {
    1428        if (((CommonBlob*)&typelib->data[container_offset])->blob_type == BLOB_TYPE_OBJECT)
    1429  	{
    1430  	  ObjectBlob *object;
    1431  
    1432  	  object = (ObjectBlob*)&typelib->data[container_offset];
    1433  
    1434  	  n_vfuncs = object->n_vfuncs;
    1435  	}
    1436        else
    1437  	{
    1438  	  InterfaceBlob *iface;
    1439  
    1440  	  iface = (InterfaceBlob*)&typelib->data[container_offset];
    1441  
    1442  	  n_vfuncs = iface->n_vfuncs;
    1443  	}
    1444  
    1445        if (blob->class_closure >= n_vfuncs)
    1446  	{
    1447  	  g_set_error (error,
    1448  		       GI_TYPELIB_ERROR,
    1449  		       GI_TYPELIB_ERROR_INVALID_BLOB,
    1450  		       "Invalid class closure index");
    1451  	  return FALSE;
    1452  	}
    1453      }
    1454  
    1455    if (!validate_signature_blob (typelib, blob->signature, error))
    1456      return FALSE;
    1457  
    1458    return TRUE;
    1459  }
    1460  
    1461  static gboolean
    1462  validate_struct_blob (ValidateContext *ctx,
    1463  		      guint32        offset,
    1464  		      guint16        blob_type,
    1465  		      GError       **error)
    1466  {
    1467    GITypelib *typelib = ctx->typelib;
    1468    StructBlob *blob;
    1469    gint i;
    1470    guint32 field_offset;
    1471  
    1472    if (typelib->len < offset + sizeof (StructBlob))
    1473      {
    1474        g_set_error (error,
    1475  		   GI_TYPELIB_ERROR,
    1476  		   GI_TYPELIB_ERROR_INVALID,
    1477  		   "The buffer is too short");
    1478        return FALSE;
    1479      }
    1480  
    1481    blob = (StructBlob*) &typelib->data[offset];
    1482  
    1483    if (blob->blob_type != blob_type)
    1484      {
    1485        g_set_error (error,
    1486  		   GI_TYPELIB_ERROR,
    1487  		   GI_TYPELIB_ERROR_INVALID_BLOB,
    1488  		   "Wrong blob type");
    1489        return FALSE;
    1490      }
    1491  
    1492    if (!validate_name (typelib, "struct", typelib->data, blob->name, error))
    1493      return FALSE;
    1494  
    1495    push_context (ctx, get_string_nofail (typelib, blob->name));
    1496  
    1497    if (!blob->unregistered)
    1498      {
    1499        if (!validate_name (typelib, "boxed", typelib->data, blob->gtype_name, error))
    1500  	return FALSE;
    1501  
    1502        if (!validate_name (typelib, "boxed", typelib->data, blob->gtype_init, error))
    1503  	return FALSE;
    1504      }
    1505    else
    1506      {
    1507        if (blob->gtype_name || blob->gtype_init)
    1508  	{
    1509  	  g_set_error (error,
    1510  		       GI_TYPELIB_ERROR,
    1511  		       GI_TYPELIB_ERROR_INVALID_BLOB,
    1512  		       "Gtype data in struct");
    1513  	  return FALSE;
    1514  	}
    1515      }
    1516  
    1517    if (typelib->len < offset + sizeof (StructBlob) +
    1518              blob->n_fields * sizeof (FieldBlob) +
    1519              blob->n_methods * sizeof (FunctionBlob))
    1520      {
    1521        g_set_error (error,
    1522  		   GI_TYPELIB_ERROR,
    1523  		   GI_TYPELIB_ERROR_INVALID,
    1524  		   "The buffer is too short");
    1525        return FALSE;
    1526      }
    1527  
    1528    field_offset = offset + sizeof (StructBlob);
    1529    for (i = 0; i < blob->n_fields; i++)
    1530      {
    1531        FieldBlob *field_blob = (FieldBlob*) &typelib->data[field_offset];
    1532  
    1533        if (!validate_field_blob (ctx,
    1534  				field_offset,
    1535  				error))
    1536  	return FALSE;
    1537  
    1538        field_offset += sizeof (FieldBlob);
    1539        if (field_blob->has_embedded_type)
    1540          field_offset += sizeof (CallbackBlob);
    1541      }
    1542  
    1543    for (i = 0; i < blob->n_methods; i++)
    1544      {
    1545        if (!validate_function_blob (ctx,
    1546  				   field_offset +
    1547  				   i * sizeof (FunctionBlob),
    1548  				   blob_type,
    1549  				   error))
    1550  	return FALSE;
    1551      }
    1552  
    1553    pop_context (ctx);
    1554  
    1555    return TRUE;
    1556  }
    1557  
    1558  static gboolean
    1559  validate_enum_blob (ValidateContext *ctx,
    1560  		    guint32        offset,
    1561  		    guint16        blob_type,
    1562  		    GError       **error)
    1563  {
    1564    GITypelib *typelib = ctx->typelib;
    1565    EnumBlob *blob;
    1566    gint i;
    1567    guint32 offset2;
    1568  
    1569    if (typelib->len < offset + sizeof (EnumBlob))
    1570      {
    1571        g_set_error (error,
    1572  		   GI_TYPELIB_ERROR,
    1573  		   GI_TYPELIB_ERROR_INVALID,
    1574  		   "The buffer is too short");
    1575        return FALSE;
    1576      }
    1577  
    1578    blob = (EnumBlob*) &typelib->data[offset];
    1579  
    1580    if (blob->blob_type != blob_type)
    1581      {
    1582        g_set_error (error,
    1583  		   GI_TYPELIB_ERROR,
    1584  		   GI_TYPELIB_ERROR_INVALID_BLOB,
    1585  		   "Wrong blob type");
    1586        return FALSE;
    1587      }
    1588  
    1589    if (!blob->unregistered)
    1590      {
    1591        if (!validate_name (typelib, "enum", typelib->data, blob->gtype_name, error))
    1592  	return FALSE;
    1593  
    1594        if (!validate_name (typelib, "enum", typelib->data, blob->gtype_init, error))
    1595  	return FALSE;
    1596      }
    1597    else
    1598      {
    1599        if (blob->gtype_name || blob->gtype_init)
    1600  	{
    1601  	  g_set_error (error,
    1602  		       GI_TYPELIB_ERROR,
    1603  		       GI_TYPELIB_ERROR_INVALID_BLOB,
    1604  		       "Gtype data in unregistered enum");
    1605  	  return FALSE;
    1606  	}
    1607      }
    1608  
    1609    if (!validate_name (typelib, "enum", typelib->data, blob->name, error))
    1610      return FALSE;
    1611  
    1612    if (typelib->len < offset + sizeof (EnumBlob) +
    1613        blob->n_values * sizeof (ValueBlob) +
    1614        blob->n_methods * sizeof (FunctionBlob))
    1615      {
    1616        g_set_error (error,
    1617  		   GI_TYPELIB_ERROR,
    1618  		   GI_TYPELIB_ERROR_INVALID,
    1619  		   "The buffer is too short");
    1620        return FALSE;
    1621      }
    1622  
    1623    offset2 = offset + sizeof (EnumBlob);
    1624  
    1625    push_context (ctx, get_string_nofail (typelib, blob->name));
    1626  
    1627    for (i = 0; i < blob->n_values; i++, offset2 += sizeof (ValueBlob))
    1628      {
    1629        if (!validate_value_blob (typelib,
    1630  				offset2,
    1631  				error))
    1632  	return FALSE;
    1633  
    1634  #if 0
    1635        v1 = (ValueBlob *)&typelib->data[offset2];
    1636        for (j = 0; j < i; j++)
    1637  	{
    1638  	  v2 = (ValueBlob *)&typelib->data[offset2 +
    1639                                              j * sizeof (ValueBlob)];
    1640  
    1641  	  if (v1->value == v2->value)
    1642  	    {
    1643  
    1644  	      /* FIXME should this be an error ? */
    1645  	      g_set_error (error,
    1646  			   GI_TYPELIB_ERROR,
    1647  			   GI_TYPELIB_ERROR_INVALID_BLOB,
    1648  			   "Duplicate enum value");
    1649  	      return FALSE;
    1650  	    }
    1651  	}
    1652  #endif
    1653      }
    1654  
    1655    for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob))
    1656      {
    1657        if (!validate_function_blob (ctx, offset2, BLOB_TYPE_ENUM, error))
    1658  	return FALSE;
    1659      }
    1660  
    1661    pop_context (ctx);
    1662  
    1663    return TRUE;
    1664  }
    1665  
    1666  static gboolean
    1667  validate_object_blob (ValidateContext *ctx,
    1668  		      guint32        offset,
    1669  		      GError       **error)
    1670  {
    1671    GITypelib *typelib = ctx->typelib;
    1672    Header *header;
    1673    ObjectBlob *blob;
    1674    gint i;
    1675    guint32 offset2;
    1676    guint16 n_field_callbacks;
    1677  
    1678    header = (Header *)typelib->data;
    1679  
    1680    if (typelib->len < offset + sizeof (ObjectBlob))
    1681      {
    1682        g_set_error (error,
    1683  		   GI_TYPELIB_ERROR,
    1684  		   GI_TYPELIB_ERROR_INVALID,
    1685  		   "The buffer is too short");
    1686        return FALSE;
    1687      }
    1688  
    1689    blob = (ObjectBlob*) &typelib->data[offset];
    1690  
    1691    if (blob->blob_type != BLOB_TYPE_OBJECT)
    1692      {
    1693        g_set_error (error,
    1694  		   GI_TYPELIB_ERROR,
    1695  		   GI_TYPELIB_ERROR_INVALID_BLOB,
    1696  		   "Wrong blob type");
    1697        return FALSE;
    1698      }
    1699  
    1700    if (!validate_name (typelib, "object", typelib->data, blob->gtype_name, error))
    1701      return FALSE;
    1702  
    1703    if (!validate_name (typelib, "object", typelib->data, blob->gtype_init, error))
    1704      return FALSE;
    1705  
    1706    if (!validate_name (typelib, "object", typelib->data, blob->name, error))
    1707      return FALSE;
    1708  
    1709    if (blob->parent > header->n_entries)
    1710      {
    1711        g_set_error (error,
    1712  		   GI_TYPELIB_ERROR,
    1713  		   GI_TYPELIB_ERROR_INVALID_BLOB,
    1714  		   "Invalid parent index");
    1715        return FALSE;
    1716      }
    1717  
    1718    if (blob->parent != 0)
    1719      {
    1720        DirEntry *entry;
    1721  
    1722        entry = get_dir_entry_checked (typelib, blob->parent, error);
    1723        if (!entry)
    1724          return FALSE;
    1725        if (entry->blob_type != BLOB_TYPE_OBJECT &&
    1726  	  (entry->local || entry->blob_type != 0))
    1727  	{
    1728  	  g_set_error (error,
    1729  		       GI_TYPELIB_ERROR,
    1730  		       GI_TYPELIB_ERROR_INVALID_BLOB,
    1731  		       "Parent not object");
    1732  	  return FALSE;
    1733  	}
    1734      }
    1735  
    1736    if (blob->gtype_struct != 0)
    1737      {
    1738        DirEntry *entry;
    1739  
    1740        entry = get_dir_entry_checked (typelib, blob->gtype_struct, error);
    1741        if (!entry)
    1742          return FALSE;
    1743        if (entry->blob_type != BLOB_TYPE_STRUCT && entry->local)
    1744          {
    1745            g_set_error (error,
    1746                         GI_TYPELIB_ERROR,
    1747                         GI_TYPELIB_ERROR_INVALID_BLOB,
    1748                         "Class struct invalid type or not local");
    1749            return FALSE;
    1750          }
    1751      }
    1752  
    1753    if (typelib->len < offset + sizeof (ObjectBlob) +
    1754              (blob->n_interfaces + blob->n_interfaces % 2) * 2 +
    1755              blob->n_fields * sizeof (FieldBlob) +
    1756              blob->n_properties * sizeof (PropertyBlob) +
    1757              blob->n_methods * sizeof (FunctionBlob) +
    1758              blob->n_signals * sizeof (SignalBlob) +
    1759              blob->n_vfuncs * sizeof (VFuncBlob) +
    1760              blob->n_constants * sizeof (ConstantBlob))
    1761  
    1762      {
    1763        g_set_error (error,
    1764  		   GI_TYPELIB_ERROR,
    1765  		   GI_TYPELIB_ERROR_INVALID,
    1766  		   "The buffer is too short");
    1767        return FALSE;
    1768      }
    1769  
    1770    offset2 = offset + sizeof (ObjectBlob);
    1771  
    1772    for (i = 0; i < blob->n_interfaces; i++, offset2 += 2)
    1773      {
    1774        guint16 iface;
    1775        DirEntry *entry;
    1776  
    1777        iface = *(guint16*)&typelib->data[offset2];
    1778        if (iface == 0 || iface > header->n_entries)
    1779  	{
    1780  	  g_set_error (error,
    1781  		       GI_TYPELIB_ERROR,
    1782  		       GI_TYPELIB_ERROR_INVALID_BLOB,
    1783  		       "Invalid interface index");
    1784  	  return FALSE;
    1785  	}
    1786  
    1787        entry = get_dir_entry_checked (typelib, iface, error);
    1788        if (!entry)
    1789          return FALSE;
    1790  
    1791        if (entry->blob_type != BLOB_TYPE_INTERFACE &&
    1792  	  (entry->local || entry->blob_type != 0))
    1793  	{
    1794  	  g_set_error (error,
    1795  		       GI_TYPELIB_ERROR,
    1796  		       GI_TYPELIB_ERROR_INVALID_BLOB,
    1797  		       "Not an interface");
    1798  	  return FALSE;
    1799  	}
    1800      }
    1801  
    1802    offset2 += 2 * (blob->n_interfaces %2);
    1803  
    1804    push_context (ctx, get_string_nofail (typelib, blob->name));
    1805  
    1806    n_field_callbacks = 0;
    1807    for (i = 0; i < blob->n_fields; i++)
    1808      {
    1809        FieldBlob *field_blob = (FieldBlob*) &typelib->data[offset2];
    1810  
    1811        if (!validate_field_blob (ctx, offset2, error))
    1812  	return FALSE;
    1813  
    1814        offset2 += sizeof (FieldBlob);
    1815        /* Special case fields which are callbacks. */
    1816        if (field_blob->has_embedded_type) {
    1817          offset2 += sizeof (CallbackBlob);
    1818          n_field_callbacks++;
    1819        }
    1820      }
    1821  
    1822    if (blob->n_field_callbacks != n_field_callbacks)
    1823      {
    1824        g_set_error (error,
    1825                     GI_TYPELIB_ERROR,
    1826                     GI_TYPELIB_ERROR_INVALID_BLOB,
    1827                     "Incorrect number of field callbacks; expected "
    1828                     "%" G_GUINT16_FORMAT ", got %" G_GUINT16_FORMAT,
    1829                     blob->n_field_callbacks, n_field_callbacks);
    1830        return FALSE;
    1831      }
    1832  
    1833    for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob))
    1834      {
    1835        if (!validate_property_blob (typelib, offset2, error))
    1836  	return FALSE;
    1837      }
    1838  
    1839    for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob))
    1840      {
    1841        if (!validate_function_blob (ctx, offset2, BLOB_TYPE_OBJECT, error))
    1842  	return FALSE;
    1843      }
    1844  
    1845    for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob))
    1846      {
    1847        if (!validate_signal_blob (typelib, offset2, offset, error))
    1848  	return FALSE;
    1849      }
    1850  
    1851    for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob))
    1852      {
    1853        if (!validate_vfunc_blob (typelib, offset2, offset, error))
    1854  	return FALSE;
    1855      }
    1856  
    1857    for (i = 0; i < blob->n_constants; i++, offset2 += sizeof (ConstantBlob))
    1858      {
    1859        if (!validate_constant_blob (typelib, offset2, error))
    1860  	return FALSE;
    1861      }
    1862  
    1863    pop_context (ctx);
    1864  
    1865    return TRUE;
    1866  }
    1867  
    1868  static gboolean
    1869  validate_interface_blob (ValidateContext *ctx,
    1870  			 guint32        offset,
    1871  			 GError       **error)
    1872  {
    1873    GITypelib *typelib = ctx->typelib;
    1874    Header *header;
    1875    InterfaceBlob *blob;
    1876    gint i;
    1877    guint32 offset2;
    1878  
    1879    header = (Header *)typelib->data;
    1880  
    1881    if (typelib->len < offset + sizeof (InterfaceBlob))
    1882      {
    1883        g_set_error (error,
    1884  		   GI_TYPELIB_ERROR,
    1885  		   GI_TYPELIB_ERROR_INVALID,
    1886  		   "The buffer is too short");
    1887        return FALSE;
    1888      }
    1889  
    1890    blob = (InterfaceBlob*) &typelib->data[offset];
    1891  
    1892    if (blob->blob_type != BLOB_TYPE_INTERFACE)
    1893      {
    1894        g_set_error (error,
    1895  		   GI_TYPELIB_ERROR,
    1896  		   GI_TYPELIB_ERROR_INVALID_BLOB,
    1897  		   "Wrong blob type; expected interface, got %d", blob->blob_type);
    1898        return FALSE;
    1899      }
    1900  
    1901    if (!validate_name (typelib, "interface", typelib->data, blob->gtype_name, error))
    1902      return FALSE;
    1903  
    1904    if (!validate_name (typelib, "interface", typelib->data, blob->gtype_init, error))
    1905      return FALSE;
    1906  
    1907    if (!validate_name (typelib, "interface", typelib->data, blob->name, error))
    1908      return FALSE;
    1909  
    1910    if (typelib->len < offset + sizeof (InterfaceBlob) +
    1911              (blob->n_prerequisites + blob->n_prerequisites % 2) * 2 +
    1912              blob->n_properties * sizeof (PropertyBlob) +
    1913              blob->n_methods * sizeof (FunctionBlob) +
    1914              blob->n_signals * sizeof (SignalBlob) +
    1915              blob->n_vfuncs * sizeof (VFuncBlob) +
    1916              blob->n_constants * sizeof (ConstantBlob))
    1917  
    1918      {
    1919        g_set_error (error,
    1920  		   GI_TYPELIB_ERROR,
    1921  		   GI_TYPELIB_ERROR_INVALID,
    1922  		   "The buffer is too short");
    1923        return FALSE;
    1924      }
    1925  
    1926    offset2 = offset + sizeof (InterfaceBlob);
    1927  
    1928    for (i = 0; i < blob->n_prerequisites; i++, offset2 += 2)
    1929      {
    1930        DirEntry *entry;
    1931        guint16 req;
    1932  
    1933        req = *(guint16*)&typelib->data[offset2];
    1934        if (req == 0 || req > header->n_entries)
    1935  	{
    1936  	  g_set_error (error,
    1937  		       GI_TYPELIB_ERROR,
    1938  		       GI_TYPELIB_ERROR_INVALID_BLOB,
    1939  		       "Invalid prerequisite index");
    1940  	  return FALSE;
    1941  	}
    1942  
    1943        entry = gi_typelib_get_dir_entry (typelib, req);
    1944        if (entry->blob_type != BLOB_TYPE_INTERFACE &&
    1945  	  entry->blob_type != BLOB_TYPE_OBJECT &&
    1946  	  (entry->local || entry->blob_type != 0))
    1947  	{
    1948  	  g_set_error (error,
    1949  		       GI_TYPELIB_ERROR,
    1950  		       GI_TYPELIB_ERROR_INVALID_BLOB,
    1951  		       "Not an interface or object");
    1952  	  return FALSE;
    1953  	}
    1954      }
    1955  
    1956    offset2 += 2 * (blob->n_prerequisites % 2);
    1957  
    1958    push_context (ctx, get_string_nofail (typelib, blob->name));
    1959  
    1960    for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob))
    1961      {
    1962        if (!validate_property_blob (typelib, offset2, error))
    1963  	return FALSE;
    1964      }
    1965  
    1966    for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob))
    1967      {
    1968        if (!validate_function_blob (ctx, offset2, BLOB_TYPE_INTERFACE, error))
    1969  	return FALSE;
    1970      }
    1971  
    1972    for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob))
    1973      {
    1974        if (!validate_signal_blob (typelib, offset2, offset, error))
    1975  	return FALSE;
    1976      }
    1977  
    1978    for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob))
    1979      {
    1980        if (!validate_vfunc_blob (typelib, offset2, offset, error))
    1981  	return FALSE;
    1982      }
    1983  
    1984    for (i = 0; i < blob->n_constants; i++, offset2 += sizeof (ConstantBlob))
    1985      {
    1986        if (!validate_constant_blob (typelib, offset2, error))
    1987  	return FALSE;
    1988      }
    1989  
    1990    pop_context (ctx);
    1991  
    1992    return TRUE;
    1993  }
    1994  
    1995  static gboolean
    1996  validate_union_blob (GITypelib     *typelib,
    1997  		     guint32        offset,
    1998  		     GError       **error)
    1999  {
    2000    return TRUE;
    2001  }
    2002  
    2003  static gboolean
    2004  validate_blob (ValidateContext *ctx,
    2005  	       guint32          offset,
    2006  	       GError         **error)
    2007  {
    2008    GITypelib *typelib = ctx->typelib;
    2009    CommonBlob *common;
    2010  
    2011    if (typelib->len < offset + sizeof (CommonBlob))
    2012      {
    2013        g_set_error (error,
    2014  		   GI_TYPELIB_ERROR,
    2015  		   GI_TYPELIB_ERROR_INVALID,
    2016  		   "The buffer is too short");
    2017        return FALSE;
    2018      }
    2019  
    2020    common = (CommonBlob*)&typelib->data[offset];
    2021  
    2022    switch (common->blob_type)
    2023      {
    2024      case BLOB_TYPE_FUNCTION:
    2025        if (!validate_function_blob (ctx, offset, 0, error))
    2026  	return FALSE;
    2027        break;
    2028      case BLOB_TYPE_CALLBACK:
    2029        if (!validate_callback_blob (ctx, offset, error))
    2030  	return FALSE;
    2031        break;
    2032      case BLOB_TYPE_STRUCT:
    2033      case BLOB_TYPE_BOXED:
    2034        if (!validate_struct_blob (ctx, offset, common->blob_type, error))
    2035  	return FALSE;
    2036        break;
    2037      case BLOB_TYPE_ENUM:
    2038      case BLOB_TYPE_FLAGS:
    2039        if (!validate_enum_blob (ctx, offset, common->blob_type, error))
    2040  	return FALSE;
    2041        break;
    2042      case BLOB_TYPE_OBJECT:
    2043        if (!validate_object_blob (ctx, offset, error))
    2044  	return FALSE;
    2045        break;
    2046      case BLOB_TYPE_INTERFACE:
    2047        if (!validate_interface_blob (ctx, offset, error))
    2048  	return FALSE;
    2049        break;
    2050      case BLOB_TYPE_CONSTANT:
    2051        if (!validate_constant_blob (typelib, offset, error))
    2052  	return FALSE;
    2053        break;
    2054      case BLOB_TYPE_UNION:
    2055        if (!validate_union_blob (typelib, offset, error))
    2056  	return FALSE;
    2057        break;
    2058      default:
    2059        g_set_error (error,
    2060  		   GI_TYPELIB_ERROR,
    2061  		   GI_TYPELIB_ERROR_INVALID_ENTRY,
    2062  		   "Invalid blob type");
    2063        return FALSE;
    2064      }
    2065  
    2066    return TRUE;
    2067  }
    2068  
    2069  static gboolean
    2070  validate_directory (ValidateContext   *ctx,
    2071  		    GError            **error)
    2072  {
    2073    GITypelib *typelib = ctx->typelib;
    2074    Header *header = (Header *)typelib->data;
    2075    DirEntry *entry;
    2076    gint i;
    2077  
    2078    if (typelib->len < header->directory + header->n_entries * sizeof (DirEntry))
    2079      {
    2080        g_set_error (error,
    2081  		   GI_TYPELIB_ERROR,
    2082  		   GI_TYPELIB_ERROR_INVALID,
    2083  		   "The buffer is too short");
    2084        return FALSE;
    2085      }
    2086  
    2087    for (i = 0; i < header->n_entries; i++)
    2088      {
    2089        entry = gi_typelib_get_dir_entry (typelib, i + 1);
    2090  
    2091        if (!validate_name (typelib, "entry", typelib->data, entry->name, error))
    2092  	return FALSE;
    2093  
    2094        if ((entry->local && entry->blob_type == BLOB_TYPE_INVALID) ||
    2095  	  entry->blob_type > BLOB_TYPE_UNION)
    2096  	{
    2097  	  g_set_error (error,
    2098  		       GI_TYPELIB_ERROR,
    2099  		       GI_TYPELIB_ERROR_INVALID_DIRECTORY,
    2100  		       "Invalid entry type");
    2101  	  return FALSE;
    2102  	}
    2103  
    2104        if (i < header->n_local_entries)
    2105  	{
    2106  	  if (!entry->local)
    2107  	    {
    2108  	      g_set_error (error,
    2109  			   GI_TYPELIB_ERROR,
    2110  			   GI_TYPELIB_ERROR_INVALID_DIRECTORY,
    2111  			   "Too few local directory entries");
    2112  	      return FALSE;
    2113  	    }
    2114  
    2115  	  if (!is_aligned (entry->offset))
    2116  	    {
    2117  	      g_set_error (error,
    2118  			   GI_TYPELIB_ERROR,
    2119  			   GI_TYPELIB_ERROR_INVALID_DIRECTORY,
    2120  			   "Misaligned entry");
    2121  	      return FALSE;
    2122  	    }
    2123  
    2124  	  if (!validate_blob (ctx, entry->offset, error))
    2125  	    return FALSE;
    2126  	}
    2127        else
    2128  	{
    2129  	  if (entry->local)
    2130  	    {
    2131  	      g_set_error (error,
    2132  			   GI_TYPELIB_ERROR,
    2133  			   GI_TYPELIB_ERROR_INVALID_DIRECTORY,
    2134  			   "Too many local directory entries");
    2135  	      return FALSE;
    2136  	    }
    2137  
    2138  	  if (!validate_name (typelib, "namespace", typelib->data, entry->offset, error))
    2139  	    return FALSE;
    2140  	}
    2141      }
    2142  
    2143    return TRUE;
    2144  }
    2145  
    2146  static gboolean
    2147  validate_attributes (ValidateContext *ctx,
    2148  		     GError       **error)
    2149  {
    2150    GITypelib *typelib = ctx->typelib;
    2151    Header *header = (Header *)typelib->data;
    2152  
    2153    if (header->size < header->attributes + header->n_attributes * sizeof (AttributeBlob))
    2154      {
    2155        g_set_error (error,
    2156  		   GI_TYPELIB_ERROR,
    2157  		   GI_TYPELIB_ERROR_INVALID,
    2158  		   "The buffer is too short");
    2159        return FALSE;
    2160      }
    2161  
    2162    return TRUE;
    2163  }
    2164  
    2165  static void
    2166  prefix_with_context (GError **error,
    2167  		     const char *section,
    2168  		     ValidateContext *ctx)
    2169  {
    2170    GString *str;
    2171    GSList *link;
    2172    char *buf;
    2173  
    2174    link = ctx->context_stack;
    2175    if (!link)
    2176      {
    2177        g_prefix_error (error, "In %s:", section);
    2178        return;
    2179      }
    2180  
    2181    str = g_string_new (NULL);
    2182  
    2183    for (; link; link = link->next)
    2184      {
    2185        g_string_append (str, link->data);
    2186        if (link->next)
    2187  	g_string_append_c (str, '/');
    2188      }
    2189    g_string_append_c (str, ')');
    2190    buf = g_string_free (str, FALSE);
    2191    g_prefix_error (error, "In %s (Context: %s): ", section, buf);
    2192    g_free (buf);
    2193  }
    2194  
    2195  /**
    2196   * gi_typelib_validate:
    2197   * @typelib: a #GITypelib
    2198   * @error: return location for a [type@GLib.Error], or `NULL`
    2199   *
    2200   * Check whether @typelib is well-formed, i.e. that the file is not corrupt or
    2201   * truncated.
    2202   *
    2203   * Returns: `TRUE` if @typelib is well-formed, `FALSE` otherwise
    2204   * Since: 2.80
    2205   */
    2206  gboolean
    2207  gi_typelib_validate (GITypelib  *typelib,
    2208                       GError    **error)
    2209  {
    2210    ValidateContext ctx;
    2211    ctx.typelib = typelib;
    2212    ctx.context_stack = NULL;
    2213  
    2214    if (!validate_header (&ctx, error))
    2215      {
    2216        prefix_with_context (error, "In header", &ctx);
    2217        return FALSE;
    2218      }
    2219  
    2220    if (!validate_directory (&ctx, error))
    2221      {
    2222        prefix_with_context (error, "directory", &ctx);
    2223        return FALSE;
    2224      }
    2225  
    2226    if (!validate_attributes (&ctx, error))
    2227      {
    2228        prefix_with_context (error, "attributes", &ctx);
    2229        return FALSE;
    2230      }
    2231  
    2232    return TRUE;
    2233  }
    2234  
    2235  /**
    2236   * gi_typelib_error_quark:
    2237   *
    2238   * Get the quark representing the [type@GIRepository.TypelibError] error domain.
    2239   *
    2240   * Returns: quark representing the error domain
    2241   * Since: 2.80
    2242   */
    2243  GQuark
    2244  gi_typelib_error_quark (void)
    2245  {
    2246    static GQuark quark = 0;
    2247    if (quark == 0)
    2248      quark = g_quark_from_static_string ("gi-typelib-error-quark");
    2249    return quark;
    2250  }
    2251  
    2252  static GSList *library_paths;
    2253  
    2254  /**
    2255   * gi_repository_prepend_library_path:
    2256   * @directory: (type filename): a single directory to scan for shared libraries
    2257   *
    2258   * Prepends @directory to the search path that is used to
    2259   * search shared libraries referenced by imported namespaces.
    2260   *
    2261   * Multiple calls to this function all contribute to the final
    2262   * list of paths.
    2263   *
    2264   * The list of paths is unique and shared for all
    2265   * [class@GIRepository.Repository] instances across the process, but it doesn’t
    2266   * affect namespaces imported before the call.
    2267   *
    2268   * If the library is not found in the directories configured
    2269   * in this way, loading will fall back to the system library
    2270   * path (i.e. `LD_LIBRARY_PATH` and `DT_RPATH` in ELF systems).
    2271   * See the documentation of your dynamic linker for full details.
    2272   *
    2273   * Since: 2.80
    2274   */
    2275  void
    2276  gi_repository_prepend_library_path (const char *directory)
    2277  {
    2278    library_paths = g_slist_prepend (library_paths,
    2279                                     g_strdup (directory));
    2280  }
    2281  
    2282  /* Note on the GModule flags used by this function:
    2283  
    2284   * Glade's autoconnect feature and OpenGL's extension mechanism
    2285   * as used by Clutter rely on g_module_open(NULL) to work as a means of
    2286   * accessing the app's symbols. This keeps us from using
    2287   * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well;
    2288   * in general libraries are not expecting multiple copies of
    2289   * themselves and are not expecting to be unloaded. So we just
    2290   * load modules globally for now.
    2291   */
    2292  static GModule *
    2293  load_one_shared_library (const char *shlib)
    2294  {
    2295    GSList *p;
    2296    GModule *m;
    2297  
    2298  #ifdef __APPLE__
    2299    /* On macOS, @-prefixed shlib paths (@rpath, @executable_path, @loader_path)
    2300       need to be treated as absolute; trying to combine them with a
    2301       configured library path produces a mangled path that is unresolvable
    2302       and may cause unintended side effects (such as loading the library
    2303       from a fall-back location on macOS 12.0.1).
    2304    */
    2305    if (!g_path_is_absolute (shlib) && !g_str_has_prefix (shlib, "@"))
    2306  #else
    2307    if (!g_path_is_absolute (shlib))
    2308  #endif
    2309      {
    2310        /* First try in configured library paths */
    2311        for (p = library_paths; p; p = p->next)
    2312          {
    2313            char *path = g_build_filename (p->data, shlib, NULL);
    2314  
    2315            m = g_module_open (path, G_MODULE_BIND_LAZY);
    2316  
    2317            g_free (path);
    2318            if (m != NULL)
    2319              return m;
    2320          }
    2321      }
    2322  
    2323    /* Then try loading from standard paths */
    2324    /* Do not attempt to fix up shlib to replace .la with .so:
    2325       it's done by GModule anyway.
    2326    */
    2327    return g_module_open (shlib, G_MODULE_BIND_LAZY);
    2328  }
    2329  
    2330  static void
    2331  gi_typelib_do_dlopen (GITypelib *typelib)
    2332  {
    2333    Header *header;
    2334    const char *shlib_str;
    2335  
    2336    header = (Header *) typelib->data;
    2337    /* note that NULL shlib means to open the main app, which is allowed */
    2338    if (header->shared_library)
    2339      shlib_str = gi_typelib_get_string (typelib, header->shared_library);
    2340    else
    2341      shlib_str = NULL;
    2342  
    2343    if (shlib_str != NULL && shlib_str[0] != '\0')
    2344      {
    2345        gchar **shlibs;
    2346        gint i;
    2347  
    2348        /* shared-library is a comma-separated list of libraries */
    2349        shlibs = g_strsplit (shlib_str, ",", 0);
    2350  
    2351         /* We load all passed libs unconditionally as if the same library is loaded
    2352          * again with g_module_open(), the same file handle will be returned. See bug:
    2353          * http://bugzilla.gnome.org/show_bug.cgi?id=555294
    2354          */
    2355        for (i = 0; shlibs[i]; i++)
    2356          {
    2357            GModule *module;
    2358  
    2359            module = load_one_shared_library (shlibs[i]);
    2360  
    2361            if (module == NULL)
    2362              {
    2363                g_warning ("Failed to load shared library '%s' referenced by the typelib: %s",
    2364                           shlibs[i], g_module_error ());
    2365              }
    2366            else
    2367              {
    2368                typelib->modules = g_list_append (typelib->modules, module);
    2369              }
    2370         }
    2371  
    2372        g_strfreev (shlibs);
    2373      }
    2374    else
    2375      {
    2376        /* If there's no shared-library entry for this module, assume that
    2377         * the module is for the application.  Some of the hand-written .gir files
    2378         * in gobject-introspection don't have shared-library entries, but no one
    2379         * is really going to be calling g_module_symbol on them either.
    2380         */
    2381        GModule *module = g_module_open (NULL, 0);
    2382        if (module == NULL)
    2383          g_warning ("gtypelib.c: Failed to g_module_open (NULL): %s", g_module_error ());
    2384        else
    2385          typelib->modules = g_list_prepend (typelib->modules, module);
    2386      }
    2387  }
    2388  
    2389  static inline void
    2390  gi_typelib_ensure_open (GITypelib *typelib)
    2391  {
    2392    if (typelib->open_attempted)
    2393      return;
    2394    typelib->open_attempted = TRUE;
    2395    gi_typelib_do_dlopen (typelib);
    2396  }
    2397  
    2398  /**
    2399   * gi_typelib_new_from_memory: (skip)
    2400   * @memory: (array length=len): address of memory chunk containing the typelib
    2401   * @len: length of memory chunk containing the typelib, in bytes
    2402   * @error: a [type@GLib.Error]
    2403   *
    2404   * Creates a new [type@GIRepository.Typelib] from a memory location.
    2405   *
    2406   * The memory block pointed to by @typelib will be automatically freed when the
    2407   * repository is destroyed.
    2408   *
    2409   * Returns: (transfer full): the new [type@GIRepository.Typelib]
    2410   * Since: 2.80
    2411   */
    2412  GITypelib *
    2413  gi_typelib_new_from_memory (guint8  *memory,
    2414                              gsize    len,
    2415                              GError **error)
    2416  {
    2417    GITypelib *meta;
    2418  
    2419    if (!validate_header_basic (memory, len, error))
    2420      return NULL;
    2421  
    2422    meta = g_slice_new0 (GITypelib);
    2423    meta->data = memory;
    2424    meta->len = len;
    2425    meta->owns_memory = TRUE;
    2426    meta->modules = NULL;
    2427  
    2428    return meta;
    2429  }
    2430  
    2431  /**
    2432   * gi_typelib_new_from_const_memory: (skip)
    2433   * @memory: (array length=len): address of memory chunk containing the typelib
    2434   * @len: length of memory chunk containing the typelib
    2435   * @error: a [type@GLib.Error]
    2436   *
    2437   * Creates a new [type@GIRepository.Typelib] from a memory location.
    2438   *
    2439   * Returns: (transfer full): the new [type@GIRepository.Typelib]
    2440   * Since: 2.80
    2441   */
    2442  GITypelib *
    2443  gi_typelib_new_from_const_memory (const guchar  *memory,
    2444                                    gsize          len,
    2445                                    GError       **error)
    2446  {
    2447    GITypelib *meta;
    2448  
    2449    if (!validate_header_basic (memory, len, error))
    2450      return NULL;
    2451  
    2452    meta = g_slice_new0 (GITypelib);
    2453    meta->data = (guchar *) memory;
    2454    meta->len = len;
    2455    meta->owns_memory = FALSE;
    2456    meta->modules = NULL;
    2457  
    2458    return meta;
    2459  }
    2460  
    2461  /**
    2462   * gi_typelib_new_from_mapped_file: (skip)
    2463   * @mfile: (transfer full): a [type@GLib.MappedFile], that will be freed when
    2464   *   the repository is destroyed
    2465   * @error: a #GError
    2466   *
    2467   * Creates a new [type@GIRepository.Typelib] from a [type@GLib.MappedFile].
    2468   *
    2469   * Returns: (transfer full): the new [type@GIRepository.Typelib]
    2470   * Since: 2.80
    2471   */
    2472  GITypelib *
    2473  gi_typelib_new_from_mapped_file (GMappedFile  *mfile,
    2474                                   GError      **error)
    2475  {
    2476    GITypelib *meta;
    2477    guint8 *data = (guint8 *) g_mapped_file_get_contents (mfile);
    2478    gsize len = g_mapped_file_get_length (mfile);
    2479  
    2480    if (!validate_header_basic (data, len, error))
    2481      return NULL;
    2482  
    2483    meta = g_slice_new0 (GITypelib);
    2484    meta->mfile = mfile;
    2485    meta->owns_memory = FALSE;
    2486    meta->data = data; 
    2487    meta->len = len;
    2488  
    2489    return meta;
    2490  }
    2491  
    2492  /**
    2493   * gi_typelib_free:
    2494   * @typelib: (transfer full): a #GITypelib
    2495   *
    2496   * Free a [type@GIRepository.Typelib].
    2497   *
    2498   * Since: 2.80
    2499   */
    2500  void
    2501  gi_typelib_free (GITypelib *typelib)
    2502  {
    2503    if (typelib->mfile)
    2504      g_mapped_file_unref (typelib->mfile);
    2505    else
    2506      if (typelib->owns_memory)
    2507        g_free (typelib->data);
    2508    if (typelib->modules)
    2509      {
    2510        g_list_foreach (typelib->modules, (GFunc) (void *) g_module_close, NULL);
    2511        g_list_free (typelib->modules);
    2512      }
    2513    g_slice_free (GITypelib, typelib);
    2514  }
    2515  
    2516  /**
    2517   * gi_typelib_get_namespace:
    2518   * @typelib: a #GITypelib
    2519   *
    2520   * Get the name of the namespace represented by @typelib.
    2521   *
    2522   * Returns: name of the namespace represented by @typelib
    2523   * Since: 2.80
    2524   */
    2525  const gchar *
    2526  gi_typelib_get_namespace (GITypelib *typelib)
    2527  {
    2528    return gi_typelib_get_string (typelib, ((Header *) typelib->data)->namespace);
    2529  }
    2530  
    2531  /**
    2532   * gi_typelib_symbol:
    2533   * @typelib: the typelib
    2534   * @symbol_name: name of symbol to be loaded
    2535   * @symbol: (out) (nullable): returns a pointer to the symbol value, or `NULL`
    2536   *   on failure
    2537   *
    2538   * Loads a symbol from a `GITypelib`.
    2539   *
    2540   * Returns: `TRUE` on success
    2541   * Since: 2.80
    2542   */
    2543  gboolean
    2544  gi_typelib_symbol (GITypelib *typelib, const char *symbol_name, gpointer *symbol)
    2545  {
    2546    GList *l;
    2547  
    2548    gi_typelib_ensure_open (typelib);
    2549  
    2550    /*
    2551     * The reason for having multiple modules dates from gir-repository
    2552     * when it was desired to inject code (accessors, etc.) into an
    2553     * existing library.  In that situation, the first module listed
    2554     * will be the custom one, which overrides the main one.  A bit
    2555     * inefficient, but the problem will go away when gir-repository
    2556     * does.
    2557     *
    2558     * For modules with no shared library, we dlopen'd the current
    2559     * process above.
    2560     */
    2561    for (l = typelib->modules; l; l = l->next)
    2562      {
    2563        GModule *module = l->data;
    2564  
    2565        if (g_module_symbol (module, symbol_name, symbol))
    2566          return TRUE;
    2567      }
    2568  
    2569    return FALSE;
    2570  }