mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-16 12:28:48 +02:00
[girepository] Actually verify header of loaded typelibs in g_irepository_require
Take a GError * for typelib loading code, validate the header. This fixes bizarre errors from gjs where g_irepository_require would happily load old typelibs.
This commit is contained in:
parent
3a310fd242
commit
1b8bf7a4dc
@ -1221,7 +1221,9 @@ g_irepository_require (GIRepository *repository,
|
|||||||
goto out;
|
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;
|
header = (Header *) typelib->data;
|
||||||
typelib_namespace = g_typelib_get_string (typelib, header->namespace);
|
typelib_namespace = g_typelib_get_string (typelib, header->namespace);
|
||||||
typelib_version = g_typelib_get_string (typelib, header->nsversion);
|
typelib_version = g_typelib_get_string (typelib, header->nsversion);
|
||||||
|
@ -206,6 +206,7 @@ GTypelib *
|
|||||||
g_ir_module_build_typelib (GIrModule *module,
|
g_ir_module_build_typelib (GIrModule *module,
|
||||||
GList *modules)
|
GList *modules)
|
||||||
{
|
{
|
||||||
|
GError *error = NULL;
|
||||||
GTypelib *typelib;
|
GTypelib *typelib;
|
||||||
gsize length;
|
gsize length;
|
||||||
guint i;
|
guint i;
|
||||||
@ -434,7 +435,12 @@ g_ir_module_build_typelib (GIrModule *module,
|
|||||||
data = g_realloc (data, offset2);
|
data = g_realloc (data, offset2);
|
||||||
header = (Header*) data;
|
header = (Header*) data;
|
||||||
length = header->size = offset2;
|
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 (strings);
|
||||||
g_hash_table_destroy (types);
|
g_hash_table_destroy (types);
|
||||||
|
71
gitypelib.c
71
gitypelib.c
@ -260,30 +260,30 @@ validate_name (GTypelib *typelib,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fast path sanity check, operates on a memory blob */
|
||||||
static gboolean
|
static gboolean
|
||||||
validate_header (ValidateContext *ctx,
|
validate_header_basic (const guint8 *memory,
|
||||||
GError **error)
|
gsize len,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
GTypelib *typelib = ctx->typelib;
|
Header *header = (Header *)memory;
|
||||||
Header *header;
|
|
||||||
|
|
||||||
if (typelib->len < sizeof (Header))
|
if (len < sizeof (Header))
|
||||||
{
|
{
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
G_TYPELIB_ERROR,
|
G_TYPELIB_ERROR,
|
||||||
G_TYPELIB_ERROR_INVALID,
|
G_TYPELIB_ERROR_INVALID,
|
||||||
"The buffer is too short");
|
"The specified typelib length %" G_GSIZE_FORMAT " is too short",
|
||||||
|
len);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
header = (Header *)typelib->data;
|
|
||||||
|
|
||||||
if (strncmp (header->magic, G_IR_MAGIC, 16) != 0)
|
if (strncmp (header->magic, G_IR_MAGIC, 16) != 0)
|
||||||
{
|
{
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
G_TYPELIB_ERROR,
|
G_TYPELIB_ERROR,
|
||||||
G_TYPELIB_ERROR_INVALID_HEADER,
|
G_TYPELIB_ERROR_INVALID_HEADER,
|
||||||
"Magic string not found");
|
"Invalid magic header");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -293,7 +293,7 @@ validate_header (ValidateContext *ctx,
|
|||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
G_TYPELIB_ERROR,
|
G_TYPELIB_ERROR,
|
||||||
G_TYPELIB_ERROR_INVALID_HEADER,
|
G_TYPELIB_ERROR_INVALID_HEADER,
|
||||||
"Version mismatch; expected 3, found %d",
|
"Typelib version mismatch; expected 3, found %d",
|
||||||
header->major_version);
|
header->major_version);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@ -308,12 +308,13 @@ validate_header (ValidateContext *ctx,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (header->size != typelib->len)
|
if (header->size != len)
|
||||||
{
|
{
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
G_TYPELIB_ERROR,
|
G_TYPELIB_ERROR,
|
||||||
G_TYPELIB_ERROR_INVALID_HEADER,
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,9 +379,24 @@ validate_header (ValidateContext *ctx,
|
|||||||
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;
|
return FALSE;
|
||||||
|
|
||||||
|
{
|
||||||
|
Header *header = (Header*)typelib->data;
|
||||||
|
if (!validate_name (typelib, "namespace", typelib->data, header->namespace, error))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2056,6 +2072,7 @@ _g_typelib_ensure_open (GTypelib *typelib)
|
|||||||
* g_typelib_new_from_memory:
|
* g_typelib_new_from_memory:
|
||||||
* @memory: address of memory chunk containing the typelib
|
* @memory: address of memory chunk containing the typelib
|
||||||
* @len: length 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
|
* Creates a new #GTypelib from a memory location. The memory block
|
||||||
* pointed to by @typelib will be automatically g_free()d when the
|
* pointed to by @typelib will be automatically g_free()d when the
|
||||||
@ -2064,10 +2081,15 @@ _g_typelib_ensure_open (GTypelib *typelib)
|
|||||||
* Return value: the new #GTypelib
|
* Return value: the new #GTypelib
|
||||||
**/
|
**/
|
||||||
GTypelib *
|
GTypelib *
|
||||||
g_typelib_new_from_memory (guchar *memory, gsize len)
|
g_typelib_new_from_memory (guint8 *memory,
|
||||||
|
gsize len,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
GTypelib *meta;
|
GTypelib *meta;
|
||||||
|
|
||||||
|
if (!validate_header_basic (memory, len, error))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
meta = g_slice_new0 (GTypelib);
|
meta = g_slice_new0 (GTypelib);
|
||||||
meta->data = memory;
|
meta->data = memory;
|
||||||
meta->len = len;
|
meta->len = len;
|
||||||
@ -2081,16 +2103,22 @@ g_typelib_new_from_memory (guchar *memory, gsize len)
|
|||||||
* g_typelib_new_from_const_memory:
|
* g_typelib_new_from_const_memory:
|
||||||
* @memory: address of memory chunk containing the typelib
|
* @memory: address of memory chunk containing the typelib
|
||||||
* @len: length 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.
|
* Creates a new #GTypelib from a memory location.
|
||||||
*
|
*
|
||||||
* Return value: the new #GTypelib
|
* Return value: the new #GTypelib
|
||||||
**/
|
**/
|
||||||
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;
|
GTypelib *meta;
|
||||||
|
|
||||||
|
if (!validate_header_basic (memory, len, error))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
meta = g_slice_new0 (GTypelib);
|
meta = g_slice_new0 (GTypelib);
|
||||||
meta->data = (guchar *) memory;
|
meta->data = (guchar *) memory;
|
||||||
meta->len = len;
|
meta->len = len;
|
||||||
@ -2103,21 +2131,28 @@ g_typelib_new_from_const_memory (const guchar *memory, gsize len)
|
|||||||
/**
|
/**
|
||||||
* g_typelib_new_from_mapped_file:
|
* g_typelib_new_from_mapped_file:
|
||||||
* @mfile: a #GMappedFile, that will be free'd when the repository is destroyed
|
* @mfile: a #GMappedFile, that will be free'd when the repository is destroyed
|
||||||
|
* @error: a #GError
|
||||||
*
|
*
|
||||||
* Creates a new #GTypelib from a #GMappedFile.
|
* Creates a new #GTypelib from a #GMappedFile.
|
||||||
*
|
*
|
||||||
* Return value: the new #GTypelib
|
* Return value: the new #GTypelib
|
||||||
**/
|
**/
|
||||||
GTypelib *
|
GTypelib *
|
||||||
g_typelib_new_from_mapped_file (GMappedFile *mfile)
|
g_typelib_new_from_mapped_file (GMappedFile *mfile,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
GTypelib *meta;
|
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 = g_slice_new0 (GTypelib);
|
||||||
meta->mfile = mfile;
|
meta->mfile = mfile;
|
||||||
meta->owns_memory = FALSE;
|
meta->owns_memory = FALSE;
|
||||||
meta->data = (guchar *) g_mapped_file_get_contents (mfile);
|
meta->data = data;
|
||||||
meta->len = g_mapped_file_get_length (mfile);
|
meta->len = len;
|
||||||
|
|
||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
13
gitypelib.h
13
gitypelib.h
@ -34,11 +34,14 @@ G_BEGIN_DECLS
|
|||||||
|
|
||||||
typedef struct _GTypelib GTypelib;
|
typedef struct _GTypelib GTypelib;
|
||||||
|
|
||||||
GTypelib * g_typelib_new_from_memory (guchar *memory,
|
GTypelib * g_typelib_new_from_memory (guint8 *memory,
|
||||||
gsize len);
|
gsize len,
|
||||||
GTypelib * g_typelib_new_from_const_memory (const guchar *memory,
|
GError **error);
|
||||||
gsize len);
|
GTypelib * g_typelib_new_from_const_memory (const guint8 *memory,
|
||||||
GTypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile);
|
gsize len,
|
||||||
|
GError **error);
|
||||||
|
GTypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile,
|
||||||
|
GError **error);
|
||||||
void g_typelib_free (GTypelib *typelib);
|
void g_typelib_free (GTypelib *typelib);
|
||||||
|
|
||||||
gboolean g_typelib_symbol (GTypelib *typelib,
|
gboolean g_typelib_symbol (GTypelib *typelib,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user