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