From 7c0ecc4bbea7aeadc0f99da3288da79e76326dda Mon Sep 17 00:00:00 2001 From: vsadov <8218165+VSadov@users.noreply.github.com> Date: Wed, 9 Aug 2023 11:04:36 -0700 Subject: [PATCH] Disallow readonly instance fields in InlineArray --- src/coreclr/dlls/mscorrc/mscorrc.rc | 1 + src/coreclr/dlls/mscorrc/resource.h | 1 + .../src/Internal/Runtime/TypeLoaderExceptionHelper.cs | 2 ++ .../tools/Common/TypeSystem/Common/ExceptionStringID.cs | 1 + .../TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs | 9 +++++++++ .../Common/TypeSystem/Common/Properties/Resources.resx | 5 ++++- src/coreclr/vm/methodtablebuilder.cpp | 6 ++++++ .../System.Private.CoreLib/src/Resources/Strings.resx | 3 +++ 8 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/coreclr/dlls/mscorrc/mscorrc.rc b/src/coreclr/dlls/mscorrc/mscorrc.rc index 8c3c50d4f522a7..132b2a99bb7f91 100644 --- a/src/coreclr/dlls/mscorrc/mscorrc.rc +++ b/src/coreclr/dlls/mscorrc/mscorrc.rc @@ -312,6 +312,7 @@ BEGIN IDS_CLASSLOAD_INLINE_ARRAY_FIELD_COUNT "InlineArrayAttribute requires that the target type has a single instance field. Type: '%1'. Assembly: '%2'." IDS_CLASSLOAD_INLINE_ARRAY_LENGTH "InlineArrayAttribute requires that the length argument is greater than 0. Type: '%1'. Assembly: '%2'." IDS_CLASSLOAD_INLINE_ARRAY_EXPLICIT "InlineArrayAttribute cannot be applied to a type with explicit layout. Type: '%1'. Assembly: '%2'." + IDS_CLASSLOAD_INLINE_ARRAY_READONLY "InlineArrayAttribute cannot be applied to a type with readonly instance fields. Type: '%1'. Assembly: '%2'." IDS_INVALID_RECURSIVE_GENERIC_FIELD_LOAD "Could not load type '%1' from assembly '%2' because of an invalid self-referential generic field." diff --git a/src/coreclr/dlls/mscorrc/resource.h b/src/coreclr/dlls/mscorrc/resource.h index 878fd3c509da64..ee0bca77a4499d 100644 --- a/src/coreclr/dlls/mscorrc/resource.h +++ b/src/coreclr/dlls/mscorrc/resource.h @@ -172,6 +172,7 @@ #define IDS_CLASSLOAD_INLINE_ARRAY_FIELD_COUNT 0x17ac #define IDS_CLASSLOAD_INLINE_ARRAY_LENGTH 0x17ad #define IDS_CLASSLOAD_INLINE_ARRAY_EXPLICIT 0x17ae +#define IDS_CLASSLOAD_INLINE_ARRAY_READONLY 0x17af #define IDS_DEBUG_USERBREAKPOINT 0x17b6 diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/TypeLoaderExceptionHelper.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/TypeLoaderExceptionHelper.cs index 70d17bb96989d7..d31c106e24fc29 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/TypeLoaderExceptionHelper.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/TypeLoaderExceptionHelper.cs @@ -88,6 +88,8 @@ private static string GetFormatString(ExceptionStringID id) return SR.ClassLoad_RankTooLarge; case ExceptionStringID.ClassLoadInlineArrayFieldCount: return SR.ClassLoad_InlineArrayFieldCount; + case ExceptionStringID.ClassLoadInlineArrayReadOnly: + return SR.ClassLoad_InlineArrayReadOnly; case ExceptionStringID.ClassLoadInlineArrayLength: return SR.ClassLoad_InlineArrayLength; case ExceptionStringID.ClassLoadInlineArrayExplicit: diff --git a/src/coreclr/tools/Common/TypeSystem/Common/ExceptionStringID.cs b/src/coreclr/tools/Common/TypeSystem/Common/ExceptionStringID.cs index dd53c1b47aaaf8..0b430d38d97a18 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/ExceptionStringID.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/ExceptionStringID.cs @@ -19,6 +19,7 @@ public enum ExceptionStringID ClassLoadInlineArrayFieldCount, ClassLoadInlineArrayLength, ClassLoadInlineArrayExplicit, + ClassLoadInlineArrayReadOnly, // MissingMethodException MissingMethod, diff --git a/src/coreclr/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs b/src/coreclr/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs index d56bfa19bbf210..7cf61f6efe255d 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/MetadataFieldLayoutAlgorithm.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Linq; using Debug = System.Diagnostics.Debug; namespace Internal.TypeSystem @@ -493,6 +494,14 @@ private static void AdjustForInlineArray( ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadInlineArrayFieldCount, type); } + foreach (var field in type.GetFields()) + { + if (field.IsInitOnly && !field.IsStatic) + { + ThrowHelper.ThrowTypeLoadException(ExceptionStringID.ClassLoadInlineArrayReadOnly, type); + } + } + if (!instanceByteSizeAndAlignment.Size.IsIndeterminate) { long size = instanceByteSizeAndAlignment.Size.AsInt; diff --git a/src/coreclr/tools/Common/TypeSystem/Common/Properties/Resources.resx b/src/coreclr/tools/Common/TypeSystem/Common/Properties/Resources.resx index 319bb25ffd7f00..81f2ea4d4590d6 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/Properties/Resources.resx +++ b/src/coreclr/tools/Common/TypeSystem/Common/Properties/Resources.resx @@ -138,6 +138,9 @@ InlineArrayAttribute cannot be applied to a type with explicit layout. Type: '{0}'. Assembly: '{1}'.' + + InlineArrayAttribute cannot be applied to a type with readonly instance fields. Type: '{0}'. Assembly: '{1}'. + Array of type '{0}' from assembly '{1}' cannot be created because base value type is too large @@ -195,4 +198,4 @@ Ambiguity in binding of UnsafeAccessorAttribute. - + \ No newline at end of file diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index 47024106985eee..b0e76558e6f64e 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -1724,6 +1724,12 @@ MethodTableBuilder::BuildMethodTableThrowing( BuildMethodTableThrowException(IDS_CLASSLOAD_INLINE_ARRAY_FIELD_COUNT); } + DWORD dwFieldAttrs = bmtMetaData->pFieldAttrs[0]; + if (IsFdInitOnly(dwFieldAttrs)) + { + BuildMethodTableThrowException(IDS_CLASSLOAD_INLINE_ARRAY_READONLY); + } + if (cbVal >= (sizeof(INT32) + 2)) { INT32 repeat = GET_UNALIGNED_VAL32((byte*)pVal + 2); diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx index bd016b716a1617..06cd095e8fa3f1 100644 --- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx @@ -4130,6 +4130,9 @@ InlineArrayAttribute cannot be applied to a type with explicit layout. Type: '{0}'. Assembly: '{1}'. + + InlineArrayAttribute cannot be applied to a type with readonly instance fields. Type: '{0}'. Assembly: '{1}'. + Could not load type '{0}' from assembly '{1}' because generic types cannot have explicit layout.