#define HAS_CATTR_DESC (HAS_CONSTANT_DESC + 5)
5, /*bits*/
- 19, /*tables*/
+ 20, /*tables*/
MONO_TABLE_METHOD,
MONO_TABLE_FIELD,
MONO_TABLE_TYPEREF,
MONO_TABLE_FILE,
MONO_TABLE_EXPORTEDTYPE,
MONO_TABLE_MANIFESTRESOURCE,
+ MONO_TABLE_GENERICPARAM,
-#define HAS_FIELD_MARSHAL_DESC (HAS_CATTR_DESC + 21)
+#define HAS_FIELD_MARSHAL_DESC (HAS_CATTR_DESC + 22)
1, /*bits*/
2, /*tables*/
MONO_TABLE_FIELD,
if (signature != 0x06)
FAIL (ctx, g_strdup_printf ("Field: Invalid signature 0x%x, must be 6", signature));
- *_ptr = ptr;
- if (!parse_custom_mods (ctx, _ptr, end))
+ if (!parse_custom_mods (ctx, &ptr, end))
return FALSE;
+ if (safe_read8 (signature, ptr, end)) {
+ if (signature != MONO_TYPE_BYREF)
+ --ptr;
+ }
+ *_ptr = ptr;
+
return parse_type (ctx, _ptr, end);
}
if (!safe_read_cint (locals_count, ptr, end))
FAIL (ctx, g_strdup ("LocalsSig: Not enough room for the param count"));
+ /* LAMEIMPL: MS sometimes generates empty local signatures and its verifier is ok with.
if (locals_count == 0)
FAIL (ctx, g_strdup ("LocalsSig: Signature with zero locals"));
+ */
for (i = 0; i < locals_count; ++i) {
if (!safe_read8 (sig, ptr, end))
FAIL (ctx, g_strdup ("LocalsSig: Not enough room for type"));
- if (sig == MONO_TYPE_TYPEDBYREF)
- continue;
-
while (sig == MONO_TYPE_CMOD_REQD || sig == MONO_TYPE_CMOD_OPT || sig == MONO_TYPE_PINNED) {
if (sig != MONO_TYPE_PINNED && !parse_custom_mods (ctx, &ptr, end))
FAIL (ctx, g_strdup_printf ("LocalsSig: Error parsing local %d", i));
if (!safe_read8 (sig, ptr, end))
FAIL (ctx, g_strdup ("LocalsSig: Not enough room for type"));
}
+
+ if (sig == MONO_TYPE_BYREF) {
+ if (!safe_read8 (sig, ptr, end))
+ FAIL (ctx, g_strdup_printf ("Type: Not enough room for byref type for local %d", i));
+ if (sig == MONO_TYPE_TYPEDBYREF)
+ FAIL (ctx, g_strdup_printf ("Type: Invalid type typedref& for local %d", i));
+ }
+
+ if (sig == MONO_TYPE_TYPEDBYREF)
+ continue;
+
--ptr;
+
if (!parse_type (ctx, &ptr, end))
FAIL (ctx, g_strdup_printf ("LocalsSig: Error parsing local %d", i));
}
if (!safe_read8 (type, ptr, end))
FAIL (ctx, g_strdup ("TypeSpec: Not enough room for type"));
- --ptr;
+ if (type == MONO_TYPE_BYREF) {
+ if (!safe_read8 (type, ptr, end))
+ FAIL (ctx, g_strdup ("TypeSpec: Not enough room for byref type"));
+ if (type == MONO_TYPE_TYPEDBYREF)
+ FAIL (ctx, g_strdup ("TypeSpec: Invalid type typedref&"));
+ }
+
if (type == MONO_TYPE_TYPEDBYREF)
return TRUE;
+ --ptr;
return parse_type (ctx, &ptr, end);
}
}
static gboolean
-is_valid_blob_object (VerifyContext *ctx, guint32 offset, int minsize)
+is_valid_blob_object (VerifyContext *ctx, guint32 offset, guint32 minsize)
{
OffsetAndSize blob = get_metadata_stream (ctx, &ctx->image->heap_blob);
guint32 entry_size, bytes;
if (!decode_value (ctx->data + offset + blob.offset, blob.size - blob.offset, &entry_size, &bytes))
return FALSE;
- if (CHECK_ADD4_OVERFLOW_UN (entry_size, bytes))
+ if (entry_size < minsize)
return FALSE;
- entry_size += bytes;
- if (CHECK_ADD4_OVERFLOW_UN (entry_size, minsize))
+ if (CHECK_ADD4_OVERFLOW_UN (entry_size, bytes))
return FALSE;
- entry_size += minsize;
+ entry_size += bytes;
return !ADD_IS_GREATER_OR_OVF (offset, entry_size, blob.size);
}
/* only verify the class token is verified as the rest is done by the IL verifier*/
for (i = 0; i < clauses; ++i) {
+ guint flags = *ptr;
guint32 class_token = 0;
ptr += (is_fat ? 20 : 8);
if (!safe_read32 (class_token, ptr, end))
FAIL (ctx, g_strdup_printf ("MethodHeader: Not enough room for section %d", i));
- if (!*ptr == MONO_EXCEPTION_CLAUSE_NONE && class_token) {
+ if (flags == MONO_EXCEPTION_CLAUSE_NONE && class_token) {
guint table = mono_metadata_token_table (class_token);
if (table != MONO_TABLE_TYPEREF && table != MONO_TABLE_TYPEDEF && table != MONO_TABLE_TYPESPEC)
FAIL (ctx, g_strdup_printf ("MethodHeader: Invalid section %d class token table %x", i, table));
return cleanup_context (&ctx, error_list);
}
+gboolean
+mono_verifier_verify_standalone_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);
+ ctx.stage = STAGE_TABLES;
+
+ is_valid_standalonesig_blob (&ctx, offset);
+ return cleanup_context (&ctx, error_list);
+}
+
+gboolean
+mono_verifier_verify_typespec_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);
+ ctx.stage = STAGE_TABLES;
+
+ is_valid_typespec_blob (&ctx, offset);
+ return cleanup_context (&ctx, error_list);
+}
+
+gboolean
+mono_verifier_verify_methodspec_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);
+ ctx.stage = STAGE_TABLES;
+
+ is_valid_methodspec_blog (&ctx, offset);
+ return cleanup_context (&ctx, error_list);
+}
+
#else
gboolean
mono_verifier_verify_table_data (MonoImage *image, GSList **error_list)
return TRUE;
}
+gboolean
+mono_verifier_verify_standalone_signature (MonoImage *image, guint32 offset, GSList **error_list)
+{
+ return TRUE;
+}
+
+gboolean
+mono_verifier_verify_typespec_signature (MonoImage *image, guint32 offset, GSList **error_list)
+{
+ return TRUE;
+}
+
+gboolean
+mono_verifier_verify_methodspec_signature (MonoImage *image, guint32 offset, GSList **error_list)
+{
+ return TRUE;
+}
+
#endif /* DISABLE_VERIFIER */