tests: Add more invalid class tests to increase coverage
[vala-gnome.git] / gobject-introspection / gmetadata.c
blob963f9fe08d52e21e4376a3ef986d3737dfc15190
1 /* GObject introspection: metadata validation, auxiliary functions
2 * related to the binary metadata format
4 * Copyright (C) 2005 Matthias Clasen
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 #include <stdlib.h>
23 #include <string.h>
25 #include <glib.h>
27 #include "gmetadata.h"
30 #define ALIGN_VALUE(this, boundary) \
31 (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
34 DirEntry *
35 g_metadata_get_dir_entry (GMetadata *metadata,
36 guint16 index)
38 Header *header = (Header *)metadata->data;
40 return (DirEntry *)&metadata->data[header->directory + (index - 1) * header->entry_blob_size];
43 void
44 g_metadata_check_sanity (void)
46 /* Check that struct layout is as we expect */
47 g_assert (sizeof (Header) == 100);
48 g_assert (sizeof (DirEntry) == 12);
49 g_assert (sizeof (SimpleTypeBlob) == 4);
50 g_assert (sizeof (ArgBlob) == 12);
51 g_assert (sizeof (SignatureBlob) == 8);
52 g_assert (sizeof (CommonBlob) == 8);
53 g_assert (sizeof (FunctionBlob) == 16);
54 g_assert (sizeof (InterfaceTypeBlob) == 4);
55 g_assert (sizeof (ArrayTypeBlob) == 8);
56 g_assert (sizeof (ParamTypeBlob) == 4);
57 g_assert (sizeof (ErrorTypeBlob) == 4);
58 g_assert (sizeof (ErrorDomainBlob) == 16);
59 g_assert (sizeof (ValueBlob) == 12);
60 g_assert (sizeof (FieldBlob) == 12);
61 g_assert (sizeof (RegisteredTypeBlob) == 16);
62 g_assert (sizeof (StructBlob) == 20);
63 g_assert (sizeof (EnumBlob) == 20);
64 g_assert (sizeof (PropertyBlob) == 12);
65 g_assert (sizeof (SignalBlob) == 12);
66 g_assert (sizeof (VFuncBlob) == 16);
67 g_assert (sizeof (ObjectBlob) == 32);
68 g_assert (sizeof (InterfaceBlob) == 28);
69 g_assert (sizeof (ConstantBlob) == 20);
70 g_assert (sizeof (AnnotationBlob) == 12);
71 g_assert (sizeof (UnionBlob) == 28);
75 static gboolean
76 is_aligned (guint32 offset)
78 return offset == ALIGN_VALUE (offset, 4);
81 #define MAX_NAME_LEN 200
83 static gboolean
84 is_name (const guchar *data, guint32 offset)
86 gchar *name;
88 name = (gchar*)&data[offset];
90 if (!memchr (name, '\0', MAX_NAME_LEN))
91 return FALSE;
93 if (strspn (name, G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_") < strlen (name))
94 return FALSE;
96 return TRUE;
99 static gboolean
100 validate_header (GMetadata *metadata,
101 GError **error)
103 Header *header;
105 if (metadata->len < sizeof (Header))
107 g_set_error (error,
108 G_METADATA_ERROR,
109 G_METADATA_ERROR_INVALID,
110 "The buffer is too short");
111 return FALSE;
114 header = (Header *)metadata->data;
116 if (strncmp (header->magic, G_IDL_MAGIC, 16) != 0)
118 g_set_error (error,
119 G_METADATA_ERROR,
120 G_METADATA_ERROR_INVALID_HEADER,
121 "Magic string not found");
122 return FALSE;
126 if (header->major_version != 1 || header->minor_version != 0)
128 g_set_error (error,
129 G_METADATA_ERROR,
130 G_METADATA_ERROR_INVALID_HEADER,
131 "Version mismatch");
132 return FALSE;
136 if (header->n_entries < header->n_local_entries)
138 g_set_error (error,
139 G_METADATA_ERROR,
140 G_METADATA_ERROR_INVALID_HEADER,
141 "Inconsistent entry counts");
142 return FALSE;
145 if (header->size != metadata->len)
147 g_set_error (error,
148 G_METADATA_ERROR,
149 G_METADATA_ERROR_INVALID_HEADER,
150 "Metadata size mismatch");
151 return FALSE;
154 if (header->entry_blob_size != 12 ||
155 header->function_blob_size != 16 ||
156 header->callback_blob_size != 12 ||
157 header->signal_blob_size != 12 ||
158 header->vfunc_blob_size != 16 ||
159 header->arg_blob_size != 12 ||
160 header->property_blob_size != 12 ||
161 header->field_blob_size != 12 ||
162 header->value_blob_size != 12 ||
163 header->constant_blob_size != 20 ||
164 header->error_domain_blob_size != 16 ||
165 header->annotation_blob_size != 12 ||
166 header->signature_blob_size != 8 ||
167 header->enum_blob_size != 20 ||
168 header->struct_blob_size != 20 ||
169 header->object_blob_size != 32 ||
170 header->interface_blob_size != 28 ||
171 header->union_blob_size != 28)
173 g_set_error (error,
174 G_METADATA_ERROR,
175 G_METADATA_ERROR_INVALID_HEADER,
176 "Blob size mismatch");
177 return FALSE;
180 if (!is_aligned (header->directory))
182 g_set_error (error,
183 G_METADATA_ERROR,
184 G_METADATA_ERROR_INVALID_HEADER,
185 "Misaligned directory");
186 return FALSE;
189 if (!is_aligned (header->annotations))
191 g_set_error (error,
192 G_METADATA_ERROR,
193 G_METADATA_ERROR_INVALID_HEADER,
194 "Misaligned annotations");
195 return FALSE;
198 if (header->annotations == 0 && header->n_annotations > 0)
200 g_set_error (error,
201 G_METADATA_ERROR,
202 G_METADATA_ERROR_INVALID_HEADER,
203 "Wrong number of annotations");
204 return FALSE;
207 if (!is_name (metadata->data, header->namespace))
209 g_set_error (error,
210 G_METADATA_ERROR,
211 G_METADATA_ERROR_INVALID_HEADER,
212 "Invalid namespace name");
213 return FALSE;
216 return TRUE;
219 static gboolean validate_type_blob (GMetadata *metadata,
220 guint32 offset,
221 guint32 signature_offset,
222 gboolean return_type,
223 GError **error);
225 static gboolean
226 validate_array_type_blob (GMetadata *metadata,
227 guint32 offset,
228 guint32 signature_offset,
229 gboolean return_type,
230 GError **error)
232 ArrayTypeBlob *blob;
234 blob = (ArrayTypeBlob*)&metadata->data[offset];
236 if (!blob->pointer)
238 g_set_error (error,
239 G_METADATA_ERROR,
240 G_METADATA_ERROR_INVALID_BLOB,
241 "Pointer type exected for tag %d", blob->tag);
242 return FALSE;
245 /* FIXME validate length */
247 if (!validate_type_blob (metadata,
248 offset + G_STRUCT_OFFSET (ArrayTypeBlob, type),
249 0, FALSE, error))
250 return FALSE;
252 return TRUE;
255 static gboolean
256 validate_iface_type_blob (GMetadata *metadata,
257 guint32 offset,
258 guint32 signature_offset,
259 gboolean return_type,
260 GError **error)
262 InterfaceTypeBlob *blob;
263 Header *header;
265 header = (Header *)metadata->data;
267 blob = (InterfaceTypeBlob*)&metadata->data[offset];
269 if (blob->interface == 0 || blob->interface > header->n_entries)
271 g_set_error (error,
272 G_METADATA_ERROR,
273 G_METADATA_ERROR_INVALID_BLOB,
274 "Invalid directory index %d", blob->interface);
275 return FALSE;
278 return TRUE;
281 static gboolean
282 validate_param_type_blob (GMetadata *metadata,
283 guint32 offset,
284 guint32 signature_offset,
285 gboolean return_type,
286 gint n_params,
287 GError **error)
289 ParamTypeBlob *blob;
290 gint i;
292 blob = (ParamTypeBlob*)&metadata->data[offset];
294 if (!blob->pointer)
296 g_set_error (error,
297 G_METADATA_ERROR,
298 G_METADATA_ERROR_INVALID_BLOB,
299 "Pointer type exected for tag %d", blob->tag);
300 return FALSE;
303 if (blob->n_types != n_params)
305 g_set_error (error,
306 G_METADATA_ERROR,
307 G_METADATA_ERROR_INVALID_BLOB,
308 "Parameter type number mismatch");
309 return FALSE;
312 for (i = 0; i < n_params; i++)
314 if (!validate_type_blob (metadata,
315 offset + sizeof (ParamTypeBlob) +
316 i * sizeof (SimpleTypeBlob),
317 0, FALSE, error))
318 return FALSE;
321 return TRUE;
324 static gboolean
325 validate_error_type_blob (GMetadata *metadata,
326 guint32 offset,
327 guint32 signature_offset,
328 gboolean return_type,
329 GError **error)
331 ErrorTypeBlob *blob;
332 Header *header;
333 gint i;
334 DirEntry *entry;
336 blob = (ErrorTypeBlob*)&metadata->data[offset];
338 header = (Header *)metadata->data;
340 if (!blob->pointer)
342 g_set_error (error,
343 G_METADATA_ERROR,
344 G_METADATA_ERROR_INVALID_BLOB,
345 "Pointer type exected for tag %d", blob->tag);
346 return FALSE;
349 for (i = 0; i < blob->n_domains; i++)
351 if (blob->domains[i] == 0 || blob->domains[i] > header->n_entries)
353 g_set_error (error,
354 G_METADATA_ERROR,
355 G_METADATA_ERROR_INVALID_BLOB,
356 "Invalid directory index %d", blob->domains[i]);
357 return FALSE;
360 entry = g_metadata_get_dir_entry (metadata, blob->domains[i]);
362 if (entry->blob_type != BLOB_TYPE_ERROR_DOMAIN &&
363 (entry->local || entry->blob_type != BLOB_TYPE_INVALID))
365 g_set_error (error,
366 G_METADATA_ERROR,
367 G_METADATA_ERROR_INVALID_BLOB,
368 "Wrong blob type");
369 return FALSE;
373 return TRUE;
376 static gboolean
377 validate_type_blob (GMetadata *metadata,
378 guint32 offset,
379 guint32 signature_offset,
380 gboolean return_type,
381 GError **error)
383 SimpleTypeBlob *simple;
384 InterfaceTypeBlob *iface;
386 simple = (SimpleTypeBlob *)&metadata->data[offset];
388 if (simple->reserved == 0 &&
389 simple->reserved2 == 0)
391 if (simple->tag >= TYPE_TAG_ARRAY)
393 g_set_error (error,
394 G_METADATA_ERROR,
395 G_METADATA_ERROR_INVALID_BLOB,
396 "Wrong tag in simple type");
397 return FALSE;
400 if (simple->tag >= TYPE_TAG_UTF8 &&
401 !simple->pointer)
403 g_set_error (error,
404 G_METADATA_ERROR,
405 G_METADATA_ERROR_INVALID_BLOB,
406 "Pointer type exected for tag %d", simple->tag);
407 return FALSE;
410 return TRUE;
413 iface = (InterfaceTypeBlob*)&metadata->data[simple->offset];
415 switch (iface->tag)
417 case TYPE_TAG_ARRAY:
418 if (!validate_array_type_blob (metadata, simple->offset,
419 signature_offset, return_type, error))
420 return FALSE;
421 break;
422 case TYPE_TAG_INTERFACE:
423 if (!validate_iface_type_blob (metadata, simple->offset,
424 signature_offset, return_type, error))
425 return FALSE;
426 break;
427 case TYPE_TAG_LIST:
428 case TYPE_TAG_SLIST:
429 if (!validate_param_type_blob (metadata, simple->offset,
430 signature_offset, return_type, 1, error))
431 return FALSE;
432 break;
433 case TYPE_TAG_HASH:
434 if (!validate_param_type_blob (metadata, simple->offset,
435 signature_offset, return_type, 2, error))
436 return FALSE;
437 break;
438 case TYPE_TAG_ERROR:
439 if (!validate_error_type_blob (metadata, simple->offset,
440 signature_offset, return_type, error))
441 return FALSE;
442 break;
443 default:
444 g_set_error (error,
445 G_METADATA_ERROR,
446 G_METADATA_ERROR_INVALID_BLOB,
447 "Wrong tag in complex type");
448 return FALSE;
451 return TRUE;
454 static gboolean
455 validate_arg_blob (GMetadata *metadata,
456 guint32 offset,
457 guint32 signature_offset,
458 GError **error)
460 ArgBlob *blob;
462 if (metadata->len < offset + sizeof (ArgBlob))
464 g_set_error (error,
465 G_METADATA_ERROR,
466 G_METADATA_ERROR_INVALID,
467 "The buffer is too short");
468 return FALSE;
471 blob = (ArgBlob*) &metadata->data[offset];
473 if (!is_name (metadata->data, blob->name))
475 g_set_error (error,
476 G_METADATA_ERROR,
477 G_METADATA_ERROR_INVALID_BLOB,
478 "Invalid argument name");
479 return FALSE;
482 if (!validate_type_blob (metadata,
483 offset + G_STRUCT_OFFSET (ArgBlob, arg_type),
484 signature_offset, FALSE, error))
485 return FALSE;
487 return TRUE;
490 static gboolean
491 validate_signature_blob (GMetadata *metadata,
492 guint32 offset,
493 GError **error)
495 SignatureBlob *blob;
496 gint i;
498 if (metadata->len < offset + sizeof (SignatureBlob))
500 g_set_error (error,
501 G_METADATA_ERROR,
502 G_METADATA_ERROR_INVALID,
503 "The buffer is too short");
504 return FALSE;
507 blob = (SignatureBlob*) &metadata->data[offset];
509 if (blob->return_type.offset != 0)
511 if (!validate_type_blob (metadata,
512 offset + G_STRUCT_OFFSET (SignatureBlob, return_type),
513 offset, TRUE, error))
514 return FALSE;
517 for (i = 0; i < blob->n_arguments; i++)
519 if (!validate_arg_blob (metadata,
520 offset + sizeof (SignatureBlob) +
521 i * sizeof (ArgBlob),
522 offset,
523 error))
524 return FALSE;
527 /* FIXME check constraints on return_value */
528 /* FIXME check array-length pairs */
529 return TRUE;
532 static gboolean
533 validate_function_blob (GMetadata *metadata,
534 guint32 offset,
535 guint16 container_type,
536 GError **error)
538 FunctionBlob *blob;
540 if (metadata->len < offset + sizeof (FunctionBlob))
542 g_set_error (error,
543 G_METADATA_ERROR,
544 G_METADATA_ERROR_INVALID,
545 "The buffer is too short");
546 return FALSE;
549 blob = (FunctionBlob*) &metadata->data[offset];
551 if (blob->blob_type != BLOB_TYPE_FUNCTION)
553 g_set_error (error,
554 G_METADATA_ERROR,
555 G_METADATA_ERROR_INVALID_BLOB,
556 "Wrong blob type");
557 return FALSE;
560 if (!is_name (metadata->data, blob->name))
562 g_set_error (error,
563 G_METADATA_ERROR,
564 G_METADATA_ERROR_INVALID_BLOB,
565 "Invalid function name");
566 return FALSE;
569 if (!is_name (metadata->data, blob->symbol))
571 g_set_error (error,
572 G_METADATA_ERROR,
573 G_METADATA_ERROR_INVALID_BLOB,
574 "Invalid function symbol");
575 return FALSE;
578 if (blob->constructor)
580 switch (container_type)
582 case BLOB_TYPE_BOXED:
583 case BLOB_TYPE_OBJECT:
584 case BLOB_TYPE_INTERFACE:
585 break;
586 default:
587 g_set_error (error,
588 G_METADATA_ERROR,
589 G_METADATA_ERROR_INVALID_BLOB,
590 "Constructor not allowed");
591 return FALSE;
595 if (blob->setter || blob->getter || blob->wraps_vfunc)
597 switch (container_type)
599 case BLOB_TYPE_OBJECT:
600 case BLOB_TYPE_INTERFACE:
601 break;
602 default:
603 g_set_error (error,
604 G_METADATA_ERROR,
605 G_METADATA_ERROR_INVALID_BLOB,
606 "Setter, getter or wrapper not allowed");
607 return FALSE;
611 if (blob->index)
613 if (!(blob->setter || blob->getter || blob->wraps_vfunc))
615 g_set_error (error,
616 G_METADATA_ERROR,
617 G_METADATA_ERROR_INVALID_BLOB,
618 "Must be setter, getter or wrapper");
619 return FALSE;
623 /* FIXME: validate index range */
624 /* FIXME: validate "this" argument for methods */
625 /* FIXME: validate return type for constructors */
627 if (!validate_signature_blob (metadata, blob->signature, error))
628 return FALSE;
630 return TRUE;
633 static gboolean
634 validate_callback_blob (GMetadata *metadata,
635 guint32 offset,
636 GError **error)
638 CallbackBlob *blob;
640 if (metadata->len < offset + sizeof (CallbackBlob))
642 g_set_error (error,
643 G_METADATA_ERROR,
644 G_METADATA_ERROR_INVALID,
645 "The buffer is too short");
646 return FALSE;
649 blob = (CallbackBlob*) &metadata->data[offset];
651 if (blob->blob_type != BLOB_TYPE_CALLBACK)
653 g_set_error (error,
654 G_METADATA_ERROR,
655 G_METADATA_ERROR_INVALID_BLOB,
656 "Wrong blob type");
657 return FALSE;
660 if (!is_name (metadata->data, blob->name))
662 g_set_error (error,
663 G_METADATA_ERROR,
664 G_METADATA_ERROR_INVALID_BLOB,
665 "Invalid callback name");
666 return FALSE;
669 if (!validate_signature_blob (metadata, blob->signature, error))
670 return FALSE;
672 return TRUE;
675 static gboolean
676 validate_constant_blob (GMetadata *metadata,
677 guint32 offset,
678 GError **error)
680 gint value_size[] = {
681 0, 4, 1, 1, 2, 2, 4, 4, 8, 8,
682 sizeof (gint), sizeof (guint),
683 sizeof (glong), sizeof (gulong),
684 sizeof (gssize), sizeof (gsize),
685 sizeof (gfloat), sizeof (gdouble),
686 0, 0
688 ConstantBlob *blob;
689 SimpleTypeBlob *type;
691 if (metadata->len < offset + sizeof (ConstantBlob))
693 g_set_error (error,
694 G_METADATA_ERROR,
695 G_METADATA_ERROR_INVALID,
696 "The buffer is too short");
697 return FALSE;
700 blob = (ConstantBlob*) &metadata->data[offset];
702 if (blob->blob_type != BLOB_TYPE_CONSTANT)
704 g_set_error (error,
705 G_METADATA_ERROR,
706 G_METADATA_ERROR_INVALID_BLOB,
707 "Wrong blob type");
708 return FALSE;
711 if (!is_name (metadata->data, blob->name))
713 g_set_error (error,
714 G_METADATA_ERROR,
715 G_METADATA_ERROR_INVALID_BLOB,
716 "Invalid constant name");
717 return FALSE;
720 if (!validate_type_blob (metadata, offset + G_STRUCT_OFFSET (ConstantBlob, type),
721 0, FALSE, error))
722 return FALSE;
724 if (!is_aligned (blob->offset))
726 g_set_error (error,
727 G_METADATA_ERROR,
728 G_METADATA_ERROR_INVALID_BLOB,
729 "Misaligned constant value");
730 return FALSE;
733 type = (SimpleTypeBlob *)&metadata->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)];
734 if (type->reserved == 0)
736 if (type->tag == 0)
738 g_set_error (error,
739 G_METADATA_ERROR,
740 G_METADATA_ERROR_INVALID_BLOB,
741 "Constant value type void");
742 return FALSE;
745 if (value_size[type->tag] != 0 &&
746 blob->size != value_size[type->tag])
748 g_set_error (error,
749 G_METADATA_ERROR,
750 G_METADATA_ERROR_INVALID_BLOB,
751 "Constant value size mismatch");
752 return FALSE;
754 /* FIXME check string values */
757 return TRUE;
760 static gboolean
761 validate_value_blob (GMetadata *metadata,
762 guint32 offset,
763 GError **error)
765 ValueBlob *blob;
767 if (metadata->len < offset + sizeof (ValueBlob))
769 g_set_error (error,
770 G_METADATA_ERROR,
771 G_METADATA_ERROR_INVALID,
772 "The buffer is too short");
773 return FALSE;
776 blob = (ValueBlob*) &metadata->data[offset];
778 if (!is_name (metadata->data, blob->name))
780 g_set_error (error,
781 G_METADATA_ERROR,
782 G_METADATA_ERROR_INVALID_BLOB,
783 "Invalid value name");
784 return FALSE;
787 return TRUE;
790 static gboolean
791 validate_field_blob (GMetadata *metadata,
792 guint32 offset,
793 GError **error)
795 FieldBlob *blob;
797 if (metadata->len < offset + sizeof (FieldBlob))
799 g_set_error (error,
800 G_METADATA_ERROR,
801 G_METADATA_ERROR_INVALID,
802 "The buffer is too short");
803 return FALSE;
806 blob = (FieldBlob*) &metadata->data[offset];
808 if (!is_name (metadata->data, blob->name))
810 g_set_error (error,
811 G_METADATA_ERROR,
812 G_METADATA_ERROR_INVALID_BLOB,
813 "Invalid field name");
814 return FALSE;
817 if (!validate_type_blob (metadata,
818 offset + G_STRUCT_OFFSET (FieldBlob, type),
819 0, FALSE, error))
820 return FALSE;
822 return TRUE;
825 static gboolean
826 validate_property_blob (GMetadata *metadata,
827 guint32 offset,
828 GError **error)
830 PropertyBlob *blob;
832 if (metadata->len < offset + sizeof (PropertyBlob))
834 g_set_error (error,
835 G_METADATA_ERROR,
836 G_METADATA_ERROR_INVALID,
837 "The buffer is too short");
838 return FALSE;
841 blob = (PropertyBlob*) &metadata->data[offset];
843 if (!is_name (metadata->data, blob->name))
845 g_set_error (error,
846 G_METADATA_ERROR,
847 G_METADATA_ERROR_INVALID_BLOB,
848 "Invalid property name");
849 return FALSE;
852 if (!validate_type_blob (metadata,
853 offset + G_STRUCT_OFFSET (PropertyBlob, type),
854 0, FALSE, error))
855 return FALSE;
857 return TRUE;
860 static gboolean
861 validate_signal_blob (GMetadata *metadata,
862 guint32 offset,
863 guint32 container_offset,
864 GError **error)
866 SignalBlob *blob;
867 gint n_signals;
869 if (metadata->len < offset + sizeof (SignalBlob))
871 g_set_error (error,
872 G_METADATA_ERROR,
873 G_METADATA_ERROR_INVALID,
874 "The buffer is too short");
875 return FALSE;
878 blob = (SignalBlob*) &metadata->data[offset];
880 if (!is_name (metadata->data, blob->name))
882 g_set_error (error,
883 G_METADATA_ERROR,
884 G_METADATA_ERROR_INVALID_BLOB,
885 "Invalid signal name");
886 return FALSE;
889 if ((blob->run_first != 0) +
890 (blob->run_last != 0) +
891 (blob->run_cleanup != 0) != 1)
893 g_set_error (error,
894 G_METADATA_ERROR,
895 G_METADATA_ERROR_INVALID_BLOB,
896 "Invalid signal run flags");
897 return FALSE;
900 if (blob->has_class_closure)
902 if (((CommonBlob*)&metadata->data[container_offset])->blob_type == BLOB_TYPE_OBJECT)
904 ObjectBlob *object;
906 object = (ObjectBlob*)&metadata->data[container_offset];
908 n_signals = object->n_signals;
910 else
912 InterfaceBlob *iface;
914 iface = (InterfaceBlob*)&metadata->data[container_offset];
916 n_signals = iface->n_signals;
919 if (blob->class_closure >= n_signals)
921 g_set_error (error,
922 G_METADATA_ERROR,
923 G_METADATA_ERROR_INVALID_BLOB,
924 "Invalid class closure index");
925 return FALSE;
929 if (!validate_signature_blob (metadata, blob->signature, error))
930 return FALSE;
932 return TRUE;
935 static gboolean
936 validate_vfunc_blob (GMetadata *metadata,
937 guint32 offset,
938 guint32 container_offset,
939 GError **error)
941 VFuncBlob *blob;
942 gint n_vfuncs;
944 if (metadata->len < offset + sizeof (VFuncBlob))
946 g_set_error (error,
947 G_METADATA_ERROR,
948 G_METADATA_ERROR_INVALID,
949 "The buffer is too short");
950 return FALSE;
953 blob = (VFuncBlob*) &metadata->data[offset];
955 if (!is_name (metadata->data, blob->name))
957 g_set_error (error,
958 G_METADATA_ERROR,
959 G_METADATA_ERROR_INVALID_BLOB,
960 "Invalid vfunc name");
961 return FALSE;
964 if (blob->class_closure)
966 if (((CommonBlob*)&metadata->data[container_offset])->blob_type == BLOB_TYPE_OBJECT)
968 ObjectBlob *object;
970 object = (ObjectBlob*)&metadata->data[container_offset];
972 n_vfuncs = object->n_vfuncs;
974 else
976 InterfaceBlob *iface;
978 iface = (InterfaceBlob*)&metadata->data[container_offset];
980 n_vfuncs = iface->n_vfuncs;
983 if (blob->class_closure >= n_vfuncs)
985 g_set_error (error,
986 G_METADATA_ERROR,
987 G_METADATA_ERROR_INVALID_BLOB,
988 "Invalid class closure index");
989 return FALSE;
993 if (!validate_signature_blob (metadata, blob->signature, error))
994 return FALSE;
996 return TRUE;
999 static gboolean
1000 validate_struct_blob (GMetadata *metadata,
1001 guint32 offset,
1002 guint16 blob_type,
1003 GError **error)
1005 StructBlob *blob;
1006 gint i;
1008 if (metadata->len < offset + sizeof (StructBlob))
1010 g_set_error (error,
1011 G_METADATA_ERROR,
1012 G_METADATA_ERROR_INVALID,
1013 "The buffer is too short");
1014 return FALSE;
1017 blob = (StructBlob*) &metadata->data[offset];
1019 if (blob->blob_type != blob_type)
1021 g_set_error (error,
1022 G_METADATA_ERROR,
1023 G_METADATA_ERROR_INVALID_BLOB,
1024 "Wrong blob type");
1025 return FALSE;
1028 if ((blob->blob_type == BLOB_TYPE_BOXED && blob->unregistered) ||
1029 (blob->blob_type == BLOB_TYPE_STRUCT && !blob->unregistered))
1031 g_set_error (error,
1032 G_METADATA_ERROR,
1033 G_METADATA_ERROR_INVALID_BLOB,
1034 "Registration/blob type mismatch");
1035 return FALSE;
1038 if (!is_name (metadata->data, blob->name))
1040 g_set_error (error,
1041 G_METADATA_ERROR,
1042 G_METADATA_ERROR_INVALID_BLOB,
1043 "Invalid struct name");
1044 return FALSE;
1047 if (blob_type == BLOB_TYPE_BOXED)
1049 if (!is_name (metadata->data, blob->gtype_name))
1051 g_set_error (error,
1052 G_METADATA_ERROR,
1053 G_METADATA_ERROR_INVALID_BLOB,
1054 "Invalid boxed type name");
1055 return FALSE;
1058 if (!is_name (metadata->data, blob->gtype_init))
1060 g_set_error (error,
1061 G_METADATA_ERROR,
1062 G_METADATA_ERROR_INVALID_BLOB,
1063 "Invalid boxed type init");
1064 return FALSE;
1067 else
1069 if (blob->gtype_name || blob->gtype_init)
1071 g_set_error (error,
1072 G_METADATA_ERROR,
1073 G_METADATA_ERROR_INVALID_BLOB,
1074 "Gtype data in struct");
1075 return FALSE;
1079 if (metadata->len < offset + sizeof (StructBlob) +
1080 blob->n_fields * sizeof (FieldBlob) +
1081 blob->n_methods * sizeof (FunctionBlob))
1083 g_set_error (error,
1084 G_METADATA_ERROR,
1085 G_METADATA_ERROR_INVALID,
1086 "The buffer is too short");
1087 return FALSE;
1090 for (i = 0; i < blob->n_fields; i++)
1092 if (!validate_field_blob (metadata,
1093 offset + sizeof (StructBlob) +
1094 i * sizeof (FieldBlob),
1095 error))
1096 return FALSE;
1099 for (i = 0; i < blob->n_methods; i++)
1101 if (!validate_function_blob (metadata,
1102 offset + sizeof (StructBlob) +
1103 blob->n_fields * sizeof (FieldBlob) +
1104 i * sizeof (FunctionBlob),
1105 blob_type,
1106 error))
1107 return FALSE;
1110 return TRUE;
1113 static gboolean
1114 validate_enum_blob (GMetadata *metadata,
1115 guint32 offset,
1116 guint16 blob_type,
1117 GError **error)
1119 EnumBlob *blob;
1120 ValueBlob *v1, *v2;
1121 gint i, j;
1123 if (metadata->len < offset + sizeof (EnumBlob))
1125 g_set_error (error,
1126 G_METADATA_ERROR,
1127 G_METADATA_ERROR_INVALID,
1128 "The buffer is too short");
1129 return FALSE;
1132 blob = (EnumBlob*) &metadata->data[offset];
1134 if (blob->blob_type != blob_type)
1136 g_set_error (error,
1137 G_METADATA_ERROR,
1138 G_METADATA_ERROR_INVALID_BLOB,
1139 "Wrong blob type");
1140 return FALSE;
1143 if (!blob->unregistered)
1145 if (!is_name (metadata->data, blob->gtype_name))
1147 g_set_error (error,
1148 G_METADATA_ERROR,
1149 G_METADATA_ERROR_INVALID_BLOB,
1150 "Invalid enum type name");
1151 return FALSE;
1154 if (!is_name (metadata->data, blob->gtype_init))
1156 g_set_error (error,
1157 G_METADATA_ERROR,
1158 G_METADATA_ERROR_INVALID_BLOB,
1159 "Invalid enum type init");
1160 return FALSE;
1163 else
1165 if (blob->gtype_name || blob->gtype_init)
1167 g_set_error (error,
1168 G_METADATA_ERROR,
1169 G_METADATA_ERROR_INVALID_BLOB,
1170 "Gtype data in unregistered enum");
1171 return FALSE;
1175 if (!is_name (metadata->data, blob->name))
1177 g_set_error (error,
1178 G_METADATA_ERROR,
1179 G_METADATA_ERROR_INVALID_BLOB,
1180 "Invalid enum name");
1181 return FALSE;
1184 if (metadata->len < offset + sizeof (EnumBlob) +
1185 blob->n_values * sizeof (ValueBlob))
1187 g_set_error (error,
1188 G_METADATA_ERROR,
1189 G_METADATA_ERROR_INVALID,
1190 "The buffer is too short");
1191 return FALSE;
1194 for (i = 0; i < blob->n_values; i++)
1196 if (!validate_value_blob (metadata,
1197 offset + sizeof (EnumBlob) +
1198 i * sizeof (ValueBlob),
1199 error))
1200 return FALSE;
1202 v1 = (ValueBlob *)&metadata->data[offset + sizeof (EnumBlob) +
1203 i * sizeof (ValueBlob)];
1204 for (j = 0; j < i; j++)
1206 v2 = (ValueBlob *)&metadata->data[offset + sizeof (EnumBlob) +
1207 j * sizeof (ValueBlob)];
1209 if (v1->value == v2->value)
1211 /* FIXME should this be an error ? */
1212 g_set_error (error,
1213 G_METADATA_ERROR,
1214 G_METADATA_ERROR_INVALID_BLOB,
1215 "Duplicate enum value");
1216 return FALSE;
1221 return TRUE;
1224 static gboolean
1225 validate_object_blob (GMetadata *metadata,
1226 guint32 offset,
1227 GError **error)
1229 Header *header;
1230 ObjectBlob *blob;
1231 gint i;
1232 guint32 offset2;
1234 header = (Header *)metadata->data;
1236 if (metadata->len < offset + sizeof (ObjectBlob))
1238 g_set_error (error,
1239 G_METADATA_ERROR,
1240 G_METADATA_ERROR_INVALID,
1241 "The buffer is too short");
1242 return FALSE;
1245 blob = (ObjectBlob*) &metadata->data[offset];
1247 if (blob->blob_type != BLOB_TYPE_OBJECT)
1249 g_set_error (error,
1250 G_METADATA_ERROR,
1251 G_METADATA_ERROR_INVALID_BLOB,
1252 "Wrong blob type");
1253 return FALSE;
1256 if (!is_name (metadata->data, blob->gtype_name))
1258 g_set_error (error,
1259 G_METADATA_ERROR,
1260 G_METADATA_ERROR_INVALID_BLOB,
1261 "Invalid object type name");
1262 return FALSE;
1265 if (!is_name (metadata->data, blob->gtype_init))
1267 g_set_error (error,
1268 G_METADATA_ERROR,
1269 G_METADATA_ERROR_INVALID_BLOB,
1270 "Invalid object type init");
1271 return FALSE;
1274 if (!is_name (metadata->data, blob->name))
1276 g_set_error (error,
1277 G_METADATA_ERROR,
1278 G_METADATA_ERROR_INVALID_BLOB,
1279 "Invalid object name");
1280 return FALSE;
1283 if (blob->parent > header->n_entries)
1285 g_set_error (error,
1286 G_METADATA_ERROR,
1287 G_METADATA_ERROR_INVALID_BLOB,
1288 "Invalid parent index");
1289 return FALSE;
1292 if (blob->parent != 0)
1294 DirEntry *entry;
1296 entry = g_metadata_get_dir_entry (metadata, blob->parent);
1297 if (entry->blob_type != BLOB_TYPE_OBJECT &&
1298 (entry->local || entry->blob_type != 0))
1300 g_set_error (error,
1301 G_METADATA_ERROR,
1302 G_METADATA_ERROR_INVALID_BLOB,
1303 "Parent not object");
1304 return FALSE;
1308 if (metadata->len < offset + sizeof (ObjectBlob) +
1309 (blob->n_interfaces + blob->n_interfaces % 2) * 2 +
1310 blob->n_fields * sizeof (FieldBlob) +
1311 blob->n_properties * sizeof (PropertyBlob) +
1312 blob->n_methods * sizeof (FunctionBlob) +
1313 blob->n_signals * sizeof (SignalBlob) +
1314 blob->n_vfuncs * sizeof (VFuncBlob) +
1315 blob->n_constants * sizeof (ConstantBlob))
1318 g_set_error (error,
1319 G_METADATA_ERROR,
1320 G_METADATA_ERROR_INVALID,
1321 "The buffer is too short");
1322 return FALSE;
1325 offset2 = offset + sizeof (ObjectBlob);
1327 for (i = 0; i < blob->n_interfaces; i++, offset2 += 2)
1329 guint16 iface;
1330 DirEntry *entry;
1332 iface = *(guint16*)&metadata->data[offset2];
1333 if (iface == 0 || iface > header->n_entries)
1335 g_set_error (error,
1336 G_METADATA_ERROR,
1337 G_METADATA_ERROR_INVALID_BLOB,
1338 "Invalid interface index");
1339 return FALSE;
1342 entry = g_metadata_get_dir_entry (metadata, iface);
1344 if (entry->blob_type != BLOB_TYPE_INTERFACE &&
1345 (entry->local || entry->blob_type != 0))
1347 g_set_error (error,
1348 G_METADATA_ERROR,
1349 G_METADATA_ERROR_INVALID_BLOB,
1350 "Not an interface");
1351 return FALSE;
1355 offset2 += 2 * (blob->n_interfaces %2);
1357 for (i = 0; i < blob->n_fields; i++, offset2 += sizeof (FieldBlob))
1359 if (!validate_field_blob (metadata, offset2, error))
1360 return FALSE;
1363 for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob))
1365 if (!validate_property_blob (metadata, offset2, error))
1366 return FALSE;
1369 for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob))
1371 if (!validate_function_blob (metadata, offset2, BLOB_TYPE_OBJECT, error))
1372 return FALSE;
1375 for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob))
1377 if (!validate_signal_blob (metadata, offset2, offset, error))
1378 return FALSE;
1381 for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob))
1383 if (!validate_vfunc_blob (metadata, offset2, offset, error))
1384 return FALSE;
1387 for (i = 0; i < blob->n_constants; i++, offset2 += sizeof (ConstantBlob))
1389 if (!validate_constant_blob (metadata, offset2, error))
1390 return FALSE;
1393 return TRUE;
1396 static gboolean
1397 validate_interface_blob (GMetadata *metadata,
1398 guint32 offset,
1399 GError **error)
1401 Header *header;
1402 InterfaceBlob *blob;
1403 gint i;
1404 guint32 offset2;
1406 header = (Header *)metadata->data;
1408 if (metadata->len < offset + sizeof (InterfaceBlob))
1410 g_set_error (error,
1411 G_METADATA_ERROR,
1412 G_METADATA_ERROR_INVALID,
1413 "The buffer is too short");
1414 return FALSE;
1417 blob = (InterfaceBlob*) &metadata->data[offset];
1419 if (blob->blob_type != BLOB_TYPE_INTERFACE)
1421 g_set_error (error,
1422 G_METADATA_ERROR,
1423 G_METADATA_ERROR_INVALID_BLOB,
1424 "Wrong blob type");
1425 return FALSE;
1428 if (!is_name (metadata->data, blob->gtype_name))
1430 g_set_error (error,
1431 G_METADATA_ERROR,
1432 G_METADATA_ERROR_INVALID_BLOB,
1433 "Invalid interface type name");
1434 return FALSE;
1437 if (!is_name (metadata->data, blob->gtype_init))
1439 g_set_error (error,
1440 G_METADATA_ERROR,
1441 G_METADATA_ERROR_INVALID_BLOB,
1442 "Invalid interface type init");
1443 return FALSE;
1446 if (!is_name (metadata->data, blob->name))
1448 g_set_error (error,
1449 G_METADATA_ERROR,
1450 G_METADATA_ERROR_INVALID_BLOB,
1451 "Invalid interface name");
1452 return FALSE;
1455 if (metadata->len < offset + sizeof (InterfaceBlob) +
1456 (blob->n_prerequisites + blob->n_prerequisites % 2) * 2 +
1457 blob->n_properties * sizeof (PropertyBlob) +
1458 blob->n_methods * sizeof (FunctionBlob) +
1459 blob->n_signals * sizeof (SignalBlob) +
1460 blob->n_vfuncs * sizeof (VFuncBlob) +
1461 blob->n_constants * sizeof (ConstantBlob))
1464 g_set_error (error,
1465 G_METADATA_ERROR,
1466 G_METADATA_ERROR_INVALID,
1467 "The buffer is too short");
1468 return FALSE;
1471 offset2 = offset + sizeof (InterfaceBlob);
1473 for (i = 0; i < blob->n_prerequisites; i++, offset2 += 2)
1475 DirEntry *entry;
1476 guint16 req;
1478 req = *(guint16*)&metadata->data[offset2];
1479 if (req == 0 || req > header->n_entries)
1481 g_set_error (error,
1482 G_METADATA_ERROR,
1483 G_METADATA_ERROR_INVALID_BLOB,
1484 "Invalid prerequisite index");
1485 return FALSE;
1488 entry = g_metadata_get_dir_entry (metadata, req);
1489 if (entry->blob_type != BLOB_TYPE_INTERFACE &&
1490 entry->blob_type != BLOB_TYPE_OBJECT &&
1491 (entry->local || entry->blob_type != 0))
1493 g_set_error (error,
1494 G_METADATA_ERROR,
1495 G_METADATA_ERROR_INVALID_BLOB,
1496 "Not an interface or object");
1497 return FALSE;
1501 offset2 += 2 * (blob->n_prerequisites % 2);
1503 for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob))
1505 if (!validate_property_blob (metadata, offset2, error))
1506 return FALSE;
1509 for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob))
1511 if (!validate_function_blob (metadata, offset2, BLOB_TYPE_INTERFACE, error))
1512 return FALSE;
1515 for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob))
1517 if (!validate_signal_blob (metadata, offset2, offset, error))
1518 return FALSE;
1521 for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob))
1523 if (!validate_vfunc_blob (metadata, offset2, offset, error))
1524 return FALSE;
1527 for (i = 0; i < blob->n_constants; i++, offset2 += sizeof (ConstantBlob))
1529 if (!validate_constant_blob (metadata, offset2, error))
1530 return FALSE;
1533 return TRUE;
1536 static gboolean
1537 validate_errordomain_blob (GMetadata *metadata,
1538 guint32 offset,
1539 GError **error)
1541 return TRUE;
1544 static gboolean
1545 validate_union_blob (GMetadata *metadata,
1546 guint32 offset,
1547 GError **error)
1549 return TRUE;
1552 static gboolean
1553 validate_blob (GMetadata *metadata,
1554 guint32 offset,
1555 GError **error)
1557 CommonBlob *common;
1559 if (metadata->len < offset + sizeof (CommonBlob))
1561 g_set_error (error,
1562 G_METADATA_ERROR,
1563 G_METADATA_ERROR_INVALID,
1564 "The buffer is too short");
1565 return FALSE;
1568 common = (CommonBlob*)&metadata->data[offset];
1570 switch (common->blob_type)
1572 case BLOB_TYPE_FUNCTION:
1573 if (!validate_function_blob (metadata, offset, 0, error))
1574 return FALSE;
1575 break;
1576 case BLOB_TYPE_CALLBACK:
1577 if (!validate_callback_blob (metadata, offset, error))
1578 return FALSE;
1579 break;
1580 case BLOB_TYPE_STRUCT:
1581 case BLOB_TYPE_BOXED:
1582 if (!validate_struct_blob (metadata, offset, common->blob_type, error))
1583 return FALSE;
1584 break;
1585 case BLOB_TYPE_ENUM:
1586 case BLOB_TYPE_FLAGS:
1587 if (!validate_enum_blob (metadata, offset, common->blob_type, error))
1588 return FALSE;
1589 break;
1590 case BLOB_TYPE_OBJECT:
1591 if (!validate_object_blob (metadata, offset, error))
1592 return FALSE;
1593 break;
1594 case BLOB_TYPE_INTERFACE:
1595 if (!validate_interface_blob (metadata, offset, error))
1596 return FALSE;
1597 break;
1598 case BLOB_TYPE_CONSTANT:
1599 if (!validate_constant_blob (metadata, offset, error))
1600 return FALSE;
1601 break;
1602 case BLOB_TYPE_ERROR_DOMAIN:
1603 if (!validate_errordomain_blob (metadata, offset, error))
1604 return FALSE;
1605 break;
1606 case BLOB_TYPE_UNION:
1607 if (!validate_union_blob (metadata, offset, error))
1608 return FALSE;
1609 break;
1610 default:
1611 g_set_error (error,
1612 G_METADATA_ERROR,
1613 G_METADATA_ERROR_INVALID_ENTRY,
1614 "Invalid blob type");
1615 return FALSE;
1618 return TRUE;
1621 static gboolean
1622 validate_directory (GMetadata *metadata,
1623 GError **error)
1625 Header *header = (Header *)metadata->data;
1626 DirEntry *entry;
1627 gint i;
1629 if (metadata->len < header->directory + header->n_entries * sizeof (DirEntry))
1631 g_set_error (error,
1632 G_METADATA_ERROR,
1633 G_METADATA_ERROR_INVALID,
1634 "The buffer is too short");
1635 return FALSE;
1638 for (i = 0; i < header->n_entries; i++)
1640 entry = g_metadata_get_dir_entry (metadata, i + 1);
1642 if (!is_name (metadata->data, entry->name))
1644 g_set_error (error,
1645 G_METADATA_ERROR,
1646 G_METADATA_ERROR_INVALID_DIRECTORY,
1647 "Invalid entry name");
1648 return FALSE;
1651 if ((entry->local && entry->blob_type == BLOB_TYPE_INVALID) ||
1652 entry->blob_type > BLOB_TYPE_UNION)
1654 g_set_error (error,
1655 G_METADATA_ERROR,
1656 G_METADATA_ERROR_INVALID_DIRECTORY,
1657 "Invalid entry type");
1658 return FALSE;
1661 if (i < header->n_local_entries)
1663 if (!entry->local)
1665 g_set_error (error,
1666 G_METADATA_ERROR,
1667 G_METADATA_ERROR_INVALID_DIRECTORY,
1668 "Too few local directory entries");
1669 return FALSE;
1672 if (!is_aligned (entry->offset))
1674 g_set_error (error,
1675 G_METADATA_ERROR,
1676 G_METADATA_ERROR_INVALID_DIRECTORY,
1677 "Misaligned entry");
1678 return FALSE;
1681 if (!validate_blob (metadata, entry->offset, error))
1682 return FALSE;
1684 else
1686 if (entry->local)
1688 g_set_error (error,
1689 G_METADATA_ERROR,
1690 G_METADATA_ERROR_INVALID_DIRECTORY,
1691 "Too many local directory entries");
1692 return FALSE;
1695 if (!is_name (metadata->data, entry->offset))
1697 g_set_error (error,
1698 G_METADATA_ERROR,
1699 G_METADATA_ERROR_INVALID_DIRECTORY,
1700 "Invalid namespace name");
1701 return FALSE;
1706 return TRUE;
1709 static gboolean
1710 validate_annotations (GMetadata *metadata,
1711 GError **error)
1713 Header *header = (Header *)metadata->data;
1715 if (header->size < header->annotations + header->n_annotations * sizeof (AnnotationBlob))
1717 g_set_error (error,
1718 G_METADATA_ERROR,
1719 G_METADATA_ERROR_INVALID,
1720 "The buffer is too short");
1721 return FALSE;
1724 return TRUE;
1727 gboolean
1728 g_metadata_validate (GMetadata *metadata,
1729 GError **error)
1731 if (!validate_header (metadata, error))
1732 return FALSE;
1734 if (!validate_directory (metadata, error))
1735 return FALSE;
1737 if (!validate_annotations (metadata, error))
1738 return FALSE;
1740 return TRUE;
1743 GQuark
1744 g_metadata_error_quark (void)
1746 static GQuark quark = 0;
1747 if (quark == 0)
1748 quark = g_quark_from_static_string ("g-metadata-error-quark");
1749 return quark;
1753 static inline void
1754 _g_metadata_init (GMetadata *metadata)
1756 Header *header;
1758 header = (Header *) metadata->data;
1759 if (header->shared_library)
1761 const gchar *shlib;
1762 shlib = g_metadata_get_string (metadata, header->shared_library);
1763 metadata->module = g_module_open (shlib, G_MODULE_BIND_LAZY|G_MODULE_BIND_LOCAL);
1764 if (metadata->module == NULL)
1765 g_warning ("Failed to load shared library referenced by the metadata: %s",
1766 g_module_error ());
1771 * g_metadata_new_from_memory:
1772 * @memory: address of memory chunk containing the metadata
1773 * @len: length of memory chunk containing the metadata
1775 * Creates a new #GMetadata from a memory location. The memory block
1776 * pointed to by @metadata will be automatically g_free()d when the
1777 * repository is destroyed.
1779 * Return value: the new #GMetadata
1781 GMetadata *
1782 g_metadata_new_from_memory (guchar *memory, gsize len)
1784 GMetadata *meta;
1786 meta = g_new0 (GMetadata, 1);
1787 meta->data = memory;
1788 meta->len = len;
1789 meta->owns_memory = TRUE;
1790 _g_metadata_init (meta);
1791 return meta;
1795 * g_metadata_new_from_const_memory:
1796 * @memory: address of memory chunk containing the metadata
1797 * @len: length of memory chunk containing the metadata
1799 * Creates a new #GMetadata from a memory location.
1801 * Return value: the new #GMetadata
1803 GMetadata *
1804 g_metadata_new_from_const_memory (const guchar *memory, gsize len)
1806 GMetadata *meta;
1808 meta = g_new0 (GMetadata, 1);
1809 meta->data = (guchar *) memory;
1810 meta->len = len;
1811 meta->owns_memory = FALSE;
1812 _g_metadata_init (meta);
1813 return meta;
1817 * g_metadata_new_from_mapped_file:
1818 * @mfile: a #GMappedFile, that will be free'd when the repository is destroyed
1820 * Creates a new #GMetadata from a #GMappedFile.
1822 * Return value: the new #GMetadata
1824 GMetadata *
1825 g_metadata_new_from_mapped_file (GMappedFile *mfile)
1827 GMetadata *meta;
1829 meta = g_new0 (GMetadata, 1);
1830 meta->mfile = mfile;
1831 meta->owns_memory = FALSE;
1832 meta->data = (guchar *) g_mapped_file_get_contents (mfile);
1833 meta->len = g_mapped_file_get_length (mfile);
1834 _g_metadata_init (meta);
1835 return meta;
1839 * g_metadata_free:
1840 * @metadata: a #GMetadata
1842 * Free a #GMetadata.
1844 void
1845 g_metadata_free (GMetadata *metadata)
1847 if (metadata->mfile)
1848 g_mapped_file_unref (metadata->mfile);
1849 else
1850 if (metadata->owns_memory)
1851 g_free (metadata->data);
1852 if (metadata->module)
1853 g_module_close (metadata->module);
1854 g_free (metadata);
1858 * g_metadata_set_module:
1859 * @metadata: a #GMetadata instance
1860 * @module: a #GModule; takes ownership of this module
1862 * Sets the target module for all symbols referenced by the metadata.
1864 void
1865 g_metadata_set_module (GMetadata *metadata, GModule *module)
1867 if (metadata->module)
1868 g_module_close (metadata->module);
1869 metadata->module = module;
1872 const gchar *
1873 g_metadata_get_namespace(GMetadata *metadata)
1875 return g_metadata_get_string (metadata, ((Header *) metadata->data)->namespace);