gobject-introspection r477 - trunk/girepository
- From: walters svn gnome org
- To: svn-commits-list gnome org
- Subject: gobject-introspection r477 - trunk/girepository
- Date: Sat, 23 Aug 2008 21:30:09 +0000 (UTC)
Author: walters
Date: Sat Aug 23 21:30:09 2008
New Revision: 477
URL: http://svn.gnome.org/viewvc/gobject-introspection?rev=477&view=rev
Log:
Check constructor returns
Modified:
trunk/girepository/gtypelib.c
Modified: trunk/girepository/gtypelib.c
==============================================================================
--- trunk/girepository/gtypelib.c (original)
+++ trunk/girepository/gtypelib.c Sat Aug 23 21:30:09 2008
@@ -30,6 +30,46 @@
#define ALIGN_VALUE(this, boundary) \
(( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
+static gboolean
+validate_interface_blob (GTypelib *typelib,
+ guint32 offset,
+ GError **error);
+
+static InterfaceTypeBlob *
+get_type_blob (GTypelib *typelib,
+ const char *funcname,
+ SimpleTypeBlob *simple,
+ GError **error)
+{
+ if (simple->offset == 0)
+ {
+ g_set_error (error,
+ G_TYPELIB_ERROR,
+ G_TYPELIB_ERROR_INVALID,
+ "Expected blob for type");
+ return FALSE;
+ }
+
+ if (simple->reserved == 0 && simple->reserved2 == 0)
+ {
+ g_set_error (error,
+ G_TYPELIB_ERROR,
+ G_TYPELIB_ERROR_INVALID,
+ "Expected non-basic type in function %s, got %d", funcname,
+ simple->tag);
+ return FALSE;
+ }
+
+ if (typelib->len < simple->offset + sizeof (CommonBlob))
+ {
+ g_set_error (error,
+ G_TYPELIB_ERROR,
+ G_TYPELIB_ERROR_INVALID,
+ "The buffer is too short");
+ return FALSE;
+ }
+ return (InterfaceTypeBlob*) &typelib->data[simple->offset];
+}
DirEntry *
g_typelib_get_dir_entry (GTypelib *typelib,
@@ -80,26 +120,41 @@
#define MAX_NAME_LEN 200
-static gboolean
-validate_name (GTypelib *typelib,
- const char *msg,
- const guchar *data, guint32 offset,
- GError **error)
+static const char *
+get_string (GTypelib *typelib, guint32 offset, GError **error)
{
- gchar *name;
-
if (typelib->len < offset)
{
g_set_error (error,
G_TYPELIB_ERROR,
G_TYPELIB_ERROR_INVALID,
- "The buffer is too short for type %s",
- msg);
- return FALSE;
+ "Buffer is too short while looking up name");
+ return NULL;
}
- name = (gchar*)&data[offset];
-
+ return (const char*)&typelib->data[offset];
+}
+
+static const char *
+get_string_nofail (GTypelib *typelib, guint32 offset)
+{
+ const char *ret = get_string (typelib, offset, NULL);
+ g_assert (ret);
+ return ret;
+}
+
+static gboolean
+validate_name (GTypelib *typelib,
+ const char *msg,
+ const guchar *data, guint32 offset,
+ GError **error)
+{
+ const char *name;
+
+ name = get_string (typelib, offset, error);
+ if (!name)
+ return FALSE;
+
if (!memchr (name, '\0', MAX_NAME_LEN))
{
g_set_error (error,
@@ -502,6 +557,34 @@
return TRUE;
}
+static SimpleTypeBlob *
+return_type_from_signature (GTypelib *typelib,
+ guint32 offset,
+ GError **error)
+{
+ SignatureBlob *blob;
+ if (typelib->len < offset + sizeof (SignatureBlob))
+ {
+ g_set_error (error,
+ G_TYPELIB_ERROR,
+ G_TYPELIB_ERROR_INVALID,
+ "The buffer is too short");
+ return NULL;
+ }
+
+ blob = (SignatureBlob*) &typelib->data[offset];
+ if (blob->return_type.offset == 0)
+ {
+ g_set_error (error,
+ G_TYPELIB_ERROR,
+ G_TYPELIB_ERROR_INVALID,
+ "No return type found in signature");
+ return NULL;
+ }
+
+ return (SimpleTypeBlob *)&typelib->data[offset + G_STRUCT_OFFSET (SignatureBlob, return_type)];
+}
+
static gboolean
validate_signature_blob (GTypelib *typelib,
guint32 offset,
@@ -551,6 +634,8 @@
GError **error)
{
FunctionBlob *blob;
+ SignatureBlob *sigblob;
+ const char *funcname;
if (typelib->len < offset + sizeof (FunctionBlob))
{
@@ -574,6 +659,8 @@
if (!validate_name (typelib, "function", typelib->data, blob->name, error))
return FALSE;
+
+ funcname = get_string_nofail (typelib, blob->name);
if (!validate_name (typelib, "function symbol", typelib->data, blob->symbol, error))
return FALSE;
@@ -590,7 +677,7 @@
g_set_error (error,
G_TYPELIB_ERROR,
G_TYPELIB_ERROR_INVALID_BLOB,
- "Constructor not allowed");
+ "Constructor %s not allowed", funcname);
return FALSE;
}
}
@@ -625,10 +712,33 @@
/* FIXME: validate index range */
/* FIXME: validate "this" argument for methods */
- /* FIXME: validate return type for constructors */
if (!validate_signature_blob (typelib, blob->signature, error))
return FALSE;
+
+ sigblob = (SignatureBlob*) &typelib->data[blob->signature];
+
+ if (blob->constructor)
+ {
+ SimpleTypeBlob *simple = return_type_from_signature (typelib,
+ blob->signature,
+ error);
+ InterfaceTypeBlob *iface;
+ if (!simple)
+ return FALSE;
+ iface = get_type_blob (typelib, funcname, simple, error);
+ if (!iface)
+ return FALSE;
+ if (!(iface->tag == GI_TYPE_TAG_INTERFACE))
+ {
+ g_set_error (error,
+ G_TYPELIB_ERROR,
+ G_TYPELIB_ERROR_INVALID,
+ "Invalid return type %d for constructor %s",
+ iface->tag, funcname);
+ return FALSE;
+ }
+ }
return TRUE;
}
@@ -1331,7 +1441,7 @@
g_set_error (error,
G_TYPELIB_ERROR,
G_TYPELIB_ERROR_INVALID_BLOB,
- "Wrong blob type");
+ "Wrong blob type; expected interface, got %d", blob->blob_type);
return FALSE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]