goto out;
}
- typelib = g_typelib_new_from_mapped_file (mfile);
+ typelib = g_typelib_new_from_mapped_file (mfile, error);
+ if (!typelib)
+ goto out;
header = (Header *) typelib->data;
typelib_namespace = g_typelib_get_string (typelib, header->namespace);
typelib_version = g_typelib_get_string (typelib, header->nsversion);
g_ir_module_build_typelib (GIrModule *module,
GList *modules)
{
+ GError *error = NULL;
GTypelib *typelib;
gsize length;
guint i;
data = g_realloc (data, offset2);
header = (Header*) data;
length = header->size = offset2;
- typelib = g_typelib_new_from_memory (data, length);
+ typelib = g_typelib_new_from_memory (data, length, &error);
+ if (!typelib)
+ {
+ g_error ("error building typelib: %s",
+ error->message);
+ }
g_hash_table_destroy (strings);
g_hash_table_destroy (types);
return TRUE;
}
+/* Fast path sanity check, operates on a memory blob */
static gboolean
-validate_header (ValidateContext *ctx,
- GError **error)
+validate_header_basic (const guint8 *memory,
+ gsize len,
+ GError **error)
{
- GTypelib *typelib = ctx->typelib;
- Header *header;
+ Header *header = (Header *)memory;
- if (typelib->len < sizeof (Header))
+ if (len < sizeof (Header))
{
g_set_error (error,
G_TYPELIB_ERROR,
G_TYPELIB_ERROR_INVALID,
- "The buffer is too short");
+ "The specified typelib length %" G_GSIZE_FORMAT " is too short",
+ len);
return FALSE;
}
- header = (Header *)typelib->data;
-
if (strncmp (header->magic, G_IR_MAGIC, 16) != 0)
{
g_set_error (error,
G_TYPELIB_ERROR,
G_TYPELIB_ERROR_INVALID_HEADER,
- "Magic string not found");
+ "Invalid magic header");
return FALSE;
}
g_set_error (error,
G_TYPELIB_ERROR,
G_TYPELIB_ERROR_INVALID_HEADER,
- "Version mismatch; expected 3, found %d",
+ "Typelib version mismatch; expected 3, found %d",
header->major_version);
return FALSE;
return FALSE;
}
- if (header->size != typelib->len)
+ if (header->size != len)
{
g_set_error (error,
G_TYPELIB_ERROR,
G_TYPELIB_ERROR_INVALID_HEADER,
- "Typelib size mismatch");
+ "Typelib size %" G_GSIZE_FORMAT " does not match %" G_GSIZE_FORMAT,
+ header->size, len);
return FALSE;
}
return FALSE;
}
- if (!validate_name (typelib, "namespace", typelib->data, header->namespace, error))
+ return TRUE;
+}
+
+static gboolean
+validate_header (ValidateContext *ctx,
+ GError **error)
+{
+ GTypelib *typelib = ctx->typelib;
+
+ if (!validate_header_basic (typelib->data, typelib->len, error))
return FALSE;
+ {
+ Header *header = (Header*)typelib->data;
+ if (!validate_name (typelib, "namespace", typelib->data, header->namespace, error))
+ return FALSE;
+ }
+
return TRUE;
}
* g_typelib_new_from_memory:
* @memory: address of memory chunk containing the typelib
* @len: length of memory chunk containing the typelib
+ * @error: a #GError
*
* Creates a new #GTypelib from a memory location. The memory block
* pointed to by @typelib will be automatically g_free()d when the
* Return value: the new #GTypelib
**/
GTypelib *
-g_typelib_new_from_memory (guchar *memory, gsize len)
+g_typelib_new_from_memory (guint8 *memory,
+ gsize len,
+ GError **error)
{
GTypelib *meta;
+ if (!validate_header_basic (memory, len, error))
+ return NULL;
+
meta = g_slice_new0 (GTypelib);
meta->data = memory;
meta->len = len;
* g_typelib_new_from_const_memory:
* @memory: address of memory chunk containing the typelib
* @len: length of memory chunk containing the typelib
+ * @error: A #GError
*
* Creates a new #GTypelib from a memory location.
*
* Return value: the new #GTypelib
**/
GTypelib *
-g_typelib_new_from_const_memory (const guchar *memory, gsize len)
+g_typelib_new_from_const_memory (const guchar *memory,
+ gsize len,
+ GError **error)
{
GTypelib *meta;
+ if (!validate_header_basic (memory, len, error))
+ return NULL;
+
meta = g_slice_new0 (GTypelib);
meta->data = (guchar *) memory;
meta->len = len;
/**
* g_typelib_new_from_mapped_file:
* @mfile: a #GMappedFile, that will be free'd when the repository is destroyed
+ * @error: a #GError
*
* Creates a new #GTypelib from a #GMappedFile.
*
* Return value: the new #GTypelib
**/
GTypelib *
-g_typelib_new_from_mapped_file (GMappedFile *mfile)
+g_typelib_new_from_mapped_file (GMappedFile *mfile,
+ GError **error)
{
GTypelib *meta;
+ guint8 *data = (guint8 *) g_mapped_file_get_contents (mfile);
+ gsize len = g_mapped_file_get_length (mfile);
+
+ if (!validate_header_basic (data, len, error))
+ return NULL;
meta = g_slice_new0 (GTypelib);
meta->mfile = mfile;
meta->owns_memory = FALSE;
- meta->data = (guchar *) g_mapped_file_get_contents (mfile);
- meta->len = g_mapped_file_get_length (mfile);
+ meta->data = data;
+ meta->len = len;
return meta;
}
typedef struct _GTypelib GTypelib;
-GTypelib * g_typelib_new_from_memory (guchar *memory,
- gsize len);
-GTypelib * g_typelib_new_from_const_memory (const guchar *memory,
- gsize len);
-GTypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile);
+GTypelib * g_typelib_new_from_memory (guint8 *memory,
+ gsize len,
+ GError **error);
+GTypelib * g_typelib_new_from_const_memory (const guint8 *memory,
+ gsize len,
+ GError **error);
+GTypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile,
+ GError **error);
void g_typelib_free (GTypelib *typelib);
gboolean g_typelib_symbol (GTypelib *typelib,
result = g_string_sized_new (6 * typelib->len);
+ g_string_append_printf (result, "/* GENERATED CODE - DO NOT EDIT */\n");
g_string_append_printf (result, "#include <stdlib.h>\n");
g_string_append_printf (result, "#include <girepository.h>\n\n");
"register_typelib (void)\n"
"{\n"
"\tGTypelib *typelib;\n"
- "\ttypelib = g_typelib_new_from_const_memory (_G_TYPELIB, _G_TYPELIB_SIZE);\n"
+ "\ttypelib = g_typelib_new_from_const_memory (_G_TYPELIB, _G_TYPELIB_SIZE, NULL);\n"
+ "\tg_assert (typelib != NULL);\n"
"\tg_irepository_load_typelib (NULL, typelib, G_IREPOSITORY_LOAD_FLAG_LAZY, NULL);\n"
"}\n\n");
}
#include "girepository.h"
#include "gitypelib-internal.h"
-static const guchar *
-load_typelib (const gchar *filename,
- GModule **dlhandle,
- gsize *len)
-{
- guchar *typelib;
- gsize *typelib_size;
- GModule *handle;
-
- handle = g_module_open (filename, G_MODULE_BIND_LOCAL|G_MODULE_BIND_LAZY);
- if (handle == NULL)
- {
- g_printerr ("Could not load typelib from '%s': %s\n",
- filename, g_module_error ());
- return NULL;
- }
-
- if (!g_module_symbol (handle, "_G_TYPELIB", (gpointer *) &typelib))
- {
- g_printerr ("Could not load typelib from '%s': %s\n",
- filename, g_module_error ());
- return NULL;
- }
-
- if (!g_module_symbol (handle, "_G_TYPELIB_SIZE", (gpointer *) &typelib_size))
- {
- g_printerr ("Could not load typelib from '%s': %s\n",
- filename, g_module_error ());
- return NULL;
- }
-
- *len = *typelib_size;
-
- if (dlhandle)
- *dlhandle = handle;
-
- return typelib;
-}
-
int
main (int argc, char *argv[])
{
for (i = 0; input[i]; i++)
{
- GModule *dlhandle = NULL;
- const guchar *typelib;
- gsize len;
+ GError *error = NULL;
const char *namespace;
+ GMappedFile *mfile;
+ GTypelib *typelib;
- if (!shlib)
- {
- if (!g_file_get_contents (input[i], (gchar **)&typelib, &len, &error))
- {
- g_fprintf (stderr, "failed to read '%s': %s\n",
- input[i], error->message);
- g_clear_error (&error);
- continue;
- }
- }
- else
- {
- typelib = load_typelib (input[i], &dlhandle, &len);
- if (!typelib)
- {
- g_fprintf (stderr, "failed to load typelib from '%s'\n",
- input[i]);
- continue;
- }
- }
+ mfile = g_mapped_file_new (input[i], FALSE, &error);
+ if (!mfile)
+ g_error ("failed to read '%s': %s", input[i], error->message);
if (input[i + 1] && output)
needs_prefix = TRUE;
else
needs_prefix = FALSE;
- data = g_typelib_new_from_const_memory (typelib, len);
- {
- GError *error = NULL;
- if (!g_typelib_validate (data, &error)) {
- g_printerr ("typelib not valid: %s\n", error->message);
- g_clear_error (&error);
- return 1;
- }
- }
- namespace = g_irepository_load_typelib (g_irepository_get_default (), data, 0,
+ typelib = g_typelib_new_from_mapped_file (mfile, &error);
+ if (!typelib)
+ g_error ("failed to create typelib '%s': %s", input[i], error->message);
+
+ namespace = g_irepository_load_typelib (g_irepository_get_default (), typelib, 0,
&error);
if (namespace == NULL)
- {
- g_printerr ("failed to load typelib: %s\n", error->message);
- return 1;
- }
-
+ g_error ("failed to load typelib: %s", error->message);
+
gir_writer_write (output, namespace, needs_prefix, show_all);
- if (dlhandle)
- {
- g_module_close (dlhandle);
- dlhandle = NULL;
- }
-
/* when writing to stdout, stop after the first module */
if (input[i + 1] && !output)
{