X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fmetadata-verify.c;h=e898178e00a1532a253acbf3adea8e23787c6fd9;hb=HEAD;hp=f31983c303f3a9b039fb44ba970437689a3a7114;hpb=a3304910e9e08ec965fb06ef6fa4a19257dddf8c;p=mono.git diff --git a/mono/metadata/metadata-verify.c b/mono/metadata/metadata-verify.c index f31983c303f..e898178e00a 100644 --- a/mono/metadata/metadata-verify.c +++ b/mono/metadata/metadata-verify.c @@ -1514,6 +1514,7 @@ parse_method_signature (VerifyContext *ctx, const char **_ptr, const char *end, static gboolean parse_property_signature (VerifyContext *ctx, const char **_ptr, const char *end) { + unsigned type = 0; unsigned sig = 0; unsigned param_count = 0, i; const char *ptr = *_ptr; @@ -1530,6 +1531,13 @@ parse_property_signature (VerifyContext *ctx, const char **_ptr, const char *end if (!parse_custom_mods (ctx, &ptr, end)) return FALSE; + if (!safe_read8 (type, ptr, end)) + FAIL (ctx, g_strdup ("PropertySig: Not enough room for the type")); + + //check if it's a byref. safe_read8 did update ptr, so we rollback if it's not a byref + if (type != MONO_TYPE_BYREF) + --ptr; + if (!parse_type (ctx, &ptr, end)) FAIL (ctx, g_strdup ("PropertySig: Could not parse property type")); @@ -1894,8 +1902,13 @@ handle_enum: FAIL (ctx, g_strdup_printf ("CustomAttribute: Invalid boxed object type %x", sub_type)); } - case MONO_TYPE_CLASS: + if (klass && klass->enumtype) { + klass = klass->element_class; + type = klass->byval_arg.type; + goto handle_enum; + } + if (klass != mono_defaults.systemtype_class) FAIL (ctx, g_strdup_printf ("CustomAttribute: Invalid class parameter type %s:%s ",klass->name_space, klass->name)); *_ptr = ptr; @@ -2413,7 +2426,7 @@ verify_typedef_table (VerifyContext *ctx) for (i = 0; i < table->rows; ++i) { mono_metadata_decode_row (table, i, data, MONO_TYPEDEF_SIZE); if (data [MONO_TYPEDEF_FLAGS] & INVALID_TYPEDEF_FLAG_BITS) - ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row %d invalid flags field 0x%08x", i, data [MONO_TYPEDEF_FLAGS])); + ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row %d invalid flags field 0x%08x rejected bits: 0x%08x", i, data [MONO_TYPEDEF_FLAGS], data [MONO_TYPEDEF_FLAGS] & INVALID_TYPEDEF_FLAG_BITS)); if ((data [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_LAYOUT_MASK) == 0x18) ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row %d invalid class layout 0x18", i)); @@ -2962,8 +2975,11 @@ verify_cattr_table_full (VerifyContext *ctx) /*This can't fail since this is checked in is_valid_cattr_blob*/ g_assert (decode_signature_header (ctx, data [MONO_CUSTOM_ATTR_VALUE], &size, &ptr)); - if (!is_valid_cattr_content (ctx, ctor, ptr, size)) - ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute content row %d Value field 0x%08x", i, data [MONO_CUSTOM_ATTR_VALUE])); + if (!is_valid_cattr_content (ctx, ctor, ptr, size)) { + char *ctor_name = mono_method_full_name (ctor, TRUE); + ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute content row %d Value field 0x%08x ctor: %s", i, data [MONO_CUSTOM_ATTR_VALUE], ctor_name)); + g_free (ctor_name); + } } } @@ -3750,6 +3766,54 @@ verify_typeref_table_global_constraints (VerifyContext *ctx) g_hash_table_destroy (unique_types); } +typedef struct { + guint32 klass; + guint32 method_declaration; +} MethodImplUniqueId; + +static guint +methodimpl_hash (gconstpointer _key) +{ + const MethodImplUniqueId *key = (const MethodImplUniqueId *)_key; + return key->klass ^ key->method_declaration; +} + +static gboolean +methodimpl_equals (gconstpointer _a, gconstpointer _b) +{ + const MethodImplUniqueId *a = (const MethodImplUniqueId *)_a; + const MethodImplUniqueId *b = (const MethodImplUniqueId *)_b; + return a->klass == b->klass && a->method_declaration == b->method_declaration; +} + +static void +verify_methodimpl_table_global_constraints (VerifyContext *ctx) +{ + int i; + guint32 data [MONO_METHODIMPL_SIZE]; + MonoTableInfo *table = &ctx->image->tables [MONO_TABLE_METHODIMPL]; + GHashTable *unique_impls = g_hash_table_new_full (&methodimpl_hash, &methodimpl_equals, g_free, NULL); + + for (i = 0; i < table->rows; ++i) { + MethodImplUniqueId *impl = g_new (MethodImplUniqueId, 1); + mono_metadata_decode_row (table, i, data, MONO_METHODIMPL_SIZE); + + impl->klass = data [MONO_METHODIMPL_CLASS]; + impl->method_declaration = data [MONO_METHODIMPL_DECLARATION]; + + if (g_hash_table_lookup (unique_impls, impl)) { + ADD_ERROR_NO_RETURN (ctx, g_strdup_printf ("MethodImpl table row %d has duplicate for tuple (0x%x, 0x%x)", impl->klass, impl->method_declaration)); + g_hash_table_destroy (unique_impls); + g_free (impl); + return; + } + g_hash_table_insert (unique_impls, impl, GUINT_TO_POINTER (1)); + } + + g_hash_table_destroy (unique_impls); +} + + static void verify_tables_data_global_constraints (VerifyContext *ctx) { @@ -3761,6 +3825,7 @@ verify_tables_data_global_constraints_full (VerifyContext *ctx) { verify_typeref_table (ctx); verify_typeref_table_global_constraints (ctx); + verify_methodimpl_table_global_constraints (ctx); } static void