diff --git a/girepository/girepository.c b/girepository/girepository.c index f9619d072..83ec69e52 100644 --- a/girepository/girepository.c +++ b/girepository/girepository.c @@ -93,8 +93,10 @@ gtype_interface_cache_free (gpointer data) g_free (cache); } -struct _GIRepositoryPrivate +struct _GIRepository { + GObject parent; + GHashTable *typelibs; /* (string) namespace -> GITypelib */ GHashTable *lazy_typelibs; /* (string) namespace-version -> GITypelib */ GHashTable *info_by_gtype; /* GType -> GIBaseInfo */ @@ -106,7 +108,7 @@ struct _GIRepositoryPrivate size_t cached_n_shared_libraries; /* length of @cached_shared_libraries, not including NULL terminator */ }; -G_DEFINE_TYPE_WITH_CODE (GIRepository, gi_repository, G_TYPE_OBJECT, G_ADD_PRIVATE (GIRepository)); +G_DEFINE_TYPE (GIRepository, gi_repository, G_TYPE_OBJECT); #ifdef G_PLATFORM_WIN32 @@ -146,28 +148,27 @@ DllMain (HINSTANCE hinstDLL, static void gi_repository_init (GIRepository *repository) { - repository->priv = gi_repository_get_instance_private (repository); - repository->priv->typelibs + repository->typelibs = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) gi_typelib_free); - repository->priv->lazy_typelibs + repository->lazy_typelibs = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) NULL); - repository->priv->info_by_gtype + repository->info_by_gtype = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) NULL, (GDestroyNotify) gi_base_info_unref); - repository->priv->info_by_error_domain + repository->info_by_error_domain = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) NULL, (GDestroyNotify) gi_base_info_unref); - repository->priv->interfaces_for_gtype + repository->interfaces_for_gtype = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) NULL, (GDestroyNotify) gtype_interface_cache_free); - repository->priv->unknown_gtypes = g_hash_table_new (NULL, NULL); + repository->unknown_gtypes = g_hash_table_new (NULL, NULL); } static void @@ -175,14 +176,14 @@ gi_repository_finalize (GObject *object) { GIRepository *repository = GI_REPOSITORY (object); - g_hash_table_destroy (repository->priv->typelibs); - g_hash_table_destroy (repository->priv->lazy_typelibs); - g_hash_table_destroy (repository->priv->info_by_gtype); - g_hash_table_destroy (repository->priv->info_by_error_domain); - g_hash_table_destroy (repository->priv->interfaces_for_gtype); - g_hash_table_destroy (repository->priv->unknown_gtypes); + g_hash_table_destroy (repository->typelibs); + g_hash_table_destroy (repository->lazy_typelibs); + g_hash_table_destroy (repository->info_by_gtype); + g_hash_table_destroy (repository->info_by_error_domain); + g_hash_table_destroy (repository->interfaces_for_gtype); + g_hash_table_destroy (repository->unknown_gtypes); - g_clear_pointer (&repository->priv->cached_shared_libraries, g_strfreev); + g_clear_pointer (&repository->cached_shared_libraries, g_strfreev); (* G_OBJECT_CLASS (gi_repository_parent_class)->finalize) (G_OBJECT (repository)); } @@ -374,10 +375,10 @@ get_registered_status (GIRepository *repository, repository = get_repository (repository); if (lazy_status) *lazy_status = FALSE; - typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); + typelib = g_hash_table_lookup (repository->typelibs, namespace); if (typelib) return check_version_conflict (typelib, namespace, version, version_conflict); - typelib = g_hash_table_lookup (repository->priv->lazy_typelibs, namespace); + typelib = g_hash_table_lookup (repository->lazy_typelibs, namespace); if (!typelib) return NULL; if (lazy_status) @@ -453,9 +454,9 @@ register_internal (GIRepository *repository, if (lazy) { - g_assert (!g_hash_table_lookup (repository->priv->lazy_typelibs, + g_assert (!g_hash_table_lookup (repository->lazy_typelibs, namespace)); - g_hash_table_insert (repository->priv->lazy_typelibs, + g_hash_table_insert (repository->lazy_typelibs, build_typelib_key (namespace, source), (void *)typelib); } else @@ -468,20 +469,20 @@ register_internal (GIRepository *repository, return NULL; /* Check if we are transitioning from lazily loaded state */ - if (g_hash_table_lookup_extended (repository->priv->lazy_typelibs, + if (g_hash_table_lookup_extended (repository->lazy_typelibs, namespace, (gpointer)&key, &value)) - g_hash_table_remove (repository->priv->lazy_typelibs, key); + g_hash_table_remove (repository->lazy_typelibs, key); else key = build_typelib_key (namespace, source); - g_hash_table_insert (repository->priv->typelibs, + g_hash_table_insert (repository->typelibs, g_steal_pointer (&key), (void *)typelib); } /* These types might be resolved now, clear the cache */ - g_hash_table_remove_all (repository->priv->unknown_gtypes); + g_hash_table_remove_all (repository->unknown_gtypes); return namespace; } @@ -887,13 +888,13 @@ gi_repository_find_by_gtype (GIRepository *repository, repository = get_repository (repository); - cached = g_hash_table_lookup (repository->priv->info_by_gtype, + cached = g_hash_table_lookup (repository->info_by_gtype, (gpointer)gtype); if (cached != NULL) return gi_base_info_ref (cached); - if (g_hash_table_contains (repository->priv->unknown_gtypes, (gpointer)gtype)) + if (g_hash_table_contains (repository->unknown_gtypes, (gpointer)gtype)) return NULL; data.gtype_name = g_type_name (gtype); @@ -906,9 +907,9 @@ gi_repository_find_by_gtype (GIRepository *repository, * target type does not have this typelib's C prefix. Use this * assumption as our first attempt at locating the DirEntry. */ - entry = find_by_gtype (repository->priv->typelibs, &data, TRUE); + entry = find_by_gtype (repository->typelibs, &data, TRUE); if (entry == NULL) - entry = find_by_gtype (repository->priv->lazy_typelibs, &data, TRUE); + entry = find_by_gtype (repository->lazy_typelibs, &data, TRUE); /* Not ever class library necessarily specifies a correct c_prefix, * so take a second pass. This time we will try a global lookup, @@ -916,9 +917,9 @@ gi_repository_find_by_gtype (GIRepository *repository, * See http://bugzilla.gnome.org/show_bug.cgi?id=564016 */ if (entry == NULL) - entry = find_by_gtype (repository->priv->typelibs, &data, FALSE); + entry = find_by_gtype (repository->typelibs, &data, FALSE); if (entry == NULL) - entry = find_by_gtype (repository->priv->lazy_typelibs, &data, FALSE); + entry = find_by_gtype (repository->lazy_typelibs, &data, FALSE); if (entry != NULL) { @@ -926,14 +927,14 @@ gi_repository_find_by_gtype (GIRepository *repository, repository, NULL, data.result_typelib, entry->offset); - g_hash_table_insert (repository->priv->info_by_gtype, + g_hash_table_insert (repository->info_by_gtype, (gpointer) gtype, gi_base_info_ref (cached)); return cached; } else { - g_hash_table_add (repository->priv->unknown_gtypes, (gpointer) gtype); + g_hash_table_add (repository->unknown_gtypes, (gpointer) gtype); return NULL; } } @@ -1027,7 +1028,7 @@ gi_repository_find_by_error_domain (GIRepository *repository, repository = get_repository (repository); - cached = g_hash_table_lookup (repository->priv->info_by_error_domain, + cached = g_hash_table_lookup (repository->info_by_error_domain, GUINT_TO_POINTER (domain)); if (cached != NULL) @@ -1038,9 +1039,9 @@ gi_repository_find_by_error_domain (GIRepository *repository, data.result_typelib = NULL; data.result = NULL; - g_hash_table_foreach (repository->priv->typelibs, find_by_error_domain_foreach, &data); + g_hash_table_foreach (repository->typelibs, find_by_error_domain_foreach, &data); if (data.result == NULL) - g_hash_table_foreach (repository->priv->lazy_typelibs, find_by_error_domain_foreach, &data); + g_hash_table_foreach (repository->lazy_typelibs, find_by_error_domain_foreach, &data); if (data.result != NULL) { @@ -1048,7 +1049,7 @@ gi_repository_find_by_error_domain (GIRepository *repository, repository, NULL, data.result_typelib, data.result->offset); - g_hash_table_insert (repository->priv->info_by_error_domain, + g_hash_table_insert (repository->info_by_error_domain, GUINT_TO_POINTER (domain), gi_base_info_ref ((GIBaseInfo *) cached)); return cached; @@ -1091,7 +1092,7 @@ gi_repository_get_object_gtype_interfaces (GIRepository *repository, repository = get_repository (repository); - cache = g_hash_table_lookup (repository->priv->interfaces_for_gtype, + cache = g_hash_table_lookup (repository->interfaces_for_gtype, (void *) gtype); if (cache == NULL) { @@ -1127,7 +1128,7 @@ gi_repository_get_object_gtype_interfaces (GIRepository *repository, cache->interfaces[i] = iter->data; g_list_free (interface_infos); - g_hash_table_insert (repository->priv->interfaces_for_gtype, (gpointer) gtype, + g_hash_table_insert (repository->interfaces_for_gtype, (gpointer) gtype, cache); g_free (interfaces); @@ -1167,8 +1168,8 @@ gi_repository_get_loaded_namespaces (GIRepository *repository) repository = get_repository (repository); - g_hash_table_foreach (repository->priv->typelibs, collect_namespaces, &list); - g_hash_table_foreach (repository->priv->lazy_typelibs, collect_namespaces, &list); + g_hash_table_foreach (repository->typelibs, collect_namespaces, &list); + g_hash_table_foreach (repository->lazy_typelibs, collect_namespaces, &list); names = g_malloc0 (sizeof (char *) * (g_list_length (list) + 1)); i = 0; @@ -1264,21 +1265,21 @@ gi_repository_get_shared_libraries (GIRepository *repository, } /* Populate the cache. */ - if (repository->priv->cached_shared_libraries == NULL) + if (repository->cached_shared_libraries == NULL) { const char *comma_separated = gi_typelib_get_string (typelib, header->shared_library); if (comma_separated != NULL && *comma_separated != '\0') { - repository->priv->cached_shared_libraries = g_strsplit (comma_separated, ",", -1); - repository->priv->cached_n_shared_libraries = g_strv_length (repository->priv->cached_shared_libraries); + repository->cached_shared_libraries = g_strsplit (comma_separated, ",", -1); + repository->cached_n_shared_libraries = g_strv_length (repository->cached_shared_libraries); } } if (out_n_elements != NULL) - *out_n_elements = repository->priv->cached_n_shared_libraries; + *out_n_elements = repository->cached_n_shared_libraries; - return (const char * const *) repository->priv->cached_shared_libraries; + return (const char * const *) repository->cached_shared_libraries; } /** @@ -1346,10 +1347,10 @@ gi_repository_get_typelib_path (GIRepository *repository, repository = get_repository (repository); - if (!g_hash_table_lookup_extended (repository->priv->typelibs, namespace, + if (!g_hash_table_lookup_extended (repository->typelibs, namespace, &orig_key, &value)) { - if (!g_hash_table_lookup_extended (repository->priv->lazy_typelibs, namespace, + if (!g_hash_table_lookup_extended (repository->lazy_typelibs, namespace, &orig_key, &value)) return NULL; diff --git a/girepository/girepository.h b/girepository/girepository.h index f430e95aa..a6aa4fdc6 100644 --- a/girepository/girepository.h +++ b/girepository/girepository.h @@ -57,29 +57,9 @@ G_BEGIN_DECLS -#define GI_TYPE_REPOSITORY (gi_repository_get_type ()) -#define GI_REPOSITORY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GI_TYPE_REPOSITORY, GIRepository)) -#define GI_REPOSITORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GI_TYPE_REPOSITORY, GIRepositoryClass)) -#define GI_IS_REPOSITORY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GI_TYPE_REPOSITORY)) -#define GI_IS_REPOSITORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GI_TYPE_REPOSITORY)) -#define GI_REPOSITORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GI_TYPE_REPOSITORY, GIRepositoryClass)) - -typedef struct _GIRepository GIRepository; -typedef struct _GIRepositoryClass GIRepositoryClass; -typedef struct _GIRepositoryPrivate GIRepositoryPrivate; - -struct _GIRepository -{ - /*< private >*/ - GObject parent; - GIRepositoryPrivate *priv; -}; - -struct _GIRepositoryClass -{ - /*< private >*/ - GObjectClass parent; -}; +#define GI_TYPE_REPOSITORY (gi_repository_get_type ()) +GI_AVAILABLE_IN_ALL +G_DECLARE_FINAL_TYPE (GIRepository, gi_repository, GI, REPOSITORY, GObject) /** * GIRepositoryLoadFlags: @@ -96,9 +76,6 @@ typedef enum /* Repository */ -GI_AVAILABLE_IN_ALL -GType gi_repository_get_type (void) G_GNUC_CONST; - GI_AVAILABLE_IN_ALL GIRepository *gi_repository_get_default (void); diff --git a/girepository/girmodule.c b/girepository/girmodule.c index 500d749d4..da4519d7f 100644 --- a/girepository/girmodule.c +++ b/girepository/girmodule.c @@ -37,6 +37,15 @@ #define NUM_SECTIONS 2 +/*< private > + * gi_ir_module_new: + * @name: + * @version: + * @shared_library: (nullable): + * @c_prefix: + * + * Since: 2.80 + */ GIIrModule * gi_ir_module_new (const char *name, const char *version, @@ -49,10 +58,7 @@ gi_ir_module_new (const char *name, module->name = g_strdup (name); module->version = g_strdup (version); - if (shared_library) - module->shared_library = g_strdup (shared_library); - else - module->shared_library = NULL; + module->shared_library = g_strdup (shared_library); module->c_prefix = g_strdup (c_prefix); module->dependencies = NULL; module->entries = NULL; diff --git a/girepository/girnode-private.h b/girepository/girnode-private.h index 4b8a14177..353d6d6ca 100644 --- a/girepository/girnode-private.h +++ b/girepository/girnode-private.h @@ -94,19 +94,19 @@ typedef enum struct _GIIrNode { GIIrNodeTypeId type; - char *name; - GIIrModule *module; + char *name; /* (owned) */ + GIIrModule *module; /* (unowned) */ uint32_t offset; /* Assigned as we build the typelib */ - GHashTable *attributes; + GHashTable *attributes; /* (element-type utf8 utf8) (owned) */ }; struct _GIIrNodeXRef { GIIrNode node; - char *namespace; + char *namespace; /* (owned) */ }; struct _GIIrNodeFunction @@ -124,11 +124,11 @@ struct _GIIrNodeFunction uint8_t throws : 1; uint8_t instance_transfer_full : 1; - char *symbol; - char *property; + char *symbol; /* (owned) */ + char *property; /* (owned) */ - GIIrNodeParam *result; - GList *parameters; + GIIrNodeParam *result; /* (owned) */ + GList *parameters; /* (element-type GIIrNode) (owned) */ }; struct _GIIrNodeType @@ -145,20 +145,20 @@ struct _GIIrNodeType uint8_t is_error : 1; int tag; - char *unparsed; + char *unparsed; /* (owned) */ uint8_t zero_terminated : 1; uint8_t has_length : 1; - int length; + unsigned int length; uint8_t has_size : 1; - int size; - int array_type; + size_t size; + GIArrayType array_type; - GIIrNodeType *parameter_type1; - GIIrNodeType *parameter_type2; + GIIrNodeType *parameter_type1; /* (owned) */ + GIIrNodeType *parameter_type2; /* (owned) */ - char *giinterface; - char **errors; + char *giinterface; /* (owned) */ + char **errors; /* (array zero-terminated=1) (owned) */ }; struct _GIIrNodeParam @@ -179,7 +179,7 @@ struct _GIIrNodeParam int8_t closure; int8_t destroy; - GIIrNodeType *type; + GIIrNodeType *type; /* (owned) */ }; struct _GIIrNodeProperty @@ -188,7 +188,7 @@ struct _GIIrNodeProperty uint8_t deprecated : 1; - char *name; + char *name; /* (owned) */ uint8_t readable : 1; uint8_t writable : 1; uint8_t construct : 1; @@ -196,10 +196,10 @@ struct _GIIrNodeProperty uint8_t transfer : 1; uint8_t shallow_transfer : 1; - char *setter; - char *getter; + char *setter; /* (owned) */ + char *getter; /* (owned) */ - GIIrNodeType *type; + GIIrNodeType *type; /* (owned) */ }; struct _GIIrNodeSignal @@ -220,10 +220,10 @@ struct _GIIrNodeSignal uint8_t has_class_closure : 1; uint8_t true_stops_emit : 1; - int class_closure; + unsigned int class_closure; - GList *parameters; - GIIrNodeParam *result; + GList *parameters; /* (element-type GIIrNode) (owned) */ + GIIrNodeParam *result; /* (owned) */ }; struct _GIIrNodeVFunc @@ -238,12 +238,12 @@ struct _GIIrNodeVFunc uint8_t throws : 1; uint8_t instance_transfer_full : 1; - char *invoker; + char *invoker; /* (owned) */ - GList *parameters; - GIIrNodeParam *result; + GList *parameters; /* (element-type GIIrNode) (owned) */ + GIIrNodeParam *result; /* (owned) */ - int offset; + size_t offset; }; struct _GIIrNodeField @@ -252,11 +252,12 @@ struct _GIIrNodeField uint8_t readable : 1; uint8_t writable : 1; - int bits; - int offset; - GIIrNodeFunction *callback; + unsigned int bits; + size_t offset; + GIIrOffsetsState offset_state; + GIIrNodeFunction *callback; /* (owned) */ - GIIrNodeType *type; + GIIrNodeType *type; /* (owned) */ }; struct _GIIrNodeInterface @@ -268,25 +269,25 @@ struct _GIIrNodeInterface uint8_t fundamental : 1; uint8_t final_ : 1; - char *gtype_name; - char *gtype_init; + char *gtype_name; /* (owned) */ + char *gtype_init; /* (owned) */ - char *ref_func; - char *unref_func; - char *set_value_func; - char *get_value_func; + char *ref_func; /* (owned) */ + char *unref_func; /* (owned) */ + char *set_value_func; /* (owned) */ + char *get_value_func; /* (owned) */ - char *parent; - char *glib_type_struct; + char *parent; /* (owned) */ + char *glib_type_struct; /* (owned) */ - GList *interfaces; - GList *prerequisites; + GList *interfaces; /* (element-type GIIrNode) (owned) */ + GList *prerequisites; /* (element-type utf8) (owned) */ size_t alignment; size_t size; GIIrOffsetsState offsets_state; - GList *members; + GList *members; /* (element-type GIIrNode) (owned) */ }; struct _GIIrNodeValue @@ -304,9 +305,9 @@ struct _GIIrNodeConstant uint8_t deprecated : 1; - GIIrNodeType *type; + GIIrNodeType *type; /* (owned) */ - char *value; + char *value; /* (owned) */ }; struct _GIIrNodeEnum @@ -314,14 +315,14 @@ struct _GIIrNodeEnum GIIrNode node; uint8_t deprecated : 1; - int storage_type; + GITypeTag storage_type; - char *gtype_name; - char *gtype_init; - char *error_domain; + char *gtype_name; /* (owned) */ + char *gtype_init; /* (owned) */ + char *error_domain; /* (owned) */ - GList *values; - GList *methods; + GList *values; /* (element-type GIIrNode) (owned) */ + GList *methods; /* (element-type GIIrNode) (owned) */ }; struct _GIIrNodeBoxed @@ -330,14 +331,14 @@ struct _GIIrNodeBoxed uint8_t deprecated : 1; - char *gtype_name; - char *gtype_init; + char *gtype_name; /* (owned) */ + char *gtype_init; /* (owned) */ size_t alignment; size_t size; GIIrOffsetsState offsets_state; - GList *members; + GList *members; /* (element-type GIIrNode) (owned) */ }; struct _GIIrNodeStruct @@ -351,17 +352,17 @@ struct _GIIrNodeStruct uint8_t is_gtype_struct : 1; uint8_t foreign : 1; - char *gtype_name; - char *gtype_init; + char *gtype_name; /* (owned) */ + char *gtype_init; /* (owned) */ - char *copy_func; - char *free_func; + char *copy_func; /* (owned) */ + char *free_func; /* (owned) */ size_t alignment; size_t size; GIIrOffsetsState offsets_state; - GList *members; + GList *members; /* (element-type GIIrNode) (owned) */ }; struct _GIIrNodeUnion @@ -370,21 +371,21 @@ struct _GIIrNodeUnion uint8_t deprecated : 1; - GList *members; - GList *discriminators; + GList *members; /* (element-type GIIrNode) (owned) */ + GList *discriminators; /* (element-type GIIrNode) (owned) */ - char *gtype_name; - char *gtype_init; + char *gtype_name; /* (owned) */ + char *gtype_init; /* (owned) */ - char *copy_func; - char *free_func; + char *copy_func; /* (owned) */ + char *free_func; /* (owned) */ size_t alignment; size_t size; GIIrOffsetsState offsets_state; - int discriminator_offset; - GIIrNodeType *discriminator_type; + size_t discriminator_offset; + GIIrNodeType *discriminator_type; /* (owned) */ }; diff --git a/girepository/girnode.c b/girepository/girnode.c index b1f243fbd..6ba72c23c 100644 --- a/girepository/girnode.c +++ b/girepository/girnode.c @@ -240,7 +240,7 @@ gi_ir_node_free (GIIrNode *node) g_free (type->giinterface); g_strfreev (type->errors); - + g_free (type->unparsed); } break; @@ -320,6 +320,8 @@ gi_ir_node_free (GIIrNode *node) g_free ((GIIrNode *)l->data); g_list_free (iface->interfaces); + g_list_free_full (iface->prerequisites, g_free); + for (l = iface->members; l; l = l->next) gi_ir_node_free ((GIIrNode *)l->data); g_list_free (iface->members); @@ -1241,7 +1243,7 @@ serialize_type (GIIrTypelibBuild *build, if (node->has_length) g_string_append_printf (str, "length=%d", node->length); else if (node->has_size) - g_string_append_printf (str, "fixed-size=%d", node->size); + g_string_append_printf (str, "fixed-size=%" G_GSIZE_FORMAT, node->size); if (node->zero_terminated) g_string_append_printf (str, "%szero-terminated=1", @@ -1599,7 +1601,7 @@ gi_ir_node_build_typelib (GIIrNode *node, blob->writable = field->writable; blob->reserved = 0; blob->bits = 0; - if (field->offset >= 0) + if (field->offset_state == GI_IR_OFFSETS_COMPUTED) blob->struct_offset = field->offset; else blob->struct_offset = 0xFFFF; /* mark as unknown */ diff --git a/girepository/giroffsets.c b/girepository/giroffsets.c index 19cbcbf12..d3fe36a1d 100644 --- a/girepository/giroffsets.c +++ b/girepository/giroffsets.c @@ -392,6 +392,7 @@ compute_struct_field_offsets (GIIrTypelibBuild *build, size = GI_ALIGN (size, member_alignment); alignment = MAX (alignment, member_alignment); field->offset = size; + field->offset_state = GI_IR_OFFSETS_COMPUTED; size += member_size; } else @@ -399,7 +400,10 @@ compute_struct_field_offsets (GIIrTypelibBuild *build, } if (have_error) - field->offset = -1; + { + field->offset = 0; + field->offset_state = GI_IR_OFFSETS_FAILED; + } } else if (member->type == GI_IR_NODE_CALLBACK) { diff --git a/girepository/girparser.c b/girepository/girparser.c index 3924259a0..0d65590f6 100644 --- a/girepository/girparser.c +++ b/girepository/girparser.c @@ -1366,6 +1366,7 @@ start_field (GMarkupParseContext *context, GIIrNodeField *field; ParseState target_state; gboolean introspectable; + guint64 parsed_bits; switch (ctx->state) { @@ -1428,10 +1429,15 @@ start_field (GMarkupParseContext *context, field->readable = readable == NULL || strcmp (readable, "0") == 0; field->writable = writable != NULL && strcmp (writable, "1") == 0; - if (bits) - field->bits = atoi (bits); - else + if (bits == NULL) field->bits = 0; + else if (g_ascii_string_to_unsigned (bits, 10, 0, G_MAXUINT, &parsed_bits, error)) + field->bits = parsed_bits; + else + { + gi_ir_node_free ((GIIrNode *) field); + return FALSE; + } switch (CURRENT_NODE (ctx)->type) { @@ -2100,15 +2106,33 @@ start_type (GMarkupParseContext *context, } if (typenode->array_type == GI_ARRAY_TYPE_C) { + guint64 parsed_uint; + zero = find_attribute ("zero-terminated", attribute_names, attribute_values); len = find_attribute ("length", attribute_names, attribute_values); size = find_attribute ("fixed-size", attribute_names, attribute_values); typenode->has_length = len != NULL; - typenode->length = typenode->has_length ? atoi (len) : -1; + if (!typenode->has_length) + typenode->length = -1; + else if (g_ascii_string_to_unsigned (len, 10, 0, G_MAXUINT, &parsed_uint, error)) + typenode->length = parsed_uint; + else + { + gi_ir_node_free ((GIIrNode *) typenode); + return FALSE; + } typenode->has_size = size != NULL; - typenode->size = typenode->has_size ? atoi (size) : -1; + if (!typenode->has_size) + typenode->size = -1; + else if (g_ascii_string_to_unsigned (size, 10, 0, G_MAXSIZE, &parsed_uint, error)) + typenode->size = parsed_uint; + else + { + gi_ir_node_free ((GIIrNode *) typenode); + return FALSE; + } if (zero) typenode->zero_terminated = strcmp(zero, "1") == 0; @@ -2543,6 +2567,7 @@ start_vfunc (GMarkupParseContext *context, const char *throws; GIIrNodeInterface *iface; GIIrNodeVFunc *vfunc; + guint64 parsed_offset; if (!(strcmp (element_name, "virtual-method") == 0 && (ctx->state == STATE_CLASS || @@ -2602,10 +2627,15 @@ start_vfunc (GMarkupParseContext *context, else vfunc->throws = FALSE; - if (offset) - vfunc->offset = atoi (offset); - else + if (offset == NULL) vfunc->offset = 0xFFFF; + else if (g_ascii_string_to_unsigned (offset, 10, 0, G_MAXSIZE, &parsed_offset, error)) + vfunc->offset = parsed_offset; + else + { + gi_ir_node_free ((GIIrNode *) vfunc); + return FALSE; + } vfunc->invoker = g_strdup (invoker); @@ -2780,6 +2810,8 @@ start_discriminator (GMarkupParseContext *context, { const char *type; const char *offset; + guint64 parsed_offset; + if (!(strcmp (element_name, "discriminator") == 0 && ctx->state == STATE_UNION)) return FALSE; @@ -2799,8 +2831,11 @@ start_discriminator (GMarkupParseContext *context, ((GIIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type = parse_type (ctx, type); - ((GIIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset - = atoi (offset); + + if (g_ascii_string_to_unsigned (offset, 10, 0, G_MAXSIZE, &parsed_offset, error)) + ((GIIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset = parsed_offset; + else + return FALSE; return TRUE; }