Author: kumpera
Date: 2007-06-13 08:41:37 -0400 (Wed, 13 Jun 2007)
New Revision: 79403
Modified:
trunk/mono/mono/metadata/ChangeLog
trunk/mono/mono/metadata/verify.c
Log:
2007-06-13 Rodrigo Kumpera <[EMAIL PROTECTED]>
* verify.c: method invocation is now validated, now we verify parameter
types on stack.
Fixed overflow and underflow not aborting the verification process.
Modified: trunk/mono/mono/metadata/ChangeLog
===================================================================
--- trunk/mono/mono/metadata/ChangeLog 2007-06-13 12:28:20 UTC (rev 79402)
+++ trunk/mono/mono/metadata/ChangeLog 2007-06-13 12:41:37 UTC (rev 79403)
@@ -1,3 +1,8 @@
+2007-06-13 Rodrigo Kumpera <[EMAIL PROTECTED]>
+
+ * verify.c: method invocation is now validated, now we verify parameter
types on stack.
+ Fixed overflow and underflow not aborting the verification process.
+
2007-06-13 Mark Probst <[EMAIL PROTECTED]>
* class-internals.h (MonoStats): Added stats entries for dynamic
Modified: trunk/mono/mono/metadata/verify.c
===================================================================
--- trunk/mono/mono/metadata/verify.c 2007-06-13 12:28:20 UTC (rev 79402)
+++ trunk/mono/mono/metadata/verify.c 2007-06-13 12:41:37 UTC (rev 79403)
@@ -40,7 +40,7 @@
vinfo->message = ( __msg ); \
(__ctx)->list = g_slist_prepend ((__ctx)->list, vinfo); \
} while (0)
-
+
#define ADD_VERIFY_ERROR(__ctx, __msg) ADD_VERIFY_INFO(__ctx, __msg,
MONO_VERIFY_ERROR)
enum {
@@ -68,18 +68,21 @@
int code_size;
ILCodeDesc *code;
ILCodeDesc eval;
-
+
MonoType **params;
GSList *list;
-
+
int num_locals;
MonoType **locals;
-
+
int target;
-
+
guint32 ip_offset;
MonoMethodSignature *signature;
MonoMethodHeader *header;
+
+ MonoGenericContext *generic_context;
+ MonoImage *image;
} VerifyContext;
//////////////////////////////////////////////////////////////////
@@ -98,14 +101,14 @@
TYPE_COMPLEX = 6,
/* Number of types, used to define the size of the tables*/
TYPE_MAX = 8, /* FIXME: This should probably be 7, but would
require all the tables to be updated */
-
+
/* Used by tables to signal that a result is not verifiable*/
NON_VERIFIABLE_RESULT = 0x80,
/*Mask used to extract just the type, excluding flags */
TYPE_MASK = 0x0F,
-
-
+
+
/* The stack type is a pointer, unmask the value to res */
POINTER_MASK = 0x100,
/* Controlled Mutability Manager Pointer */
@@ -208,7 +211,7 @@
{
int i;
int found;
-
+
found = *cname == 0;
for (i = 0; i < G_N_ELEMENTS (valid_cultures); ++i) {
if (g_strcasecmp (valid_cultures [i], cname)) {
@@ -231,7 +234,7 @@
{
guint32 size;
const char *p, *blob_end;
-
+
if (blob_index >= image->heap_blob.size)
return 0;
p = mono_metadata_blob_heap (image, blob_index);
@@ -247,7 +250,7 @@
is_valid_string (MonoImage *image, guint32 str_index, int notnull)
{
const char *p, *blob_end, *res;
-
+
if (str_index >= image->heap_strings.size)
return NULL;
res = p = mono_metadata_string_heap (image, str_index);
@@ -303,7 +306,7 @@
if (t->rows > 1)
ADD_ERROR (list, g_strdup ("Assembly table may only
have 0 or 1 rows"));
mono_metadata_decode_row (t, 0, cols, MONO_ASSEMBLY_SIZE);
-
+
switch (cols [MONO_ASSEMBLY_HASH_ALG]) {
case ASSEMBLY_HASH_NONE:
case ASSEMBLY_HASH_MD5:
@@ -312,13 +315,13 @@
default:
ADD_ERROR (list, g_strdup_printf ("Hash algorithm 0x%x
unknown", cols [MONO_ASSEMBLY_HASH_ALG]));
}
-
+
if (!is_valid_assembly_flags (cols [MONO_ASSEMBLY_FLAGS]))
ADD_ERROR (list, g_strdup_printf ("Invalid flags in
assembly: 0x%x", cols [MONO_ASSEMBLY_FLAGS]));
-
+
if (!is_valid_blob (image, cols [MONO_ASSEMBLY_PUBLIC_KEY],
FALSE))
ADD_ERROR (list, g_strdup ("Assembly public key is an
invalid index"));
-
+
if (!(p = is_valid_string (image, cols [MONO_ASSEMBLY_NAME],
TRUE))) {
ADD_ERROR (list, g_strdup ("Assembly name is invalid"));
} else {
@@ -349,10 +352,10 @@
mono_metadata_decode_row (t, i, cols,
MONO_ASSEMBLYREF_SIZE);
if (!is_valid_assembly_flags (cols
[MONO_ASSEMBLYREF_FLAGS]))
ADD_ERROR (list, g_strdup_printf ("Invalid
flags in assemblyref row %d: 0x%x", i + 1, cols [MONO_ASSEMBLY_FLAGS]));
-
+
if (!is_valid_blob (image, cols
[MONO_ASSEMBLYREF_PUBLIC_KEY], FALSE))
ADD_ERROR (list, g_strdup_printf ("AssemblyRef
public key in row %d is an invalid index", i + 1));
-
+
if (!(p = is_valid_string (image, cols
[MONO_ASSEMBLYREF_CULTURE], FALSE))) {
ADD_ERROR (list, g_strdup_printf ("AssemblyRef
culture in row %d is invalid", i + 1));
} else {
@@ -379,7 +382,7 @@
MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
guint32 cols [MONO_CLASS_LAYOUT_SIZE];
guint32 value, i;
-
+
if (level & MONO_VERIFY_ERROR) {
for (i = 0; i < t->rows; ++i) {
mono_metadata_decode_row (t, i, cols,
MONO_CLASS_LAYOUT_SIZE);
@@ -421,7 +424,7 @@
}
}
}
-
+
return list;
}
@@ -432,7 +435,7 @@
guint32 cols [MONO_CONSTANT_SIZE];
guint32 value, i;
GHashTable *dups = g_hash_table_new (NULL, NULL);
-
+
for (i = 0; i < t->rows; ++i) {
mono_metadata_decode_row (t, i, cols, MONO_CONSTANT_SIZE);
@@ -535,7 +538,7 @@
guint32 cols [MONO_EVENT_SIZE];
const char *p;
guint32 value, i;
-
+
for (i = 0; i < t->rows; ++i) {
mono_metadata_decode_row (t, i, cols, MONO_EVENT_SIZE);
@@ -552,7 +555,7 @@
ADD_WARN (list, MONO_VERIFY_CLS,
g_strdup_printf ("Invalid CLS name '%s` in Event row %d", p, i + 1));
}
}
-
+
if (level & MONO_VERIFY_ERROR && cols [MONO_EVENT_TYPE]) {
value = cols [MONO_EVENT_TYPE] >>
MONO_TYPEDEFORREF_BITS;
switch (cols [MONO_EVENT_TYPE] &
MONO_TYPEDEFORREF_MASK) {
@@ -590,7 +593,7 @@
guint32 cols [MONO_FIELD_SIZE];
const char *p;
guint32 i, flags;
-
+
for (i = 0; i < t->rows; ++i) {
mono_metadata_decode_row (t, i, cols, MONO_FIELD_SIZE);
/*
@@ -641,8 +644,8 @@
* public or private (not allowed in cls mode).
* if owner is an enum ...
*/
-
-
+
+
}
return list;
}
@@ -655,7 +658,7 @@
const char *p;
guint32 i;
GHashTable *dups = g_hash_table_new (g_str_hash, g_str_equal);
-
+
for (i = 0; i < t->rows; ++i) {
mono_metadata_decode_row (t, i, cols, MONO_FILE_SIZE);
if (level & MONO_VERIFY_ERROR) {
@@ -701,7 +704,7 @@
const char *p, *pf;
guint32 found, i, j, value;
GHashTable *dups = g_hash_table_new (g_str_hash, g_str_equal);
-
+
for (i = 0; i < t->rows; ++i) {
mono_metadata_decode_row (t, i, cols, MONO_MODULEREF_SIZE);
if (!(p = is_valid_string (image, cols [MONO_MODULEREF_NAME],
TRUE))) {
@@ -1345,10 +1348,10 @@
if (value->stype & CMMP_MASK)
printf ("Controled Mutability MP: ");
-
+
if (value->stype & POINTER_MASK)
printf ("Managed Pointer: ");
-
+
switch (value->stype & TYPE_MASK) {
case TYPE_INV:
printf ("invalid type]");
@@ -1381,7 +1384,7 @@
dump_stack_state (ILCodeDesc *state)
{
int i;
-
+
printf ("(%d) ", state->size);
for (i = 0; i < state->size; ++i)
dump_stack_value (state->stack + i);
@@ -1414,12 +1417,12 @@
g_assert (target->type == MONO_TYPE_ARRAY);
g_assert (candidate->type == MONO_TYPE_ARRAY);
-
+
if ((left->rank != right->rank) ||
(left->numsizes != right->numsizes) ||
(left->numlobounds != right->numlobounds))
return FALSE;
-
+
for (i = 0; i < left->numsizes; ++i)
if (left->sizes [i] != right->sizes [i])
return FALSE;
@@ -1455,23 +1458,23 @@
case MONO_TYPE_I:
case MONO_TYPE_U:
return TYPE_NATIVE_INT | mask;
-
+
case MONO_TYPE_PTR:
mask = POINTER_MASK;
type = type->type;
t = type->type;
goto handle_enum;
-
+
case MONO_TYPE_CLASS:
case MONO_TYPE_STRING:
case MONO_TYPE_OBJECT:
case MONO_TYPE_SZARRAY:
case MONO_TYPE_ARRAY:
case MONO_TYPE_TYPEDBYREF:
-
+
/* TODO verify if this case is correct */
case MONO_TYPE_FNPTR:
-
+
case MONO_TYPE_GENERICINST:
return TYPE_COMPLEX | mask;
@@ -1526,24 +1529,24 @@
case MONO_TYPE_U:
stack->stype = TYPE_NATIVE_INT | mask;
return;
-
+
case MONO_TYPE_PTR:
mask = POINTER_MASK;
/* We should use the underlying pointer type */
stack->type = type = type->type;
t = type->type;
goto handle_enum;
-
+
case MONO_TYPE_CLASS:
case MONO_TYPE_STRING:
case MONO_TYPE_OBJECT:
case MONO_TYPE_SZARRAY:
case MONO_TYPE_ARRAY:
case MONO_TYPE_TYPEDBYREF:
-
+
//TODO verify if this case is correct
case MONO_TYPE_FNPTR:
-
+
case MONO_TYPE_GENERICINST:
stack->stype = TYPE_COMPLEX | mask;
return;
@@ -1569,7 +1572,6 @@
}
return;
}
-
/* Generics validation stuff, should be moved to another metadata/? file */
static gboolean
@@ -1588,7 +1590,7 @@
case MONO_TYPE_CLASS:
if (candidate->type != MONO_TYPE_CLASS)
return FALSE;
-
+
VERIFIER_DEBUG ( printf ("verifying type class%d %d\n",
target->data.klass, candidate->data.klass); );
return mono_class_is_assignable_from (target->data.klass,
candidate->data.klass);
@@ -1600,7 +1602,7 @@
if (candidate->type != MONO_TYPE_SZARRAY)
return FALSE;
return mono_class_is_assignable_from (target->data.klass,
candidate->data.klass);
-
+
case MONO_TYPE_VALUETYPE:
if (target->data.klass->enumtype) {
target = target->data.klass->enum_basetype->type;
@@ -1615,12 +1617,12 @@
if (candidate->type != MONO_TYPE_ARRAY)
return FALSE;
return is_array_type_compatible (target, candidate);
-
+
default:
VERIFIER_DEBUG ( printf ("unknown target type %d\n",
target->type); );
g_assert_not_reached ();
}
-
+
return FALSE;
}
@@ -1629,7 +1631,7 @@
mono_is_generic_instance_compatible (MonoGenericClass *target,
MonoGenericClass *candidate, MonoGenericClass *root_candidate) {
MonoGenericContainer *container;
int i;
-
+
VERIFIER_DEBUG ( printf ("candidate container %d\n",
candidate->container_class->generic_container); );
if (target->container_class != candidate->container_class) {
MonoType *param_class;
@@ -1638,11 +1640,11 @@
param_class = candidate->inst->type_argv[0];
VERIFIER_DEBUG ( printf ("param 0 %d\n", param_class->type); );
cand_class = candidate->container_class;
-
+
/* We must check if it's an interface type*/
if (MONO_CLASS_IS_INTERFACE (target->container_class)) {
VERIFIER_DEBUG ( printf ("generic type is an
interface\n"); );
-
+
do {
int iface_count = cand_class->interface_count;
MonoClass **ifaces = cand_class->interfaces;
@@ -1659,17 +1661,17 @@
return TRUE;
}
}
-
+
cand_class = cand_class->parent;
} while (cand_class);
VERIFIER_DEBUG ( printf ("don't implements an
interface\n"); );
-
+
} else {
VERIFIER_DEBUG ( printf ("verifying upper classes\n");
);
-
+
cand_class = cand_class->parent;
-
+
while (cand_class) {
VERIFIER_DEBUG ( printf ("verifying parent
class name %s\n", cand_class->name); );
if (cand_class->generic_class) {
@@ -1684,22 +1686,22 @@
}
return FALSE;
}
-
+
/* now we verify if the instantiations are compatible*/
if (target->inst == candidate->inst) {
VERIFIER_DEBUG ( printf ("generic types are compatible, both
have the same instantiation\n"); );
return TRUE;
}
-
+
if (target->inst->type_argc != candidate->inst->type_argc) {
VERIFIER_DEBUG ( printf ("generic instantiations with diferent
arg counts\n"); );
return FALSE;
}
-
+
//verify if open instance -- none should be
-
+
container = target->container_class->generic_container;
-
+
for (i = 0; i < container->type_argc; ++i) {
MonoGenericParam *param = container->type_params + i;
MonoType *target_type = target->inst->type_argv [i];
@@ -1720,7 +1722,7 @@
VERIFIER_DEBUG ( printf ("generic type has variance
flag, need to perform hierarquical check\n"); );
/* first we check if they are the same kind */
/* byref generic params are forbiden, but better safe
than sorry.*/
-
+
if ((param->flags &
GENERIC_PARAMETER_ATTRIBUTE_COVARIANT) == GENERIC_PARAMETER_ATTRIBUTE_COVARIANT)
return mono_is_generic_type_compatible
(target_type, candidate_type);
else /* the attribute must be contravariant */
@@ -1739,7 +1741,7 @@
static gboolean
verify_stack_type_compatibility (VerifyContext *ctx, MonoType *target,
MonoType *candidate, gboolean strict) {
VERIFIER_DEBUG ( printf ("checking type compatibility %d %d %d\n", ctx,
target, candidate); );
-
+
if (candidate->byref) {
if (get_stack_type (target) == TYPE_NATIVE_INT) {
ctx->verifiable = 0;
@@ -1767,7 +1769,7 @@
if (strict)
return candidate->type == target->type;
return get_stack_type (candidate) == TYPE_I8;
-
+
case MONO_TYPE_R4:
case MONO_TYPE_R8:
if (strict)
@@ -1779,7 +1781,7 @@
if (strict)
return candidate->type == target->type;
return get_stack_type (target) == TYPE_NATIVE_INT;
-
+
case MONO_TYPE_PTR:
if (candidate->type != MONO_TYPE_PTR)
return FALSE;
@@ -1804,7 +1806,7 @@
if (candidate->type != MONO_TYPE_CLASS)
return FALSE;
return mono_class_is_assignable_from (target->data.klass,
candidate->data.klass);
-
+
case MONO_TYPE_OBJECT:
return MONO_TYPE_IS_REFERENCE (candidate);
@@ -1877,7 +1879,7 @@
case MONO_TYPE_I8:
case MONO_TYPE_U8:
return stack_type == TYPE_I8;
-
+
case MONO_TYPE_R4:
case MONO_TYPE_R8:
return stack_type == TYPE_R8;
@@ -1885,7 +1887,7 @@
case MONO_TYPE_I:
case MONO_TYPE_U:
return stack_type == TYPE_NATIVE_INT;
-
+
case MONO_TYPE_PTR:
if ((stack_type & POINTER_MASK) == 0)
return FALSE;
@@ -1924,7 +1926,7 @@
return FALSE;
return mono_class_is_assignable_from (type->data.klass,
stack->type->data.klass);
-
+
case MONO_TYPE_OBJECT:
if (stack_type != TYPE_COMPLEX)
return FALSE;
@@ -1975,7 +1977,7 @@
return FALSE;
return stack->type->data.klass == type->data.klass;
}
-
+
default:
printf("unknown store type %d\n", type->type);
g_assert_not_reached ();
@@ -2009,7 +2011,7 @@
store_arg (VerifyContext *ctx, guint32 arg)
{
ILStackDesc *value;
-
+
if (arg >= ctx->max_args) {
ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Method doesn't have
local var %d at 0x%04x", arg + 1, ctx->ip_offset));
return;
@@ -2047,38 +2049,38 @@
ILStackDesc *a, *b;
int idxa, idxb, complexMerge = 0;
unsigned char res;
-
+
if (!check_underflow (ctx, 2))
return;
a = stack_get (ctx, 1);
b = stack_top (ctx);
-
+
idxa = a->stype;
if (idxa & POINTER_MASK) {
idxa = TYPE_PTR;
complexMerge = 1;
}
-
+
idxb = b->stype;
if (idxb & POINTER_MASK) {
idxb = TYPE_PTR;
complexMerge = 2;
}
-
+
--idxa;
--idxb;
res = table [idxa][idxb];
VERIFIER_DEBUG ( printf ("binop res %d\n", res); );
VERIFIER_DEBUG ( printf ("idxa %d idxb %d\n", idxa, idxb); );
-
+
if (res == TYPE_INV) {
ADD_VERIFY_ERROR(ctx, g_strdup_printf (
"Binary instruction applyed to ill formed stack (%s x
%s)",
type_names [idxa & TYPE_MASK], type_names [idxb &
TYPE_MASK]));
return;
}
-
+
if (res & NON_VERIFIABLE_RESULT) {
ctx->verifiable = 0;
res = res & ~NON_VERIFIABLE_RESULT;
@@ -2108,41 +2110,42 @@
int idxa, idxb;
unsigned char res;
int target = ctx->ip_offset + delta;
-
+
VERIFIER_DEBUG ( printf ("branch offset %d delta %d target %d\n",
ctx->ip_offset, delta, target); );
-
+
if (target < 0 || target >= ctx->code_size) {
ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Branch target out of
code at 0x%04x", ctx->ip_offset));
return;
}
+
if (!in_same_block (ctx->header, ctx->ip_offset, target)) {
ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Branch target escapes
out of exception block at 0x%04x", ctx->ip_offset));
return;
}
-
+
ctx->target = target;
-
+
if (!check_underflow (ctx, 2))
return;
b = stack_pop (ctx);
a = stack_pop (ctx);
-
+
idxa = a->stype;
if (idxa & POINTER_MASK)
idxa = TYPE_PTR;
-
+
idxb = b->stype;
if (idxb & POINTER_MASK)
idxb = TYPE_PTR;
-
+
--idxa;
--idxb;
res = table [idxa][idxb];
VERIFIER_DEBUG ( printf ("branch res %d\n", res); );
VERIFIER_DEBUG ( printf ("idxa %d idxb %d\n", idxa, idxb); );
-
+
if (res == TYPE_INV) {
ADD_VERIFY_ERROR (ctx,
g_strdup_printf ("Compare and Branch instruction
applyed to ill formed stack (%s x %s) at 0x%04x",
@@ -2159,27 +2162,27 @@
ILStackDesc *a, *b;
int idxa, idxb;
unsigned char res;
-
+
if (!check_underflow (ctx, 2))
return;
b = stack_pop (ctx);
a = stack_pop (ctx);
-
+
idxa = a->stype;
if (idxa & POINTER_MASK)
idxa = TYPE_PTR;
-
+
idxb = b->stype;
if (idxb & POINTER_MASK)
idxb = TYPE_PTR;
-
+
--idxa;
--idxb;
res = table [idxa][idxb];
printf("binop res %d\n", res);
printf("idxa %d idxb %d\n", idxa, idxb);
-
+
if(res == TYPE_INV) {
ADD_VERIFY_ERROR (ctx, g_strdup_printf("Compare and Branch
instruction applyed to ill formed stack (%s x %s) at 0x%04x", type_names [idxa
& TYPE_MASK], type_names [idxb & TYPE_MASK], ctx->ip_offset));
return;
@@ -2198,28 +2201,78 @@
ILStackDesc *top;
if (!check_underflow (ctx, 1))
return;
-
+
top = stack_pop(ctx);
-
+
if (!verify_type_compat (ctx, ctx->signature->ret, top)) {
ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Incompatible
return value on stack with method signature ret at 0x%04x", ctx->ip_offset));
return;
}
}
-
+
if (ctx->eval.size > 0) {
ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Stack not empty (%d)
after ret at 0x%04x", ctx->eval.size, ctx->ip_offset));
} else if (in_any_block (ctx->header, ctx->ip_offset))
ADD_VERIFY_ERROR (ctx, g_strdup_printf ("ret cannot escape
exception blocks at 0x%04x", ctx->ip_offset));
}
+/* FIXME: we could just load the signature instead of the whole MonoMethod
+ * TODO handle vararg calls
+ * TODO handle non virt calls to non-final virtual calls (from the
verifiability clause in page 52 of partition 3)
+ */
+static void
+do_invoke_method (VerifyContext *ctx, int method_token)
+{
+ int param_count, i;
+ MonoMethodSignature *sig;
+ ILStackDesc *value;
+ MonoMethod *method = mono_get_method_full (ctx->image, method_token,
NULL, ctx->generic_context);
+
+ if (!method) {
+ ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Method 0x%08x not
found at 0x%04x", method_token, ctx->ip_offset));
+ return;
+ }
+
+ if (!(sig = mono_method_signature (method)))
+ sig = mono_method_get_signature (method, ctx->image,
method_token);
+
+ param_count = sig->param_count + sig->hasthis;
+ if (!check_underflow (ctx, param_count))
+ return;
+
+ for (i = sig->param_count - 1; i >= 0; --i) {
+ VERIFIER_DEBUG ( printf ("verifying argument %d\n", i); );
+ value = stack_pop (ctx);
+ if (!verify_type_compat (ctx, sig->params[i], value)) {
+ ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Incompatible
parameter value with function signature at 0x%04x", ctx->ip_offset));
+ return;
+ }
+ }
+
+ if (sig->hasthis) {
+ MonoType * type = method->klass->valuetype ?
&method->klass->this_arg : &method->klass->byval_arg;
+
+ VERIFIER_DEBUG ( printf ("verifying this argument\n"); );
+ value = stack_pop (ctx);
+ if (!verify_type_compat (ctx, type, value)) {
+ ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Incompatible
return value on stack with method signature ret at 0x%04x", ctx->ip_offset));
+ return;
+ }
+ }
+
+ if (sig->ret->type != MONO_TYPE_VOID) {
+ if (check_overflow (ctx))
+ set_stack_value (stack_push (ctx), sig->ret, FALSE);
+ }
+}
+
/*Merge the stacks and perform compat checks*/
static void
merge_stacks (VerifyContext *ctx, ILCodeDesc *from, ILCodeDesc *to, int start)
{
int i;
-
+
if (to->flags == IL_CODE_FLAG_NOT_PROCESSED)
stack_init (ctx, to);
@@ -2234,7 +2287,7 @@
goto end_verify;
}
VERIFIER_DEBUG ( printf ("performing stack merge %d x %d\n",
from->size, to->size); );
-
+
if (from->size != to->size) {
VERIFIER_DEBUG ( printf ("diferent stack sizes %d x %d\n",
from->size, to->size); );
ctx->verifiable = 0;
@@ -2246,24 +2299,24 @@
ILStackDesc *to_slot = to->stack + i;
int from_stype = from_slot->stype;
int to_stype = to_slot->stype;
-
+
if (from_stype != to_stype) {
VERIFIER_DEBUG ( printf ("diferent stack types %d x
%d\n", from_stype, to_stype); );
ctx->verifiable = 0;
continue;
}
-
+
if (from_stype & POINTER_MASK) {
from_stype &= ~POINTER_MASK;
to_stype &= ~POINTER_MASK;
-
+
if (from_slot->type && !
verify_stack_type_compatibility (ctx, to_slot->type, from_slot->type, TRUE)) {
ctx->verifiable = 0;
} else
copy_stack_value (to_slot, from_slot);
continue;
}
-
+
if (from_stype == TYPE_COMPLEX) {
if (!to->stack [i].type) {
ctx->verifiable = 0;
@@ -2276,10 +2329,10 @@
}
continue;
}
-
+
copy_stack_value (to_slot, from_slot);
}
-
+
end_verify:
to->flags = IL_CODE_FLAG_SEEN;
}
@@ -2305,19 +2358,19 @@
MonoGenericContext *generic_context = NULL;
MonoImage *image;
VerifyContext ctx;
-
+
if (method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL |
METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
(method->flags & (METHOD_ATTRIBUTE_PINVOKE_IMPL |
METHOD_ATTRIBUTE_ABSTRACT))) {
return NULL;
}
-
+
memset (&ctx, 0, sizeof (VerifyContext));
ctx.signature = mono_method_signature (method);
ctx.header = mono_method_get_header (method);
ip = ctx.header->code;
end = ip + ctx.header->code_size;
- image = method->klass->image;
+ ctx.image = image = method->klass->image;
ctx.max_args = ctx.signature->param_count + ctx.signature->hasthis;
@@ -2326,6 +2379,7 @@
ctx.code = g_new0 (ILCodeDesc, ctx.header->code_size);
ctx.code_size = ctx.header->code_size;
+
memset(ctx.code, 0, sizeof (ILCodeDesc) * ctx.header->code_size);
@@ -2342,11 +2396,11 @@
}
if (ctx.signature->is_inflated)
- generic_context = mono_method_get_context (method);
-
+ ctx.generic_context = generic_context = mono_method_get_context
(method);
+
stack_init(&ctx, &ctx.eval);
-
+
/* TODO implement exception entry
for (i = 0; i < header->num_clauses; ++i) {
MonoExceptionClause *clause = &header->clauses [i];
@@ -2356,10 +2410,10 @@
code [clause->handler_offset].flags |=
IL_CODE_FLAG_SEEN;
}
}*/
-
+
while (ip < end && ctx.list == NULL) {
ctx.ip_offset = ip_offset = ip - ctx.header->code;
-
+
/*TODO id stack merge fails, we break, should't we - or only on
errors??
TODO verify need_merge
*/
@@ -2396,7 +2450,7 @@
push_arg (&ctx, *ip - CEE_LDARG_0, FALSE);
++ip;
break;
-
+
case CEE_LDARG_S:
case CEE_LDARGA_S:
push_arg (&ctx, ip [1], *ip == CEE_LDARGA_S);
@@ -2407,12 +2461,12 @@
do_binop (&ctx, *ip, add_table);
++ip;
break;
-
+
case CEE_SUB:
do_binop (&ctx, *ip, sub_table);
++ip;
break;
-
+
case CEE_MUL:
case CEE_DIV:
case CEE_REM:
@@ -2435,7 +2489,7 @@
do_binop (&ctx, *ip, shift_op_table);
++ip;
break;
-
+
case CEE_POP:
if (!check_underflow (&ctx, 1))
break;
@@ -2457,7 +2511,7 @@
push_local (&ctx, *ip - CEE_LDLOC_0, FALSE);
++ip;
break;
-
+
case CEE_STLOC_0:
case CEE_STLOC_1:
case CEE_STLOC_2:
@@ -2486,44 +2540,44 @@
case CEE_LDC_I4_6:
case CEE_LDC_I4_7:
case CEE_LDC_I4_8:
- check_overflow (&ctx);
- stack_push_val (&ctx, TYPE_I4,
&mono_defaults.int_class->byval_arg);
+ if (check_overflow (&ctx))
+ stack_push_val (&ctx, TYPE_I4,
&mono_defaults.int_class->byval_arg);
++ip;
break;
-
+
case CEE_LDC_I4_S:
- check_overflow (&ctx);
- stack_push_val (&ctx, TYPE_I4,
&mono_defaults.int_class->byval_arg);
+ if (check_overflow (&ctx))
+ stack_push_val (&ctx, TYPE_I4,
&mono_defaults.int_class->byval_arg);
ip += 2;
break;
-
+
case CEE_LDC_I4:
- check_overflow (&ctx);
- stack_push_val (&ctx,TYPE_I4,
&mono_defaults.int_class->byval_arg);
+ if (check_overflow (&ctx))
+ stack_push_val (&ctx,TYPE_I4,
&mono_defaults.int_class->byval_arg);
ip += 5;
break;
-
+
case CEE_LDC_I8:
- check_overflow (&ctx);
- stack_push_val (&ctx,TYPE_I8,
&mono_defaults.int64_class->byval_arg);
+ if (check_overflow (&ctx))
+ stack_push_val (&ctx,TYPE_I8,
&mono_defaults.int64_class->byval_arg);
ip += 9;
break;
case CEE_LDC_R4:
- check_overflow (&ctx);
- stack_push_val (&ctx, TYPE_R8,
&mono_defaults.double_class->byval_arg);
+ if (check_overflow (&ctx))
+ stack_push_val (&ctx, TYPE_R8,
&mono_defaults.double_class->byval_arg);
ip += 5;
break;
case CEE_LDC_R8:
- check_overflow (&ctx);
- stack_push_val (&ctx, TYPE_R8,
&mono_defaults.double_class->byval_arg);
+ if (check_overflow (&ctx))
+ stack_push_val (&ctx, TYPE_R8,
&mono_defaults.double_class->byval_arg);
ip += 9;
break;
case CEE_LDNULL:
- check_overflow (&ctx);
- stack_push_val (&ctx,TYPE_COMPLEX,
&mono_defaults.object_class->byval_arg);
+ if (check_overflow (&ctx))
+ stack_push_val (&ctx,TYPE_COMPLEX,
&mono_defaults.object_class->byval_arg);
++ip;
break;
@@ -2533,7 +2587,7 @@
ip += 2;
need_merge =1;
break;
-
+
case CEE_BGE_S:
case CEE_BGT_S:
case CEE_BLE_S:
@@ -2546,7 +2600,7 @@
ip += 2;
need_merge =1;
break;
-
+
case CEE_BEQ:
case CEE_BNE_UN:
do_branch_op (&ctx, (gint32)read32 (ip + 1) + 5,
cmp_br_eq_op);
@@ -2579,8 +2633,10 @@
break;
case CEE_DUP:
- check_underflow (&ctx, 1);
- check_overflow (&ctx);
+ if (!check_underflow (&ctx, 1))
+ break;
+ if (!check_overflow (&ctx))
+ break;
copy_stack_value (stack_push (&ctx), stack_get (&ctx,
1));
++ip;
break;
@@ -2598,28 +2654,10 @@
break;
case CEE_CALL:
case CEE_CALLVIRT:
- token = read32 (ip + 1);
- /*
- * FIXME: we could just load the signature ...
- */
- cmethod = mono_get_method_full (image, token, NULL,
generic_context);
- if (!cmethod)
- ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Method 0x%08x not found at 0x%04x", token, ip_offset));
- if (mono_method_signature (cmethod)) {
- csig = mono_method_signature (cmethod);
- } else {
- csig = mono_method_get_signature (cmethod,
image, token);
- }
-
- check_underflow (&ctx, csig->param_count +
csig->hasthis);
- ctx.eval.size -= csig->param_count + csig->hasthis;
- if (csig->ret->type != MONO_TYPE_VOID) {
- check_overflow (&ctx);
- type_to_eval_stack_type (csig->ret, stack_top
(&ctx), FALSE);
- ++ctx.eval.size;
- }
+ do_invoke_method (&ctx, read32 (ip + 1));
ip += 5;
break;
+
case CEE_CALLI:
token = read32 (ip + 1);
/*
@@ -2643,7 +2681,8 @@
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Branch target out of code at 0x%04x", ip_offset));
if (!in_same_block (ctx.header, ip_offset, target -
ctx.header->code))
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Branch target escapes out of exception block at 0x%04x", ip_offset));
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
if (!is_valid_bool_arg (stack_pop (&ctx)))
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Argument type %s not valid for brtrue/brfalse at 0x%04x", type_names
[stack_top (&ctx)->stype], ip_offset));
ip += 2;
@@ -2665,8 +2704,8 @@
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Branch target out of code at 0x%04x", ip_offset));
if (!in_same_block (ctx.header, ip_offset, target -
ctx.header->code))
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Branch target escapes out of exception block at 0x%04x", ip_offset));
- check_underflow (&ctx, 1);
-// --cur_stack;
+ if (!check_underflow (&ctx, 1))
+ break;
if (!is_valid_bool_arg (stack_pop (&ctx)))
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Argument type %s not valid for brtrue/brfalse at 0x%04x", type_names
[stack_top (&ctx)->stype], ip_offset));
ip += 5;
@@ -2679,8 +2718,8 @@
for (i = 0; i < n; ++i)
if (target + (gint32) read32 (ip + 5 + i *
sizeof (gint32)) >= end || target + (gint32) read32 (ip + 5 + i * sizeof
(gint32)) < ctx.header->code)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Branch target out of code at 0x%04x", ip_offset));
- check_underflow (&ctx, 1);
-// --cur_stack;
+ if (!check_underflow (&ctx, 1))
+ break;
if (stack_pop (&ctx)->stype != TYPE_I4)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Invalid argument to switch at 0x%04x", ip_offset));
ip += 5 + sizeof (guint32) * n;
@@ -2696,7 +2735,8 @@
case CEE_LDIND_R4:
case CEE_LDIND_R8:
case CEE_LDIND_REF:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
if (stack_top (&ctx)->stype != TYPE_PTR && stack_top
(&ctx)->stype != TYPE_COMPLEX)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Invalid argument to ldind at 0x%04x", ip_offset));
stack_top (&ctx)->stype = ldind_type [*ip -
CEE_LDIND_I1];
@@ -2709,7 +2749,8 @@
case CEE_STIND_I8:
case CEE_STIND_R4:
case CEE_STIND_R8:
- check_underflow (&ctx, 2);
+ if (!check_underflow (&ctx, 2))
+ break;
ctx.eval.size -= 2;
if (stack_top (&ctx)->stype != TYPE_PTR && stack_top
(&ctx)->stype != TYPE_COMPLEX)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Invalid pointer argument to stind at 0x%04x", ip_offset));
@@ -2717,7 +2758,7 @@
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Incompatible value argument to stind at 0x%04x", ip_offset));
++ip;
break;
-
+
case CEE_NEG:
case CEE_NOT:
case CEE_CONV_I1:
@@ -2728,20 +2769,23 @@
case CEE_CONV_R8:
case CEE_CONV_U4:
case CEE_CONV_U8:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
if (type_from_op (*ip, stack_top (&ctx)) == TYPE_INV)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Invalid arguments to opcode 0x%02x at 0x%04x", *ip, ip_offset));
++ip;
break;
case CEE_CPOBJ:
token = read32 (ip + 1);
- check_underflow (&ctx, 2);
+ if (!check_underflow (&ctx, 2))
+ break;
ctx.eval.size -= 2;
ip += 5;
break;
case CEE_LDOBJ:
token = read32 (ip + 1);
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
if (stack_top (&ctx)->stype != TYPE_COMPLEX)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Invalid argument to ldobj at 0x%04x", ip_offset));
klass = mono_class_get_full (image, token,
generic_context);
@@ -2756,8 +2800,8 @@
case CEE_LDSTR:
/*TODO verify if token is a valid string literal*/
token = read32 (ip + 1);
- check_overflow (&ctx);
- stack_push_val (&ctx, TYPE_COMPLEX,
&mono_defaults.string_class->byval_arg);
+ if (check_overflow (&ctx))
+ stack_push_val (&ctx, TYPE_COMPLEX,
&mono_defaults.string_class->byval_arg);
ip += 5;
break;
case CEE_NEWOBJ:
@@ -2769,24 +2813,24 @@
if (!cmethod)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Constructor 0x%08x not found at 0x%04x", token, ip_offset));
csig = mono_method_signature (cmethod);
- check_underflow (&ctx, csig->param_count);
+ if (!check_underflow (&ctx, csig->param_count))
+ break;
ctx.eval.size -= csig->param_count;
- check_overflow (&ctx);
- stack_push_val (&ctx, cmethod->klass->valuetype?
TYPE_COMPLEX: TYPE_COMPLEX, &cmethod->klass->byval_arg);
-
-// stack_top (&ctx)->type = &cmethod->klass->byval_arg;
-// stack_top (&ctx)->stype = cmethod->klass->valuetype?
TYPE_COMPLEX: TYPE_COMPLEX;
-// ++cur_stack;
+ if (check_overflow (&ctx))
+ stack_push_val (&ctx,
cmethod->klass->valuetype? TYPE_COMPLEX: TYPE_COMPLEX,
&cmethod->klass->byval_arg);
+
ip += 5;
break;
case CEE_CASTCLASS:
case CEE_ISINST:
token = read32 (ip + 1);
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
ip += 5;
break;
case CEE_CONV_R_UN:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
++ip;
break;
case CEE_UNUSED58:
@@ -2795,22 +2839,25 @@
break;
case CEE_UNBOX:
token = read32 (ip + 1);
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
if (stack_top (&ctx)->stype != TYPE_COMPLEX)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Invalid argument %s to unbox at 0x%04x", type_names [stack_top
(&ctx)->stype], ip_offset));
-
+
stack_top (&ctx)->stype = TYPE_COMPLEX;
stack_top (&ctx)->type = NULL;
ip += 5;
break;
case CEE_THROW:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
stack_pop (&ctx);
++ip;
start = 1;
break;
case CEE_LDFLD:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
if (stack_top (&ctx)->stype != TYPE_COMPLEX &&
stack_top (&ctx)->stype != TYPE_COMPLEX)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Invalid argument %s to ldfld at 0x%04x", type_names [stack_top
(&ctx)->stype], ip_offset));
token = read32 (ip + 1);
@@ -2821,7 +2868,8 @@
ip += 5;
break;
case CEE_LDFLDA:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
if (stack_top (&ctx)->stype != TYPE_COMPLEX &&
stack_top (&ctx)->stype != TYPE_COMPLEX)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Invalid argument to ldflda at 0x%04x", ip_offset));
token = read32 (ip + 1);
@@ -2832,7 +2880,8 @@
ip += 5;
break;
case CEE_STFLD:
- check_underflow (&ctx, 2);
+ if (!check_underflow (&ctx, 2))
+ break;
ctx.eval.size -= 2;
if (stack_top (&ctx)->stype != TYPE_COMPLEX &&
stack_top (&ctx)->stype != TYPE_COMPLEX)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Invalid argument to stfld at 0x%04x", ip_offset));
@@ -2844,7 +2893,8 @@
ip += 5;
break;
case CEE_LDSFLD:
- check_overflow (&ctx);
+ if (!check_overflow (&ctx))
+ break;
token = read32 (ip + 1);
field = mono_field_from_token (image, token, &klass,
generic_context);
if (!field)
@@ -2854,7 +2904,8 @@
ip += 5;
break;
case CEE_LDSFLDA:
- check_overflow (&ctx);
+ if (!check_overflow (&ctx))
+ break;
token = read32 (ip + 1);
field = mono_field_from_token (image, token, &klass,
generic_context);
if (!field)
@@ -2864,9 +2915,9 @@
ip += 5;
break;
case CEE_STSFLD:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
stack_pop (&ctx);
-// --cur_stack;
token = read32 (ip + 1);
field = mono_field_from_token (image, token, &klass,
generic_context);
if (!field)
@@ -2875,7 +2926,8 @@
ip += 5;
break;
case CEE_STOBJ:
- check_underflow (&ctx, 2);
+ if (!check_underflow (&ctx, 2))
+ break;
ctx.eval.size -= 2;
token = read32 (ip + 1);
ip += 5;
@@ -2890,13 +2942,15 @@
case CEE_CONV_OVF_U8_UN:
case CEE_CONV_OVF_I_UN:
case CEE_CONV_OVF_U_UN:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
if (type_from_op (*ip, stack_top (&ctx)) == TYPE_INV)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Invalid arguments to opcode 0x%02x at 0x%04x", *ip, ip_offset));
++ip;
break;
case CEE_BOX:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
token = read32 (ip + 1);
if ( stack_top (&ctx)->stype == TYPE_COMPLEX)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Invalid argument %s to box at 0x%04x", type_names [stack_top (&ctx)->stype],
ip_offset));
@@ -2904,13 +2958,15 @@
ip += 5;
break;
case CEE_NEWARR:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
token = read32 (ip + 1);
stack_top (&ctx)->stype = TYPE_COMPLEX;
ip += 5;
break;
case CEE_LDLEN:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
if (stack_top (&ctx)->stype != TYPE_COMPLEX)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Invalid argument to ldlen at 0x%04x", ip_offset));
stack_top (&ctx)->type =
&mono_defaults.int_class->byval_arg; /* FIXME: use a native int type */
@@ -2918,7 +2974,8 @@
++ip;
break;
case CEE_LDELEMA:
- check_underflow (&ctx, 2);
+ if (check_underflow (&ctx, 2))
+ break;
--ctx.eval.size;
if (stack_top (&ctx)->stype != TYPE_COMPLEX)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Invalid array argument to ldelema at 0x%04x", ip_offset));
@@ -2939,7 +2996,8 @@
case CEE_LDELEM_R4:
case CEE_LDELEM_R8:
case CEE_LDELEM_REF:
- check_underflow (&ctx, 2);
+ if (!check_underflow (&ctx, 2))
+ break;
--ctx.eval.size;
if (stack_top (&ctx)->stype != TYPE_COMPLEX)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Invalid array argument to ldelem at 0x%04x", ip_offset));
@@ -2956,7 +3014,8 @@
case CEE_STELEM_R4:
case CEE_STELEM_R8:
case CEE_STELEM_REF:
- check_underflow (&ctx, 3);
+ if (!check_underflow (&ctx, 3))
+ break;
ctx.eval.size -= 3;
++ip;
break;
@@ -2986,7 +3045,8 @@
case CEE_CONV_OVF_U4:
case CEE_CONV_OVF_I8:
case CEE_CONV_OVF_U8:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
if (type_from_op (*ip, stack_top (&ctx)) == TYPE_INV)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Invalid arguments to opcode 0x%02x at 0x%04x", *ip, ip_offset));
++ip;
@@ -3001,11 +3061,13 @@
++ip; /* warn, error ? */
break;
case CEE_REFANYVAL:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
++ip;
break;
case CEE_CKFINITE:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
++ip;
break;
case CEE_UNUSED24:
@@ -3013,7 +3075,8 @@
++ip; /* warn, error ? */
break;
case CEE_MKREFANY:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
token = read32 (ip + 1);
ip += 5;
break;
@@ -3029,7 +3092,8 @@
++ip; /* warn, error ? */
break;
case CEE_LDTOKEN:
- check_overflow (&ctx);
+ if (!check_overflow (&ctx))
+ break;
token = read32 (ip + 1);
++ctx.eval.size;
ip += 5;
@@ -3039,7 +3103,8 @@
case CEE_CONV_I:
case CEE_CONV_OVF_I:
case CEE_CONV_OVF_U:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
if (type_from_op (*ip, stack_top (&ctx)) == TYPE_INV)
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("Invalid arguments to opcode 0x%02x at 0x%04x", *ip, ip_offset));
++ip;
@@ -3050,7 +3115,8 @@
case CEE_MUL_OVF_UN:
case CEE_SUB_OVF:
case CEE_SUB_OVF_UN:
- check_underflow (&ctx, 2);
+ if (!check_underflow (&ctx, 2))
+ break;
stack_pop (&ctx);
++ip;
break;
@@ -3077,12 +3143,14 @@
start = 1;
break;
case CEE_STIND_I:
- check_underflow (&ctx, 2);
+ if (!check_underflow (&ctx, 2))
+ break;
ctx.eval.size -= 2;
++ip;
break;
case CEE_CONV_U:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
++ip;
break;
case CEE_UNUSED26:
@@ -3151,14 +3219,16 @@
check_overflow (&ctx);
++ip;
case CEE_LDFTN:
- check_overflow (&ctx);
+ if (!check_overflow (&ctx))
+ break;
token = read32 (ip + 1);
ip += 5;
stack_top (&ctx)->stype = TYPE_PTR;
ctx.eval.size++;
break;
case CEE_LDVIRTFTN:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
token = read32 (ip + 1);
ip += 5;
if (stack_top (&ctx)->stype != TYPE_COMPLEX)
@@ -3212,7 +3282,8 @@
ADD_VERIFY_ERROR (&ctx, g_strdup_printf
("tail prefix must be used only with call opcodes at 0x%04x", ip_offset));
break;
case CEE_INITOBJ:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
token = read32 (ip + 1);
ip += 5;
stack_pop (&ctx);
@@ -3222,11 +3293,13 @@
ip += 5;
break;
case CEE_CPBLK:
- check_underflow (&ctx, 3);
+ if (!check_underflow (&ctx, 3))
+ break;
ip++;
break;
case CEE_INITBLK:
- check_underflow (&ctx, 3);
+ if (!check_underflow (&ctx, 3))
+ break;
ip++;
break;
case CEE_NO_:
@@ -3239,7 +3312,8 @@
++ip;
break;
case CEE_SIZEOF:
- check_overflow (&ctx);
+ if (!check_overflow (&ctx))
+ break;
token = read32 (ip + 1);
ip += 5;
stack_top (&ctx)->type =
&mono_defaults.uint_class->byval_arg;
@@ -3247,7 +3321,8 @@
ctx.eval.size++;
break;
case CEE_REFANYTYPE:
- check_underflow (&ctx, 1);
+ if (!check_underflow (&ctx, 1))
+ break;
++ip;
break;
case CEE_UNUSED53:
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches