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);
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 */
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;
}
}
}
- 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 ();
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;
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];
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));
}
}
}
}
+/*
+ * 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
*/
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;
}
} 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;
}
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
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;
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) {
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];
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) {
{
GHashTable *nspace_table;
GHashTable *name_cache;
+ guint32 old_index;
mono_image_lock (image);
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);
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;