From 3f4617caabf1568d26b09dbd47a2aaaf05c4f44e Mon Sep 17 00:00:00 2001 From: Tim Janik Date: Tue, 19 Mar 2002 19:26:27 +0000 Subject: [PATCH] applied patch from Matthias Clasen to check for Tue Mar 19 18:57:12 2002 Tim Janik * gtype.c (check_add_interface_L): applied patch from Matthias Clasen to check for prerequisite of interfaces, fixes #74427. fixed mutex recursion in his patch (we can't call g_type_is_a() while holding a read lock). * gparam.c (canonalize_key): cleanup. --- gobject/ChangeLog | 9 +++++++ gobject/gparam.c | 16 +++++++------ gobject/gtype.c | 61 +++++++++++++++++++++++++++++++++++++---------- 3 files changed, 67 insertions(+), 19 deletions(-) diff --git a/gobject/ChangeLog b/gobject/ChangeLog index 5e7b509d9..7087bf413 100644 --- a/gobject/ChangeLog +++ b/gobject/ChangeLog @@ -1,3 +1,12 @@ +Tue Mar 19 18:57:12 2002 Tim Janik + + * gtype.c (check_add_interface_L): applied patch from Matthias Clasen + to check for prerequisite of interfaces, fixes #74427. + fixed mutex recursion in his patch (we can't call g_type_is_a() while + holding a read lock). + + * gparam.c (canonalize_key): cleanup. + 2002-03-13 Alexander Larsson * gparam.c (canonalize_key): diff --git a/gobject/gparam.c b/gobject/gparam.c index 3bcdc376f..db0568d7c 100644 --- a/gobject/gparam.c +++ b/gobject/gparam.c @@ -258,12 +258,14 @@ g_param_spec_get_blurb (GParamSpec *pspec) } static void -canonalize_key(gchar *key) +canonalize_key (gchar *key) { - gchar *p, c; - - for (p = key; (c = *p) != 0; p++) + gchar *p; + + for (p = key; *p != 0; p++) { + gchar c = *p; + if (c != '-' && (c < '0' || c > '9') && (c < 'A' || c > 'Z') && @@ -280,18 +282,18 @@ g_param_spec_internal (GType param_type, GParamFlags flags) { GParamSpec *pspec; - + g_return_val_if_fail (G_TYPE_IS_PARAM (param_type) && param_type != G_TYPE_PARAM, NULL); g_return_val_if_fail (name != NULL, NULL); g_return_val_if_fail ((name[0] >= 'A' && name[0] <= 'Z') || (name[0] >= 'a' && name[0] <= 'z'), NULL); - + pspec = (gpointer) g_type_create_instance (param_type); pspec->name = g_strdup (name); canonalize_key (pspec->name); pspec->_nick = g_strdup (nick); pspec->_blurb = g_strdup (blurb); pspec->flags = (flags & G_PARAM_USER_MASK) | (flags & G_PARAM_MASK); - + return pspec; } diff --git a/gobject/gtype.c b/gobject/gtype.c index 49d7fdaa8..9bb0b91f9 100644 --- a/gobject/gtype.c +++ b/gobject/gtype.c @@ -137,6 +137,8 @@ static inline void type_set_qdata_W (TypeNode *node, gpointer data); static IFaceHolder* type_iface_peek_holder_L (TypeNode *iface, GType instance_type); +static gboolean type_node_is_a_L (TypeNode *node, + TypeNode *iface_node); /* --- structures --- */ @@ -776,6 +778,9 @@ check_add_interface_L (GType instance_type, TypeNode *iface = lookup_type_node_I (iface_type); IFaceEntry *entry; TypeNode *tnode; + GType *prerequisites; + guint i; + if (!node || !node->is_instantiatable) { @@ -822,6 +827,19 @@ check_add_interface_L (GType instance_type, NODE_NAME (tnode)); return FALSE; } + prerequisites = IFACE_NODE_PREREQUISITES (iface); + for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++) + { + tnode = lookup_type_node_I (prerequisites[i]); + if (!type_node_is_a_L (node, tnode)) + { + g_warning ("cannot add interface type `%s' to type `%s' which does not conform to prerequisite `%s'", + NODE_NAME (iface), + NODE_NAME (node), + NODE_NAME (tnode)); + return FALSE; + } + } return TRUE; } @@ -2180,11 +2198,12 @@ g_type_next_base (GType type, } static inline gboolean -type_node_is_a_U (TypeNode *node, - TypeNode *iface_node, - /* support_inheritance */ - gboolean support_interfaces, - gboolean support_prerequisites) +type_node_check_conformities_UorL (TypeNode *node, + TypeNode *iface_node, + /* support_inheritance */ + gboolean support_interfaces, + gboolean support_prerequisites, + gboolean have_lock) { gboolean match; @@ -2198,16 +2217,34 @@ type_node_is_a_U (TypeNode *node, match = FALSE; if (support_interfaces || support_prerequisites) { - G_READ_LOCK (&type_rw_lock); + if (!have_lock) + G_READ_LOCK (&type_rw_lock); if (support_interfaces && type_lookup_iface_entry_L (node, iface_node)) match = TRUE; else if (support_prerequisites && type_lookup_prerequisite_L (node, NODE_TYPE (iface_node))) match = TRUE; - G_READ_UNLOCK (&type_rw_lock); + if (!have_lock) + G_READ_UNLOCK (&type_rw_lock); } return match; } +static gboolean +type_node_is_a_L (TypeNode *node, + TypeNode *iface_node) +{ + return type_node_check_conformities_UorL (node, iface_node, TRUE, TRUE, TRUE); +} + +static inline gboolean +type_node_conforms_to_U (TypeNode *node, + TypeNode *iface_node, + gboolean support_interfaces, + gboolean support_prerequisites) +{ + return type_node_check_conformities_UorL (node, iface_node, support_interfaces, support_prerequisites, FALSE); +} + gboolean g_type_is_a (GType type, GType iface_type) @@ -2217,7 +2254,7 @@ g_type_is_a (GType type, node = lookup_type_node_I (type); iface_node = lookup_type_node_I (iface_type); - is_a = node && iface_node && type_node_is_a_U (node, iface_node, TRUE, TRUE); + is_a = node && iface_node && type_node_conforms_to_U (node, iface_node, TRUE, TRUE); return is_a; } @@ -2567,7 +2604,7 @@ g_type_check_instance_is_a (GTypeInstance *type_instance, node = lookup_type_node_I (type_instance->g_class->g_type); iface = lookup_type_node_I (iface_type); - check = node && node->is_instantiatable && iface && type_node_is_a_U (node, iface, TRUE, FALSE); + check = node && node->is_instantiatable && iface && type_node_conforms_to_U (node, iface, TRUE, FALSE); return check; } @@ -2584,7 +2621,7 @@ g_type_check_class_is_a (GTypeClass *type_class, node = lookup_type_node_I (type_class->g_type); iface = lookup_type_node_I (is_a_type); - check = node && node->is_classed && iface && type_node_is_a_U (node, iface, FALSE, FALSE); + check = node && node->is_classed && iface && type_node_conforms_to_U (node, iface, FALSE, FALSE); return check; } @@ -2603,7 +2640,7 @@ g_type_check_instance_cast (GTypeInstance *type_instance, node = lookup_type_node_I (type_instance->g_class->g_type); is_instantiatable = node && node->is_instantiatable; iface = lookup_type_node_I (iface_type); - check = is_instantiatable && iface && type_node_is_a_U (node, iface, TRUE, FALSE); + check = is_instantiatable && iface && type_node_conforms_to_U (node, iface, TRUE, FALSE); if (check) return type_instance; @@ -2639,7 +2676,7 @@ g_type_check_class_cast (GTypeClass *type_class, node = lookup_type_node_I (type_class->g_type); is_classed = node && node->is_classed; iface = lookup_type_node_I (is_a_type); - check = is_classed && iface && type_node_is_a_U (node, iface, FALSE, FALSE); + check = is_classed && iface && type_node_conforms_to_U (node, iface, FALSE, FALSE); if (check) return type_class;