-/*
- * metadata-verify.c: Metadata verfication support
+/**
+ * \file
+ * Metadata verfication support
*
* Author:
* Mono Project (http://www.mono-project.com)
if (!read32 (ptr + 8) || !read32 (ptr + 12))
ADD_ERROR (ctx, g_strdup_printf ("Missing medatata section in the CLI header"));
- if ((read32 (ptr + 16) & ~0x0001000B) != 0)
+ if ((read32 (ptr + 16) & ~0x0003000B) != 0)
ADD_ERROR (ctx, g_strdup_printf ("Invalid CLI header flags"));
ptr += 24;
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;
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"));
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;
}
/*bits 9,11,14,15,19,21,24-31 */
-#define INVALID_TYPEDEF_FLAG_BITS ((1 << 6) | (1 << 9) | (1 << 14) | (1 << 15) | (1 << 19) | (1 << 21) | 0xFF000000)
+#define INVALID_TYPEDEF_FLAG_BITS ((1 << 6) | (1 << 9) | (1 << 15) | (1 << 19) | (1 << 21) | 0xFF000000)
static void
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));
/*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);
+ }
}
}
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)
{
{
verify_typeref_table (ctx);
verify_typeref_table_global_constraints (ctx);
+ verify_methodimpl_table_global_constraints (ctx);
}
static void
{
VerifyContext ctx;
- mono_error_init (error);
+ error_init (error);
if (!mono_verifier_is_enabled_for_image (image))
return TRUE;
return FALSE;
if (original_sig->explicit_this != signature->explicit_this)
return FALSE;
- if (original_sig->call_convention != signature->call_convention)
- return FALSE;
if (original_sig->pinvoke != signature->pinvoke)
return FALSE;
if (original_sig->sentinelpos != signature->sentinelpos)
MonoTableInfo *table = &image->tables [MONO_TABLE_TYPEREF];
guint32 data [MONO_TYPEREF_SIZE];
- mono_error_init (error);
+ error_init (error);
if (!mono_verifier_is_enabled_for_image (image))
return TRUE;
MonoTableInfo *table = &image->tables [MONO_TABLE_METHODIMPL];
guint32 data [MONO_METHODIMPL_SIZE];
- mono_error_init (error);
+ error_init (error);
if (!mono_verifier_is_enabled_for_image (image))
return TRUE;
gboolean
mono_verifier_verify_method_signature (MonoImage *image, guint32 offset, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
return TRUE;
}
gboolean
mono_verifier_verify_typeref_row (MonoImage *image, guint32 row, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
return TRUE;
}
gboolean
mono_verifier_verify_methodimpl_row (MonoImage *image, guint32 row, MonoError *error)
{
- mono_error_init (error);
+ error_init (error);
return TRUE;
}