* Mono Project (http://www.mono-project.com)
*
* Copyright (C) 2005-2008 Novell, Inc. (http://www.novell.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include <mono/metadata/object-internals.h>
#include <mono/metadata/verify.h>
#include <mono/metadata/attrdefs.h>
#include <mono/utils/strenc.h>
#include <mono/utils/mono-error-internals.h>
+#include <mono/utils/bsearch.h>
#include <string.h>
//#include <signal.h>
#include <ctype.h>
5, /*tables*/
MONO_TABLE_TYPEDEF,
MONO_TABLE_TYPEREF,
- MONO_TABLE_MODULE,
+ MONO_TABLE_MODULEREF,
MONO_TABLE_METHOD,
MONO_TABLE_TYPESPEC,
return FALSE;
if (ctx->stage > STAGE_PE) {
- MonoCLIImageInfo *iinfo = ctx->image->image_info;
+ MonoCLIImageInfo *iinfo = (MonoCLIImageInfo *)ctx->image->image_info;
const int top = iinfo->cli_section_count;
MonoSectionTable *tables = iinfo->cli_section_tables;
int i;
DataDirectory it = ctx->data_directories [RESOURCE_TABLE_IDX];
guint32 offset;
guint16 named_entries, id_entries;
- const char *ptr, *root, *end;
+ const char *ptr;
if (it.rva == 0)
return;
ADD_ERROR (ctx, g_strdup_printf ("Resource section is too small, must be at least 16 bytes long but it's %d long", it.size));
offset = it.translated_offset;
- root = ptr = ctx->data + offset;
- end = root + it.size;
+ ptr = ctx->data + offset;
g_assert (offset != INVALID_OFFSET);
static DataDirectory
get_data_dir (VerifyContext *ctx, int idx)
{
- MonoCLIImageInfo *iinfo = ctx->image->image_info;
+ MonoCLIImageInfo *iinfo = (MonoCLIImageInfo *)ctx->image->image_info;
MonoPEDirEntry *entry= &iinfo->cli_header.datadir.pe_export_table;
DataDirectory res;
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;
base = tinfo->base;
VERIFIER_DEBUG ( printf ("looking token %x table %d col %d rsize %d roff %d\n", coded_token, table, column, locator.col_size, locator.col_offset) );
- res = bsearch (&locator, base, tinfo->rows, tinfo->row_size, token_locator);
+ res = (const char *)mono_binary_search (&locator, base, tinfo->rows, tinfo->row_size, token_locator);
if (!res)
return -1;
static gboolean
mono_verifier_is_corlib (MonoImage *image)
{
- gboolean trusted_location = (mono_security_get_mode () != MONO_SECURITY_MODE_CORE_CLR) ?
+ gboolean trusted_location = !mono_security_core_clr_enabled () ?
TRUE : mono_security_core_clr_is_platform_image (image);
return trusted_location && image->module_name && !strcmp ("mscorlib.dll", image->module_name);
if (!safe_read_cint (token, ptr, end))
FAIL (ctx, g_strdup ("CustomMod: Not enough room for the token"));
- if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, token))
+ if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, token) || !get_coded_index_token (TYPEDEF_OR_REF_DESC, token))
FAIL (ctx, g_strdup_printf ("CustomMod: invalid TypeDefOrRef token %x", token));
}
if (!safe_read_cint (token, ptr, end))
FAIL (ctx, g_strdup ("GenericInst: Not enough room for type token"));
- if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, token))
+ if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, token) || !get_coded_index_token (TYPEDEF_OR_REF_DESC, token))
FAIL (ctx, g_strdup_printf ("GenericInst: invalid TypeDefOrRef token %x", token));
if (ctx->token) {
FAIL (ctx, g_strdup ("GenericInst: Zero arguments generic instance"));
for (i = 0; i < count; ++i) {
+ if (!parse_custom_mods (ctx, &ptr, end))
+ FAIL (ctx, g_strdup ("Type: Failed to parse pointer custom attr"));
+
if (!parse_type (ctx, &ptr, end))
FAIL (ctx, g_strdup_printf ("GenericInst: invalid generic argument %d", i + 1));
}
if (!safe_read_cint (token, ptr, end))
FAIL (ctx, g_strdup ("Type: Not enough room for the type token"));
- if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, token))
+ if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, token) || !get_coded_index_token (TYPEDEF_OR_REF_DESC, token))
FAIL (ctx, g_strdup_printf ("Type: invalid TypeDefOrRef token %x", token));
+
+ if (!get_coded_index_token (TYPEDEF_OR_REF_DESC, token))
+ FAIL (ctx, g_strdup_printf ("Type: zero TypeDefOrRef token %x", token));
if (ctx->token) {
if (mono_metadata_token_index (ctx->token) == get_coded_index_token (TYPEDEF_OR_REF_DESC, token) &&
mono_metadata_token_table (ctx->token) == get_coded_index_table (TYPEDEF_OR_REF_DESC, token))
- FAIL (ctx, g_strdup_printf ("Type: Recurside type specification (%x). A type signature can't reference itself", ctx->token));
+ FAIL (ctx, g_strdup_printf ("Type: Recursive type specification (%x). A type signature can't reference itself", ctx->token));
}
break;
}
//it's a byref, update the cursor ptr
- if (type == MONO_TYPE_BYREF)
+ if (type == MONO_TYPE_BYREF) {
*_ptr = ptr;
+ if (!parse_custom_mods (ctx, _ptr, end))
+ return FALSE;
+ }
return parse_type (ctx, _ptr, end);
}
FAIL (ctx, g_strdup ("PropertySig: Could not parse property type"));
for (i = 0; i < param_count; ++i) {
+ if (!parse_custom_mods (ctx, &ptr, end))
+ FAIL (ctx, g_strdup ("Type: Failed to parse pointer custom attr"));
if (!parse_type (ctx, &ptr, end))
FAIL (ctx, g_strdup_printf ("PropertySig: Error parsing arg %d", i));
}
return parse_method_signature (ctx, &ptr, end, FALSE, FALSE);
}
+static gboolean
+is_valid_memberref_method_signature (VerifyContext *ctx, guint32 offset)
+{
+ guint32 size = 0;
+ const char *ptr = NULL, *end;
+
+ if (!decode_signature_header (ctx, offset, &size, &ptr))
+ FAIL (ctx, g_strdup ("MemberRefSig: Could not decode signature header"));
+ end = ptr + size;
+
+ return parse_method_signature (ctx, &ptr, end, TRUE, FALSE);
+}
+
+
static gboolean
is_valid_method_or_field_signature (VerifyContext *ctx, guint32 offset)
{
return NULL;
}
- enum_name = g_memdup (str_start, str_len + 1);
+ enum_name = (char *)g_memdup (str_start, str_len + 1);
enum_name [str_len] = 0;
type = mono_reflection_type_from_name (enum_name, ctx->image);
if (!type) {
klass = get_enum_by_encoded_name (ctx, &ptr, end);
if (!klass)
return FALSE;
+ } else if (etype == 0x50 || etype == MONO_TYPE_CLASS) {
+ klass = mono_defaults.systemtype_class;
} else if ((etype >= MONO_TYPE_BOOLEAN && etype <= MONO_TYPE_STRING) || etype == 0x51) {
- simple_type.type = etype == 0x51 ? MONO_TYPE_OBJECT : etype;
+ simple_type.type = etype == 0x51 ? MONO_TYPE_OBJECT : (MonoTypeEnum)etype;
klass = mono_class_from_mono_type (&simple_type);
} else
FAIL (ctx, g_strdup_printf ("CustomAttribute: Invalid array element type %x", etype));
FAIL (ctx, g_strdup_printf ("CustomAttribute: Not enough space for named parameter %d type", i));
if (kind >= MONO_TYPE_BOOLEAN && kind <= MONO_TYPE_STRING) {
- simple_type.type = kind;
+ simple_type.type = (MonoTypeEnum)kind;
type = &simple_type;
} else if (kind == MONO_TYPE_ENUM) {
MonoClass *klass = get_enum_by_encoded_name (ctx, &ptr, end);
klass = get_enum_by_encoded_name (ctx, &ptr, end);
if (!klass)
return FALSE;
+ } else if (etype == 0x50 || etype == MONO_TYPE_CLASS) {
+ klass = mono_defaults.systemtype_class;
} else if ((etype >= MONO_TYPE_BOOLEAN && etype <= MONO_TYPE_STRING) || etype == 0x51) {
- simple_type.type = etype == 0x51 ? MONO_TYPE_OBJECT : etype;
+ simple_type.type = etype == 0x51 ? MONO_TYPE_OBJECT : (MonoTypeEnum)etype;
klass = mono_class_from_mono_type (&simple_type);
} else
FAIL (ctx, g_strdup_printf ("CustomAttribute: Invalid array element type %x", etype));
FAIL (ctx, g_strdup ("MethodSpec: Zero generic argument count"));
for (i = 0; i < count; ++i) {
+ if (!parse_custom_mods (ctx, &ptr, end))
+ return FALSE;
if (!parse_type (ctx, &ptr, end))
FAIL (ctx, g_strdup_printf ("MethodSpec: Could not parse parameter %d", i + 1));
}
FAIL (ctx, g_strdup_printf ("MethodHeader: Invalid local vars signature table 0x%x", ((local_vars_tok >> 24) & 0xFF)));
if ((local_vars_tok & 0xFFFFFF) > ctx->image->tables [MONO_TABLE_STANDALONESIG].rows)
FAIL (ctx, g_strdup_printf ("MethodHeader: Invalid local vars signature points to invalid row 0x%x", local_vars_tok & 0xFFFFFF));
+ if (!(local_vars_tok & 0xFFFFFF))
+ FAIL (ctx, g_strdup_printf ("MethodHeader: Invalid local vars signature with zero index"));
*locals_token = local_vars_tok & 0xFFFFFF;
}
if (data [MONO_TYPEDEF_EXTENDS] && !is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, data [MONO_TYPEDEF_EXTENDS]))
ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row %d extend field coded index 0x%08x", i, data [MONO_TYPEDEF_EXTENDS]));
+ if (data [MONO_TYPEDEF_EXTENDS] && !get_coded_index_token (TYPEDEF_OR_REF_DESC, data [MONO_TYPEDEF_EXTENDS]))
+ ADD_ERROR (ctx, g_strdup_printf ("Invalid typedef row %d zero coded extend field coded index 0x%08x", i, data [MONO_TYPEDEF_EXTENDS]));
+
visibility = data [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_VISIBILITY_MASK;
if ((visibility >= TYPE_ATTRIBUTE_NESTED_PUBLIC && visibility <= TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM) &&
search_sorted_table (ctx, MONO_TABLE_NESTEDCLASS, MONO_NESTED_CLASS_NESTED, i + 1) == -1)
}
/*bits 8,9,10,11,13,14,15*/
-#define INVALID_METHOD_IMPLFLAG_BITS ((1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 13) | (1 << 14) | (1 << 15))
+#define INVALID_METHOD_IMPLFLAG_BITS ((1 << 9) | (1 << 10) | (1 << 11) | (1 << 13) | (1 << 14) | (1 << 15))
static void
verify_method_table (VerifyContext *ctx)
{
ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d is a global method but not Static", i));
if (flags & (METHOD_ATTRIBUTE_ABSTRACT | METHOD_ATTRIBUTE_VIRTUAL))
ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d is a global method but is Abstract or Virtual", i));
- if (!(access == METHOD_ATTRIBUTE_COMPILER_CONTROLLED || access == METHOD_ATTRIBUTE_PUBLIC || access == METHOD_ATTRIBUTE_PRIVATE))
- ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d is a global method but not CompilerControled, Public or Private", i));
+ if (access == METHOD_ATTRIBUTE_FAMILY || access == METHOD_ATTRIBUTE_FAM_AND_ASSEM || access == METHOD_ATTRIBUTE_FAM_OR_ASSEM)
+ ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d is a global method but not CompilerControled, Public, Private or Assembly", i));
}
//TODO check valuetype for synchronized
//TODO check signature contents
if (rva) {
- if (flags & METHOD_ATTRIBUTE_ABSTRACT)
- ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d has RVA != 0 but is Abstract", i));
+ if ((flags & (METHOD_ATTRIBUTE_ABSTRACT | METHOD_ATTRIBUTE_PINVOKE_IMPL)) || (implflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
+ ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d has RVA != 0 but is either Abstract, InternalCall or PinvokeImpl", i));
if (code_type == METHOD_IMPL_ATTRIBUTE_OPTIL)
ADD_ERROR (ctx, g_strdup_printf ("Invalid method row %d has RVA != 0 but is CodeTypeMask is neither Native, CIL or Runtime", i));
} else {
for (i = 0; i < table->rows; ++i) {
mono_metadata_decode_row (table, i, data, MONO_INTERFACEIMPL_SIZE);
if (data [MONO_INTERFACEIMPL_CLASS] && data [MONO_INTERFACEIMPL_CLASS] > ctx->image->tables [MONO_TABLE_TYPEDEF].rows)
- ADD_ERROR (ctx, g_strdup_printf ("Invalid InterfaceImpl row %d Class field 0x%08x", i, data [MONO_TABLE_TYPEDEF]));
+ ADD_ERROR (ctx, g_strdup_printf ("Invalid InterfaceImpl row %d Class field 0x%08x", i, data [MONO_INTERFACEIMPL_CLASS]));
if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, data [MONO_INTERFACEIMPL_INTERFACE]))
ADD_ERROR (ctx, g_strdup_printf ("Invalid InterfaceImpl row %d Inteface field coded index 0x%08x", i, data [MONO_INTERFACEIMPL_INTERFACE]));
if (!is_valid_coded_index (ctx, HAS_CATTR_DESC, data [MONO_CUSTOM_ATTR_PARENT]))
ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute row %d Parent field 0x%08x", i, data [MONO_CUSTOM_ATTR_PARENT]));
- if (!is_valid_coded_index (ctx, CATTR_TYPE_DESC, data [MONO_CUSTOM_ATTR_TYPE]))
- ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute row %d Parent field 0x%08x", i, data [MONO_CUSTOM_ATTR_PARENT]));
+ if (!is_valid_coded_index (ctx, CATTR_TYPE_DESC, data [MONO_CUSTOM_ATTR_TYPE]) || !get_coded_index_token (CATTR_TYPE_DESC, data [MONO_CUSTOM_ATTR_TYPE]))
+ ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute row %d Type field 0x%08x", i, data [MONO_CUSTOM_ATTR_TYPE]));
if (data [MONO_CUSTOM_ATTR_VALUE] && !is_valid_blob_object (ctx, data [MONO_CUSTOM_ATTR_VALUE], 0))
ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute row %d invalid value blob 0x%x", i, data [MONO_CUSTOM_ATTR_VALUE]));
static void
verify_cattr_table_full (VerifyContext *ctx)
{
+ MonoError error;
MonoTableInfo *table = &ctx->image->tables [MONO_TABLE_CUSTOMATTRIBUTE];
MonoMethod *ctor;
const char *ptr;
ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute constructor row %d Token 0x%08x", i, data [MONO_CUSTOM_ATTR_TYPE]));
}
- ctor = mono_get_method (ctx->image, mtoken, NULL);
+ ctor = mono_get_method_checked (ctx->image, mtoken, NULL, NULL, &error);
+
+ if (!ctor) {
+ ADD_ERROR (ctx, g_strdup_printf ("Invalid CustomAttribute content row %d Could not load ctor due to %s", i, mono_error_get_message (&error)));
+ mono_error_cleanup (&error);
+ }
/*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 (!found_add)
ADD_ERROR (ctx, g_strdup_printf ("Invalid Event row %d has no AddOn associated method", i));
if (!found_remove)
- ADD_ERROR (ctx, g_strdup_printf ("Invalid Event row %d has no AddOn associated method", i));
+ ADD_ERROR (ctx, g_strdup_printf ("Invalid Event row %d has no RemoveOn associated method", i));
}
}
mono_metadata_decode_row (table, i, data, MONO_MODULEREF_SIZE);
if (!is_valid_non_empty_string (ctx, data[MONO_MODULEREF_NAME]))
- ADD_ERROR (ctx, g_strdup_printf ("Invalid MethodImpl row %d Class field %08x", i, data [MONO_TABLE_TYPEDEF]));
+ ADD_ERROR (ctx, g_strdup_printf ("Invalid ModuleRef row %d name field %08x", i, data [MONO_MODULEREF_NAME]));
}
}
if (!is_valid_non_empty_string (ctx, data [MONO_IMPLMAP_NAME]))
ADD_ERROR (ctx, g_strdup_printf ("Invalid ImplMap row %d ImportName Token %x", i, data [MONO_IMPLMAP_NAME]));
- if (!data [MONO_IMPLMAP_SCOPE] || data [MONO_IMPLMAP_SCOPE] > ctx->image->tables [MONO_TABLE_MODULEREF].rows + 1)
+ if (!data [MONO_IMPLMAP_SCOPE] || data [MONO_IMPLMAP_SCOPE] > ctx->image->tables [MONO_TABLE_MODULEREF].rows)
ADD_ERROR (ctx, g_strdup_printf ("Invalid ImplMap row %d Invalid ImportScope token %x", i, data [MONO_IMPLMAP_SCOPE]));
}
}
}
}
-#define INVALID_ASSEMBLY_FLAGS_BITS ~((1 << 0) | (1 << 4) | (1 << 8) | (1 << 14) | (1 << 15))
+#define INVALID_ASSEMBLY_FLAGS_BITS ~((1 << 0) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 14) | (1 << 15))
static void
verify_assembly_table (VerifyContext *ctx)
{
}
}
-#define INVALID_ASSEMBLYREF_FLAGS_BITS ~(1)
+#define INVALID_ASSEMBLYREF_FLAGS_BITS ~((1 << 0) | (1 << 8) | (1 << 14) | (1 << 15))
static void
verify_assemblyref_table (VerifyContext *ctx)
{
static void
verify_manifest_resource_table (VerifyContext *ctx)
{
- MonoCLIImageInfo *iinfo = ctx->image->image_info;
+ MonoCLIImageInfo *iinfo = (MonoCLIImageInfo *)ctx->image->image_info;
MonoCLIHeader *ch = &iinfo->cli_cli_header;
MonoTableInfo *table = &ctx->image->tables [MONO_TABLE_MANIFESTRESOURCE];
guint32 data [MONO_MANIFEST_SIZE], impl_table, token, resources_size;
MonoTableInfo *table = &ctx->image->tables [MONO_TABLE_GENERICPARAMCONSTRAINT];
guint32 data [MONO_GENPARCONSTRAINT_SIZE];
int i;
+ guint32 last_owner = 0, last_constraint = 0;
for (i = 0; i < table->rows; ++i) {
mono_metadata_decode_row (table, i, data, MONO_GENPARCONSTRAINT_SIZE);
if (!data [MONO_GENPARCONSTRAINT_GENERICPAR] || data [MONO_GENPARCONSTRAINT_GENERICPAR] > ctx->image->tables [MONO_TABLE_GENERICPARAM].rows)
- ADD_ERROR (ctx, g_strdup_printf ("GenericParamConstraint table row %d has invalid Owner token %08x", i, data [MONO_TABLE_GENERICPARAM]));
+ ADD_ERROR (ctx, g_strdup_printf ("GenericParamConstraint table row %d has invalid Owner token %08x", i, data [MONO_GENPARCONSTRAINT_GENERICPAR]));
if (!is_valid_coded_index (ctx, TYPEDEF_OR_REF_DESC, data [MONO_GENPARCONSTRAINT_CONSTRAINT]))
ADD_ERROR (ctx, g_strdup_printf ("GenericParamConstraint table row %d has invalid Constraint token %08x", i, data [MONO_GENPARCONSTRAINT_CONSTRAINT]));
if (!get_coded_index_token (TYPEDEF_OR_REF_DESC, data [MONO_GENPARCONSTRAINT_CONSTRAINT]))
ADD_ERROR (ctx, g_strdup_printf ("GenericParamConstraint table row %d has null Constraint token", i));
+
+ if (last_owner > data [MONO_GENPARCONSTRAINT_GENERICPAR])
+ ADD_ERROR (ctx, g_strdup_printf ("GenericParamConstraint table row %d is not properly sorted. Previous value of the owner column is 0x%08x current value is 0x%08x", i, last_owner, data [MONO_GENPARCONSTRAINT_GENERICPAR]));
+
+ if (last_owner == data [MONO_GENPARCONSTRAINT_GENERICPAR]) {
+ if (last_constraint == data [MONO_GENPARCONSTRAINT_CONSTRAINT])
+ ADD_ERROR (ctx, g_strdup_printf ("GenericParamConstraint table row %d has duplicate constraint 0x%08x", i, last_constraint));
+ } else {
+ last_owner = data [MONO_GENPARCONSTRAINT_GENERICPAR];
+ }
+ last_constraint = data [MONO_GENPARCONSTRAINT_CONSTRAINT];
}
}
static guint
typedef_hash (gconstpointer _key)
{
- const TypeDefUniqueId *key = _key;
+ const TypeDefUniqueId *key = (const TypeDefUniqueId *)_key;
return g_str_hash (key->name) ^ g_str_hash (key->name_space) ^ key->resolution_scope; /*XXX better salt the int key*/
}
static gboolean
typedef_equals (gconstpointer _a, gconstpointer _b)
{
- const TypeDefUniqueId *a = _a;
- const TypeDefUniqueId *b = _b;
+ const TypeDefUniqueId *a = (const TypeDefUniqueId *)_a;
+ const TypeDefUniqueId *b = (const TypeDefUniqueId *)_b;
return !strcmp (a->name, b->name) && !strcmp (a->name_space, b->name_space) && a->resolution_scope == b->resolution_scope;
}
{
g_free (ctx->sections);
if (ctx->errors) {
- MonoVerifyInfo *info = ctx->errors->data;
+ MonoVerifyInfo *info = (MonoVerifyInfo *)ctx->errors->data;
mono_error_set_bad_image (error, ctx->image, "%s", info->message);
mono_free_verify_list (ctx->errors);
}
}
gboolean
-mono_verifier_verify_memberref_signature (MonoImage *image, guint32 offset, GSList **error_list)
+mono_verifier_verify_memberref_method_signature (MonoImage *image, guint32 offset, GSList **error_list)
{
VerifyContext ctx;
init_verify_context (&ctx, image, error_list != NULL);
ctx.stage = STAGE_TABLES;
- is_valid_method_or_field_signature (&ctx, offset);
+ is_valid_memberref_method_signature (&ctx, offset);
+ return cleanup_context (&ctx, error_list);
+}
+
+gboolean
+mono_verifier_verify_memberref_field_signature (MonoImage *image, guint32 offset, GSList **error_list)
+{
+ VerifyContext ctx;
+
+ if (!mono_verifier_is_enabled_for_image (image))
+ return TRUE;
+
+ init_verify_context (&ctx, image, error_list != NULL);
+ ctx.stage = STAGE_TABLES;
+
+ is_valid_field_signature (&ctx, offset);
return cleanup_context (&ctx, error_list);
}
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)
return TRUE;
if (row >= table->rows) {
- printf ("---1\n");
- g_assert (0);
mono_error_set_bad_image (error, image, "Invalid typeref row %d - table has %d rows", row, table->rows);
return FALSE;
}
mono_metadata_decode_row (table, row, data, MONO_TYPEREF_SIZE);
if (!is_valid_coded_index_with_image (image, RES_SCOPE_DESC, data [MONO_TYPEREF_SCOPE])) {
- printf ("---2\n");
mono_error_set_bad_image (error, image, "Invalid typeref row %d coded index 0x%08x", row, data [MONO_TYPEREF_SCOPE]);
return FALSE;
}
if (!get_coded_index_token (RES_SCOPE_DESC, data [MONO_TYPEREF_SCOPE])) {
- printf ("---3\n");
mono_error_set_bad_image (error, image, "The metadata verifier doesn't support null ResolutionScope tokens for typeref row %d", row);
return FALSE;
}
if (!data [MONO_TYPEREF_NAME] || !is_valid_string_full_with_image (image, data [MONO_TYPEREF_NAME], FALSE)) {
- printf ("---4\n");
mono_error_set_bad_image (error, image, "Invalid typeref row %d name token 0x%08x", row, data [MONO_TYPEREF_NAME]);
return FALSE;
}
if (data [MONO_TYPEREF_NAMESPACE] && !is_valid_string_full_with_image (image, data [MONO_TYPEREF_NAMESPACE], FALSE)) {
- printf ("---5\n");
mono_error_set_bad_image (error, image, "Invalid typeref row %d namespace token 0x%08x", row, data [MONO_TYPEREF_NAMESPACE]);
return FALSE;
}
return TRUE;
}
+/*Perform additional verification including metadata ones*/
+gboolean
+mono_verifier_verify_methodimpl_row (MonoImage *image, guint32 row, MonoError *error)
+{
+ MonoMethod *declaration, *body;
+ MonoMethodSignature *body_sig, *decl_sig;
+ MonoTableInfo *table = &image->tables [MONO_TABLE_METHODIMPL];
+ guint32 data [MONO_METHODIMPL_SIZE];
+
+ mono_error_init (error);
+
+ if (!mono_verifier_is_enabled_for_image (image))
+ return TRUE;
+
+ if (row >= table->rows) {
+ mono_error_set_bad_image (error, image, "Invalid methodimpl row %d - table has %d rows", row, table->rows);
+ return FALSE;
+ }
+
+ mono_metadata_decode_row (table, row, data, MONO_METHODIMPL_SIZE);
+
+ body = method_from_method_def_or_ref (image, data [MONO_METHODIMPL_BODY], NULL, error);
+ if (!body)
+ return FALSE;
+
+ declaration = method_from_method_def_or_ref (image, data [MONO_METHODIMPL_DECLARATION], NULL, error);
+ if (!declaration)
+ return FALSE;
+
+ /* FIXME
+ mono_class_setup_supertypes (class);
+ if (!mono_class_has_parent (class, body->klass)) {
+ mono_error_set_bad_image (error, image, "Invalid methodimpl body doesn't belong to parent for row %x", row);
+ return FALSE;
+ }*/
+
+ if (!(body_sig = mono_method_signature_checked (body, error))) {
+ return FALSE;
+ }
+
+ if (!(decl_sig = mono_method_signature_checked (declaration, error))) {
+ return FALSE;
+ }
+
+ if (!mono_verifier_is_signature_compatible (decl_sig, body_sig)) {
+ mono_error_set_bad_image (error, image, "Invalid methodimpl body signature not compatible with declaration row %x", row);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
#else
gboolean
mono_verifier_verify_table_data (MonoImage *image, GSList **error_list)
return TRUE;
}
-gboolean
-mono_verifier_verify_memberref_signature (MonoImage *image, guint32 offset, GSList **error_list)
-{
- return TRUE;
-}
-
gboolean
mono_verifier_verify_standalone_signature (MonoImage *image, guint32 offset, GSList **error_list)
{
mono_verifier_verify_typeref_row (MonoImage *image, guint32 row, MonoError *error)
{
mono_error_init (error);
+ return TRUE;
+}
+
+gboolean
+mono_verifier_verify_methodimpl_row (MonoImage *image, guint32 row, MonoError *error)
+{
+ mono_error_init (error);
+ return TRUE;
+}
+
+gboolean
+mono_verifier_verify_memberref_method_signature (MonoImage *image, guint32 offset, GSList **error_list)
+{
+ return TRUE;
+}
+
+gboolean
+mono_verifier_verify_memberref_field_signature (MonoImage *image, guint32 offset, GSList **error_list)
+{
+ return TRUE;
}
#endif /* DISABLE_VERIFIER */