From: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 7 Feb 2022 19:41:40 +0000 (-0800) Subject: [release/6.0] [mono] Fix downcast check in Array.CopySlow (#64479) X-Git-Tag: accepted/tizen/unified/20221103.165808~196^2~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c849005de4787ad6503725e8698f3bfdc8d9aae8;p=platform%2Fupstream%2Fdotnet%2Fruntime.git [release/6.0] [mono] Fix downcast check in Array.CopySlow (#64479) * Add regression test for object[] -> Int32Enum[] array copy where each element in the source array is the appropriate type * Fix downcast check in slow array copy When we have to resort to checking element by element, compare the type of each actual element with the destination type. In particular, not the destinations underlying type when it's an enum - we don't want to allow unrelated enums using the same representation to copy over. Fixes https://github.com/dotnet/runtime/issues/64387 Co-authored-by: Aleksey Kliger --- diff --git a/src/libraries/System.Runtime/tests/System/ArrayTests.cs b/src/libraries/System.Runtime/tests/System/ArrayTests.cs index b7bdc5f..7917c4e 100644 --- a/src/libraries/System.Runtime/tests/System/ArrayTests.cs +++ b/src/libraries/System.Runtime/tests/System/ArrayTests.cs @@ -1275,6 +1275,9 @@ namespace System.Tests // Interface[] -> Class[] yield return new object[] { new NonGenericInterface1[10], 0, new NonGenericClass1[10], 0, 10, new NonGenericClass1[10] }; + + // object[] -> Int32Enum[] when values are all Int32Enum + yield return new object[] { new object[] { Int32Enum.Case3 }, 0, new Int32Enum[1], 0, 1, new Int32Enum[] { Int32Enum.Case3 } }; } public static IEnumerable Copy_Array_UnreliableConversion_CanPerform_TestData() diff --git a/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs index 94cb9eb..6a61e0e 100644 --- a/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs @@ -164,6 +164,7 @@ namespace System Type src_type = sourceArray.GetType().GetElementType()!; Type dst_type = destinationArray.GetType().GetElementType()!; + Type dst_elem_type = dst_type; bool dst_type_vt = dst_type.IsValueType && Nullable.GetUnderlyingType(dst_type) == null; bool src_is_enum = src_type.IsEnum; @@ -196,12 +197,9 @@ namespace System { object srcval = sourceArray.GetValueImpl(source_pos + i); - if (!src_type.IsValueType && dst_is_enum) + if (dst_type_vt && (srcval == null || (src_type == typeof(object) && !dst_elem_type.IsAssignableFrom (srcval.GetType())))) throw new InvalidCastException(SR.InvalidCast_DownCastArrayElement); - if (dst_type_vt && (srcval == null || (src_type == typeof(object) && srcval.GetType() != dst_type))) - throw new InvalidCastException(); - try { destinationArray.SetValueRelaxedImpl(srcval, dest_pos + i);