diff options
author | monojenkins <jo.shields+jenkins@xamarin.com> | 2022-02-02 14:57:21 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-02 14:57:21 +0300 |
commit | e3c2771b7004661afb04d568b6e8ae1d2f397a3c (patch) | |
tree | 590dcc91b765dbd9c89493a01ae07fb839349912 | |
parent | 62c38ed74cc91c826a720d01f955a2db7b06fb6c (diff) |
Avoid an assert in ves_icall_RuntimeFieldInfo_SetValueInternal (#21410)
When the field is byref but the value being passes in is not, throw an
ArgumentException. Without this change the call to
mono_object_handle_pin_unbox will assert and kill the process.
This can occur when de-serializing an object and the field types have
changed.
Co-authored-by: bholmes <bholmes@users.noreply.github.com>
-rw-r--r-- | mono/metadata/icall.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index 08304a3c90d..6b73270845d 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -2167,8 +2167,16 @@ ves_icall_RuntimeFieldInfo_SetValueInternal (MonoReflectionFieldHandle field, Mo case MONO_TYPE_VALUETYPE: case MONO_TYPE_PTR: isref = FALSE; - if (!MONO_HANDLE_IS_NULL (value)) - v = (char*)mono_object_handle_pin_unbox (value, &value_gchandle); + if (!MONO_HANDLE_IS_NULL (value)) { + if (m_class_is_valuetype (mono_handle_class (value))) + v = (char*)mono_object_handle_pin_unbox (value, &value_gchandle); + else { + char* n = g_strdup_printf ("Object of type '%s' cannot be converted to type '%s'.", m_class_get_name (mono_handle_class (value)), m_class_get_name (mono_class_from_mono_type_internal (type))); + mono_error_set_argument (error, cf->name, n); + g_free (n); + return; + } + } break; case MONO_TYPE_STRING: case MONO_TYPE_OBJECT: |