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) {
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))
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)
{
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));
}
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)
//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 {
}
}
-#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)
{
}
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);
}
mono_metadata_decode_row (table, row, data, MONO_METHODIMPL_SIZE);
body = method_from_method_def_or_ref (image, data [MONO_METHODIMPL_BODY], NULL);
- if (mono_loader_get_last_error ()) {
+ if (!body || mono_loader_get_last_error ()) {
mono_loader_clear_error ();
mono_error_set_bad_image (error, image, "Invalid methodimpl body for row %x", row);
return FALSE;
}
declaration = method_from_method_def_or_ref (image, data [MONO_METHODIMPL_DECLARATION], NULL);
- if (mono_loader_get_last_error ()) {
+ if (!declaration || mono_loader_get_last_error ()) {
mono_loader_clear_error ();
mono_error_set_bad_image (error, image, "Invalid methodimpl declaration for row %x", row);
return FALSE;
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)
{
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 */