diff options
author | Colin Walters <walters@verbum.org> | 2008-08-21 16:15:55 +0000 |
---|---|---|
committer | Colin Walters <walters@src.gnome.org> | 2008-08-21 16:15:55 +0000 |
commit | 59df1dd48957bd494306d2a33a1a46d84895303f (patch) | |
tree | 49a55ce7666079896ca688a04cd82acdcf5634d9 | |
parent | 851faec61462ecbc5a131fbbd75cba487e9953b2 (diff) | |
download | gobject-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-- | ChangeLog | 13 | ||||
-rw-r--r-- | girepository/girmodule.c | 8 | ||||
-rw-r--r-- | girepository/girnode.c | 4 | ||||
-rw-r--r-- | girepository/gtypelib.c | 289 | ||||
-rw-r--r-- | giscanner/glibtransformer.py | 50 |
5 files changed, 141 insertions, 223 deletions
@@ -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) |