X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fclass.c;h=717f93c7b8ce1558c4944335b1099534e26f6e34;hb=3144c62025db782c6e2d72615c41a5c294a0ee67;hp=ac1b85d4cacf26bc4443a95028e0f51f0e3e307b;hpb=0816d4a7592e0c9d1ecb86d9974d3ac264442f9a;p=mono.git diff --git a/mono/metadata/class.c b/mono/metadata/class.c index ac1b85d4cac..717f93c7b8c 100644 --- a/mono/metadata/class.c +++ b/mono/metadata/class.c @@ -660,7 +660,8 @@ mono_class_get_generic_class (MonoClass *klass) MonoType* mono_class_inflate_generic_type_with_mempool (MonoImage *image, MonoType *type, MonoGenericContext *context, MonoError *error) { - MonoType *inflated = NULL; + MonoType *inflated = NULL; + mono_error_init (error); if (context) inflated = inflate_generic_type (image, type, context, error); @@ -1151,8 +1152,13 @@ mono_class_setup_fields (MonoClass *class) if (class->parent) { /* For generic instances, class->parent might not have been initialized */ mono_class_init (class->parent); - if (!class->parent->size_inited) + if (!class->parent->size_inited) { mono_class_setup_fields (class->parent); + if (class->parent->exception_type) { + mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL); + return; + } + } class->instance_size += class->parent->instance_size; class->min_align = class->parent->min_align; /* we use |= since it may have been set already */ @@ -1262,8 +1268,13 @@ mono_class_setup_fields (MonoClass *class) blittable = FALSE; } else { MonoClass *field_class = mono_class_from_mono_type (field->type); - if (field_class) + if (field_class) { mono_class_setup_fields (field_class); + if (field_class->exception_type) { + mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL); + break; + } + } if (!field_class || !field_class->blittable) blittable = FALSE; } @@ -1743,9 +1754,14 @@ mono_class_setup_methods (MonoClass *class) } } - if (MONO_CLASS_IS_INTERFACE (class)) - for (i = 0; i < class->method.count; ++i) - methods [i]->slot = i; + if (MONO_CLASS_IS_INTERFACE (class)) { + int slot = 0; + /*Only assign slots to virtual methods as interfaces are allowed to have static methods.*/ + for (i = 0; i < class->method.count; ++i) { + if (methods [i]->flags & METHOD_ATTRIBUTE_VIRTUAL) + methods [i]->slot = slot++; + } + } /* Needed because of the double-checking locking pattern */ mono_memory_barrier (); @@ -3283,7 +3299,10 @@ mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int o for (i = 0; i < parent->interface_offsets_count; i++) { MonoClass *parent_interface = parent->interfaces_packed [i]; int interface_offset = mono_class_interface_offset (class, parent_interface); - + /*FIXME this is now dead code as this condition will never hold true. + Since interface offsets are inherited then the offset of an interface implemented + by a parent will never be the out of it's vtable boundary. + */ if (interface_offset >= parent->vtable_size) { int parent_interface_offset = mono_class_interface_offset (parent, parent_interface); int j; @@ -3582,7 +3601,7 @@ mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int o printf ("VTable %s (vtable entries = %d, interfaces = %d)\n", mono_type_full_name (&class->byval_arg), class->vtable_size, icount); - for (i = 0; i < class->vtable_size; ++i) { + for (i = 0; i < cur_slot; ++i) { MonoMethod *cm; cm = vtable [i]; @@ -3601,15 +3620,15 @@ mono_class_setup_vtable_general (MonoClass *class, MonoMethod **overrides, int o ic = class->interfaces [i]; printf (" slot offset: %03d, method count: %03d, iid: %03d %s\n", mono_class_interface_offset (class, ic), - ic->method.count, ic->interface_id, mono_type_full_name (&ic->byval_arg)); + count_virtual_methods (ic), ic->interface_id, mono_type_full_name (&ic->byval_arg)); } for (k = class->parent; k ; k = k->parent) { for (i = 0; i < k->interface_count; i++) { ic = k->interfaces [i]; - printf (" slot offset: %03d, method count: %03d, iid: %03d %s\n", + printf (" parent slot offset: %03d, method count: %03d, iid: %03d %s\n", mono_class_interface_offset (class, ic), - ic->method.count, ic->interface_id, mono_type_full_name (&ic->byval_arg)); + count_virtual_methods (ic), ic->interface_id, mono_type_full_name (&ic->byval_arg)); } } } @@ -4264,6 +4283,30 @@ mono_class_setup_mono_type (MonoClass *class) } +/* + * COM initialization (using mono_init_com_types) is delayed until needed. + * However when a [ComImport] attribute is present on a type it will trigger + * the initialization. This is not a problem unless the BCL being executed + * lacks the types that COM depends on (e.g. Variant on Silverlight). + */ +static void +init_com_from_comimport (MonoClass *class) +{ + /* we don't always allow COM initialization under the CoreCLR (e.g. Moonlight does not require it) */ + if ((mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR)) { + /* but some other CoreCLR user could requires it for their platform (i.e. trusted) code */ + if (!mono_security_core_clr_determine_platform_image (class->image)) { + /* but it can not be made available for application (i.e. user code) since all COM calls + * are considered native calls. In this case we fail with a TypeLoadException (just like + * Silverlight 2 does */ + mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL); + return; + } + } + /* FIXME : we should add an extra checks to ensure COM can be initialized properly before continuing */ + mono_init_com_types (); +} + /* * LOCKING: this assumes the loader lock is held */ @@ -4290,7 +4333,7 @@ mono_class_setup_parent (MonoClass *class, MonoClass *parent) if (!MONO_CLASS_IS_INTERFACE (class)) { /* Imported COM Objects always derive from __ComObject. */ if (MONO_CLASS_IS_IMPORT (class)) { - mono_init_com_types (); + init_com_from_comimport (class); if (parent == mono_defaults.object_class) parent = mono_defaults.com_object_class; } @@ -4341,7 +4384,7 @@ mono_class_setup_parent (MonoClass *class, MonoClass *parent) } else { /* initialize com types if COM interfaces are present */ if (MONO_CLASS_IS_IMPORT (class)) - mono_init_com_types (); + init_com_from_comimport (class); class->parent = NULL; } @@ -4481,7 +4524,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token) if ((class->flags & TYPE_ATTRIBUTE_STRING_FORMAT_MASK) == TYPE_ATTRIBUTE_UNICODE_CLASS) class->unicode = 1; -#if PLATFORM_WIN32 +#ifdef PLATFORM_WIN32 if ((class->flags & TYPE_ATTRIBUTE_STRING_FORMAT_MASK) == TYPE_ATTRIBUTE_AUTO_CLASS) class->unicode = 1; #endif @@ -5178,6 +5221,9 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded) mono_class_init (eclass); if (!eclass->size_inited) mono_class_setup_fields (eclass); + if (eclass->exception_type) /*FIXME we fail the array type, but we have to let other fields be set.*/ + mono_class_set_failure (class, MONO_EXCEPTION_TYPE_LOAD, NULL); + class->has_references = MONO_TYPE_IS_REFERENCE (&eclass->byval_arg) || eclass->has_references? TRUE: FALSE; class->rank = rank; @@ -5331,6 +5377,8 @@ static MonoClassField * mono_class_get_field_idx (MonoClass *class, int idx) { mono_class_setup_fields_locking (class); + if (class->exception_type) + return NULL; while (class) { if (class->image->uncompressed_metadata) { @@ -5411,6 +5459,9 @@ mono_class_get_field_from_name_full (MonoClass *klass, const char *name, MonoTyp int i; mono_class_setup_fields_locking (klass); + if (klass->exception_type) + return NULL; + while (klass) { for (i = 0; i < klass->field.count; ++i) { MonoClassField *field = &klass->fields [i]; @@ -5446,6 +5497,9 @@ mono_class_get_field_token (MonoClassField *field) int i; mono_class_setup_fields_locking (klass); + if (klass->exception_type) + return 0; + while (klass) { for (i = 0; i < klass->field.count; ++i) { if (&klass->fields [i] == field) { @@ -5856,6 +5910,7 @@ mono_image_add_to_name_cache (MonoImage *image, const char *nspace, { GHashTable *nspace_table; GHashTable *name_cache; + guint32 old_index; mono_image_lock (image); @@ -5867,6 +5922,10 @@ mono_image_add_to_name_cache (MonoImage *image, const char *nspace, nspace_table = g_hash_table_new (g_str_hash, g_str_equal); g_hash_table_insert (name_cache, (char *)nspace, (char *)nspace_table); } + + if ((old_index = GPOINTER_TO_UINT (g_hash_table_lookup (nspace_table, (char*) name)))) + g_error ("overrwritting old token %x on image %s for type %s::%s", old_index, image->name, nspace, name); + g_hash_table_insert (nspace_table, (char *) name, GUINT_TO_POINTER (index)); mono_image_unlock (image); @@ -7752,6 +7811,14 @@ can_access_internals (MonoAssembly *accessing, MonoAssembly* accessed) return TRUE; if (!accessed || !accessing) return FALSE; + + /* extra safety under CoreCLR - the runtime does not verify the strongname signatures + * anywhere so untrusted friends are not safe to access platform's code internals */ + if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR) { + if (!mono_security_core_clr_can_access_internals (accessing->image, accessed->image)) + return FALSE; + } + mono_assembly_load_friends (accessed); for (tmp = accessed->friend_assembly_names; tmp; tmp = tmp->next) { MonoAssemblyName *friend = tmp->data;