summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2008-08-21 16:15:55 +0000
committerColin Walters <walters@src.gnome.org>2008-08-21 16:15:55 +0000
commit59df1dd48957bd494306d2a33a1a46d84895303f (patch)
tree49a55ce7666079896ca688a04cd82acdcf5634d9
parent851faec61462ecbc5a131fbbd75cba487e9953b2 (diff)
downloadgobject-introspection-59df1dd48957bd494306d2a33a1a46d84895303f.tar.gz
Tweak to use UINT instead of INT. Not likely to matter. Add to
2008-08-21 Colin Walters <walters@verbum.org> * girepository/girnode.c (write_string): Tweak to use UINT instead of INT. Not likely to matter. * girepository/girmodule.c (g_ir_module_build_typelib): Add to header_offset as well for header strings to match what write_string does. * girepository/gtypelib.c: Replace is_name with validate_name, which more strongly validates and handles errors in a better way. Update all callers. * giscanner/glibtransformer.py: Handle constructors better. svn path=/trunk/; revision=439
-rw-r--r--ChangeLog13
-rw-r--r--girepository/girmodule.c8
-rw-r--r--girepository/girnode.c4
-rw-r--r--girepository/gtypelib.c289
-rw-r--r--giscanner/glibtransformer.py50
5 files changed, 141 insertions, 223 deletions
diff --git a/ChangeLog b/ChangeLog
index 1bfd07c1..2ffb657b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2008-08-21 Colin Walters <walters@verbum.org>
+
+ * girepository/girnode.c (write_string): Tweak to
+ use UINT instead of INT. Not likely to matter.
+ * girepository/girmodule.c (g_ir_module_build_typelib):
+ Add to header_offset as well for header strings
+ to match what write_string does.
+ * girepository/gtypelib.c: Replace is_name with
+ validate_name, which more strongly validates and
+ handles errors in a better way. Update all callers.
+ * giscanner/glibtransformer.py: Handle constructors
+ better.
+
2008-08-21 Johan Dahlin <johan@gnome.org>
* gir/Makefile.am (typelibs_DATA): Build and
diff --git a/girepository/girmodule.c b/girepository/girmodule.c
index 1ffbf9ba..1fcdadbc 100644
--- a/girepository/girmodule.c
+++ b/girepository/girmodule.c
@@ -104,8 +104,12 @@ g_ir_module_build_typelib (GIrModule *module,
/* Adjust size for strings allocated in header below specially */
size += strlen (module->name);
- if (module->shared_library)
- size += strlen (module->shared_library);
+ header_size = ALIGN_VALUE (header_size + strlen (module->name) + 1, 4);
+ if (module->shared_library)
+ {
+ size += strlen (module->shared_library);
+ header_size = ALIGN_VALUE (header_size + strlen (module->shared_library) + 1, 4);
+ }
g_message ("allocating %d bytes (%d header, %d directory, %d entries)\n",
size, header_size, dir_size, size - header_size - dir_size);
diff --git a/girepository/girnode.c b/girepository/girnode.c
index 6fb32aa4..06e1b8e7 100644
--- a/girepository/girnode.c
+++ b/girepository/girnode.c
@@ -2144,12 +2144,12 @@ write_string (const gchar *str,
value = g_hash_table_lookup (strings, str);
if (value)
- return GPOINTER_TO_INT (value);
+ return GPOINTER_TO_UINT (value);
unique_string_count += 1;
unique_string_size += strlen (str);
- g_hash_table_insert (strings, (gpointer)str, GINT_TO_POINTER (*offset));
+ g_hash_table_insert (strings, (gpointer)str, GUINT_TO_POINTER (*offset));
start = *offset;
*offset = ALIGN_VALUE (start + strlen (str) + 1, 4);
diff --git a/girepository/gtypelib.c b/girepository/gtypelib.c
index 6e04f652..53684fdb 100644
--- a/girepository/gtypelib.c
+++ b/girepository/gtypelib.c
@@ -81,17 +81,44 @@ is_aligned (guint32 offset)
#define MAX_NAME_LEN 200
static gboolean
-is_name (const guchar *data, guint32 offset)
+validate_name (GTypelib *typelib,
+ const char *msg,
+ const guchar *data, 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;
+ }
+
name = (gchar*)&data[offset];
- if (!memchr (name, '\0', MAX_NAME_LEN))
- return FALSE;
+ if (!memchr (name, '\0', MAX_NAME_LEN))
+ {
+ g_set_error (error,
+ G_TYPELIB_ERROR,
+ G_TYPELIB_ERROR_INVALID,
+ "The %s is too long: %s",
+ msg, name);
+ return FALSE;
+ }
- if (strspn (name, G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_") < strlen (name))
- return FALSE;
+ if (strspn (name, G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_") < strlen (name))
+ {
+ g_set_error (error,
+ G_TYPELIB_ERROR,
+ G_TYPELIB_ERROR_INVALID,
+ "The %s is contains invalid characters: %s",
+ msg, name);
+ return FALSE;
+ }
return TRUE;
}
@@ -204,14 +231,8 @@ validate_header (GTypelib *typelib,
return FALSE;
}
- if (!is_name (typelib->data, header->namespace))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_HEADER,
- "Invalid namespace name");
- return FALSE;
- }
+ if (!validate_name (typelib, "namespace", typelib->data, header->namespace, error))
+ return FALSE;
return TRUE;
}
@@ -470,14 +491,8 @@ validate_arg_blob (GTypelib *typelib,
blob = (ArgBlob*) &typelib->data[offset];
- if (!is_name (typelib->data, blob->name))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid argument name");
- return FALSE;
- }
+ if (!validate_name (typelib, "argument", typelib->data, blob->name, error))
+ return FALSE;
if (!validate_type_blob (typelib,
offset + G_STRUCT_OFFSET (ArgBlob, arg_type),
@@ -557,23 +572,11 @@ validate_function_blob (GTypelib *typelib,
return FALSE;
}
- if (!is_name (typelib->data, blob->name))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid function name");
- return FALSE;
- }
+ if (!validate_name (typelib, "function", typelib->data, blob->name, error))
+ return FALSE;
- if (!is_name (typelib->data, blob->symbol))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid function symbol");
- return FALSE;
- }
+ if (!validate_name (typelib, "function symbol", typelib->data, blob->symbol, error))
+ return FALSE;
if (blob->constructor)
{
@@ -657,14 +660,8 @@ validate_callback_blob (GTypelib *typelib,
return FALSE;
}
- if (!is_name (typelib->data, blob->name))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid callback name");
- return FALSE;
- }
+ if (!validate_name (typelib, "callback", typelib->data, blob->name, error))
+ return FALSE;
if (!validate_signature_blob (typelib, blob->signature, error))
return FALSE;
@@ -708,14 +705,8 @@ validate_constant_blob (GTypelib *typelib,
return FALSE;
}
- if (!is_name (typelib->data, blob->name))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid constant name");
- return FALSE;
- }
+ if (!validate_name (typelib, "constant", typelib->data, blob->name, error))
+ return FALSE;
if (!validate_type_blob (typelib, offset + G_STRUCT_OFFSET (ConstantBlob, type),
0, FALSE, error))
@@ -775,14 +766,8 @@ validate_value_blob (GTypelib *typelib,
blob = (ValueBlob*) &typelib->data[offset];
- if (!is_name (typelib->data, blob->name))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid value name");
- return FALSE;
- }
+ if (!validate_name (typelib, "value", typelib->data, blob->name, error))
+ return FALSE;
return TRUE;
}
@@ -805,15 +790,9 @@ validate_field_blob (GTypelib *typelib,
blob = (FieldBlob*) &typelib->data[offset];
- if (!is_name (typelib->data, blob->name))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid field name");
- return FALSE;
- }
-
+ if (!validate_name (typelib, "field", typelib->data, blob->name, error))
+ return FALSE;
+
if (!validate_type_blob (typelib,
offset + G_STRUCT_OFFSET (FieldBlob, type),
0, FALSE, error))
@@ -840,14 +819,8 @@ validate_property_blob (GTypelib *typelib,
blob = (PropertyBlob*) &typelib->data[offset];
- if (!is_name (typelib->data, blob->name))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid property name");
- return FALSE;
- }
+ if (!validate_name (typelib, "property", typelib->data, blob->name, error))
+ return FALSE;
if (!validate_type_blob (typelib,
offset + G_STRUCT_OFFSET (PropertyBlob, type),
@@ -877,14 +850,8 @@ validate_signal_blob (GTypelib *typelib,
blob = (SignalBlob*) &typelib->data[offset];
- if (!is_name (typelib->data, blob->name))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid signal name");
- return FALSE;
- }
+ if (!validate_name (typelib, "signal", typelib->data, blob->name, error))
+ return FALSE;
if ((blob->run_first != 0) +
(blob->run_last != 0) +
@@ -952,14 +919,8 @@ validate_vfunc_blob (GTypelib *typelib,
blob = (VFuncBlob*) &typelib->data[offset];
- if (!is_name (typelib->data, blob->name))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid vfunc name");
- return FALSE;
- }
+ if (!validate_name (typelib, "vfunc", typelib->data, blob->name, error))
+ return FALSE;
if (blob->class_closure)
{
@@ -1035,34 +996,16 @@ validate_struct_blob (GTypelib *typelib,
return FALSE;
}
- if (!is_name (typelib->data, blob->name))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid struct name");
- return FALSE;
- }
+ if (!validate_name (typelib, "struct", typelib->data, blob->name, error))
+ return FALSE;
if (blob_type == BLOB_TYPE_BOXED)
{
- if (!is_name (typelib->data, blob->gtype_name))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid boxed type name");
- return FALSE;
- }
+ if (!validate_name (typelib, "boxed", typelib->data, blob->gtype_name, error))
+ return FALSE;
- if (!is_name (typelib->data, blob->gtype_init))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid boxed type init");
- return FALSE;
- }
+ if (!validate_name (typelib, "boxed", typelib->data, blob->gtype_init, error))
+ return FALSE;
}
else
{
@@ -1142,23 +1085,11 @@ validate_enum_blob (GTypelib *typelib,
if (!blob->unregistered)
{
- if (!is_name (typelib->data, blob->gtype_name))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid enum type name");
- return FALSE;
- }
+ if (!validate_name (typelib, "enum", typelib->data, blob->gtype_name, error))
+ return FALSE;
- if (!is_name (typelib->data, blob->gtype_init))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid enum type init");
- return FALSE;
- }
+ if (!validate_name (typelib, "enum", typelib->data, blob->gtype_init, error))
+ return FALSE;
}
else
{
@@ -1172,14 +1103,8 @@ validate_enum_blob (GTypelib *typelib,
}
}
- if (!is_name (typelib->data, blob->name))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid enum name");
- return FALSE;
- }
+ if (!validate_name (typelib, "enum", typelib->data, blob->name, error))
+ return FALSE;
if (typelib->len < offset + sizeof (EnumBlob) +
blob->n_values * sizeof (ValueBlob))
@@ -1256,32 +1181,14 @@ validate_object_blob (GTypelib *typelib,
return FALSE;
}
- if (!is_name (typelib->data, blob->gtype_name))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid object type name");
- return FALSE;
- }
+ if (!validate_name (typelib, "object", typelib->data, blob->gtype_name, error))
+ return FALSE;
- if (!is_name (typelib->data, blob->gtype_init))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid object type init");
- return FALSE;
- }
+ if (!validate_name (typelib, "object", typelib->data, blob->gtype_init, error))
+ return FALSE;
- if (!is_name (typelib->data, blob->name))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid object name");
- return FALSE;
- }
+ if (!validate_name (typelib, "object", typelib->data, blob->name, error))
+ return FALSE;
if (blob->parent > header->n_entries)
{
@@ -1428,32 +1335,14 @@ validate_interface_blob (GTypelib *typelib,
return FALSE;
}
- if (!is_name (typelib->data, blob->gtype_name))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid interface type name");
- return FALSE;
- }
+ if (!validate_name (typelib, "interface", typelib->data, blob->gtype_name, error))
+ return FALSE;
- if (!is_name (typelib->data, blob->gtype_init))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid interface type init");
- return FALSE;
- }
+ if (!validate_name (typelib, "interface", typelib->data, blob->gtype_init, error))
+ return FALSE;
- if (!is_name (typelib->data, blob->name))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_BLOB,
- "Invalid interface name");
- return FALSE;
- }
+ if (!validate_name (typelib, "interface", typelib->data, blob->name, error))
+ return FALSE;
if (typelib->len < offset + sizeof (InterfaceBlob) +
(blob->n_prerequisites + blob->n_prerequisites % 2) * 2 +
@@ -1642,14 +1531,8 @@ validate_directory (GTypelib *typelib,
{
entry = g_typelib_get_dir_entry (typelib, i + 1);
- if (!is_name (typelib->data, entry->name))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_DIRECTORY,
- "Invalid entry name");
- return FALSE;
- }
+ if (!validate_name (typelib, "entry", typelib->data, entry->name, error))
+ return FALSE;
if ((entry->local && entry->blob_type == BLOB_TYPE_INVALID) ||
entry->blob_type > BLOB_TYPE_UNION)
@@ -1695,14 +1578,8 @@ validate_directory (GTypelib *typelib,
return FALSE;
}
- if (!is_name (typelib->data, entry->offset))
- {
- g_set_error (error,
- G_TYPELIB_ERROR,
- G_TYPELIB_ERROR_INVALID_DIRECTORY,
- "Invalid namespace name");
- return FALSE;
- }
+ if (!validate_name (typelib, "namespace", typelib->data, entry->offset, error))
+ return FALSE;
}
}
diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py
index 6e3e7cc3..007b0054 100644
--- a/giscanner/glibtransformer.py
+++ b/giscanner/glibtransformer.py
@@ -178,10 +178,6 @@ class GLibTransformer(object):
def _parse_function(self, func):
if self._parse_get_type_function(func):
return
- elif self._parse_constructor(func):
- return
- elif self._parse_method(func):
- return
self._add_attribute(func)
@@ -245,25 +241,41 @@ class GLibTransformer(object):
target_arg = func.retval
else:
target_arg = func.parameters[0]
+ target_arg.type = self._resolve_param_type(target_arg.type)
+
klass = self._get_attribute(target_arg.type.name)
- if klass is None or not isinstance(klass, (GLibObject, GLibBoxed)):
- return False
+ if klass is None or not isinstance(klass, (GLibObject, GLibBoxed,
+ GLibInterface)):
+ return None
- # Look at the original C type (before namespace stripping), without
- # pointers: GtkButton -> gtk_button_, so we can figure out the
- # method name
orig_type = target_arg.type.ctype.replace('*', '')
prefix = to_underscores(orig_type).lower() + '_'
- if not func.symbol.startswith(prefix):
- return False
+ if not is_method:
+ # Interfaces can't have constructors, punt to global scope
+ # Constructors must have _new
+ new_idx = func.symbol.find('_new')
+ if (isinstance(klass, GLibInterface) or
+ new_idx < 0):
+ return None
+ # Just strip everything before _new
+ prefix = func.symbol[:new_idx+1]
+ # TODO - check that the return type is a subclass of the
+ # class from the prefix
+ else:
+ # Look at the original C type (before namespace stripping), without
+ # pointers: GtkButton -> gtk_button_, so we can figure out the
+ # method name
+ if not func.symbol.startswith(prefix):
+ return None
+ self._remove_attribute(func.name)
# Strip namespace and object prefix: gtk_window_new -> new
func.name = func.symbol[len(prefix):]
if is_method:
klass.methods.append(func)
else:
klass.constructors.append(func)
- return True
+ return func
def _parse_struct(self, struct):
# This is a hack, but GObject is a rather fundamental piece so.
@@ -496,7 +508,10 @@ class GLibTransformer(object):
return ptype
def _resolve_node(self, node):
- if isinstance(node, (Callback, Function)):
+ if isinstance(node, Function):
+ self._resolve_function_toplevel(node)
+
+ elif isinstance(node, Callback):
self._resolve_function(node)
elif isinstance(node, GLibObject):
self._resolve_glib_object(node)
@@ -511,6 +526,15 @@ class GLibTransformer(object):
elif isinstance(node, Alias):
self._resolve_alias(node)
+ def _resolve_function_toplevel(self, func):
+ newfunc = self._parse_constructor(func)
+ if not newfunc:
+ newfunc = self._parse_method(func)
+ if not newfunc:
+ self._resolve_function(func)
+ return
+ self._resolve_function(newfunc)
+
def _resolve_struct(self, node):
for field in node.fields:
self._resolve_field(field)