Skip to content

Commit

Permalink
Fix downcast check in slow array copy
Browse files Browse the repository at this point in the history
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 #64387
  • Loading branch information
lambdageek authored and github-actions committed Jan 28, 2022
1 parent 64dfb25 commit 5ff36f3
Showing 1 changed file with 2 additions and 4 deletions.
6 changes: 2 additions & 4 deletions src/mono/System.Private.CoreLib/src/System/Array.Mono.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ private static void Copy(Array sourceArray, int sourceIndex, Array destinationAr

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;
Expand Down Expand Up @@ -196,12 +197,9 @@ private static void Copy(Array sourceArray, int sourceIndex, Array destinationAr
{
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);
Expand Down

0 comments on commit 5ff36f3

Please sign in to comment.