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.