From bdee9a3f37887780606050265027eff687c0bb73 Mon Sep 17 00:00:00 2001 From: Alexey Zakharov Date: Thu, 24 Oct 2024 14:58:20 +0200 Subject: [PATCH 1/2] Fixed initialization of a class which has last fields in a table with 65535 field entries and the next class having no fields (cherry picked from commit 0888d04ed65b2ac9072175a518be89308bd89ebb) --- mono/metadata/class-init.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mono/metadata/class-init.c b/mono/metadata/class-init.c index e0e6287373a8..61ab176f2e61 100644 --- a/mono/metadata/class-init.c +++ b/mono/metadata/class-init.c @@ -634,8 +634,9 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError if (tt->rows > tidx){ mono_metadata_decode_row (tt, tidx, cols_next, MONO_TYPEDEF_SIZE); - field_last = cols_next [MONO_TYPEDEF_FIELD_LIST] - 1; - method_last = cols_next [MONO_TYPEDEF_METHOD_LIST] - 1; + // check if the next row has fields at all, if not, then continue run till the end of the table + field_last = cols_next [MONO_TYPEDEF_FIELD_LIST] ? cols_next [MONO_TYPEDEF_FIELD_LIST] - 1 : image->tables [MONO_TABLE_FIELD].rows; + method_last = cols_next [MONO_TYPEDEF_METHOD_LIST] ? cols_next [MONO_TYPEDEF_METHOD_LIST] - 1 : image->tables [MONO_TABLE_METHOD].rows; } else { field_last = image->tables [MONO_TABLE_FIELD].rows; method_last = image->tables [MONO_TABLE_METHOD].rows; From 6e377658c4bdca40068f745db50c4827959925a8 Mon Sep 17 00:00:00 2001 From: Alexey Zakharov Date: Wed, 6 Nov 2024 09:36:47 +0100 Subject: [PATCH 2/2] Add non-null entry check for the MethodList too, so that last entry of the table with 65635 methods and 0 in MethodList index in the last type doesnt crash --- mono/metadata/class-init.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mono/metadata/class-init.c b/mono/metadata/class-init.c index 61ab176f2e61..4666924367c9 100644 --- a/mono/metadata/class-init.c +++ b/mono/metadata/class-init.c @@ -634,7 +634,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError if (tt->rows > tidx){ mono_metadata_decode_row (tt, tidx, cols_next, MONO_TYPEDEF_SIZE); - // check if the next row has fields at all, if not, then continue run till the end of the table + /* check if the next row has fields at all, if not, then continue run till the end of the table */ field_last = cols_next [MONO_TYPEDEF_FIELD_LIST] ? cols_next [MONO_TYPEDEF_FIELD_LIST] - 1 : image->tables [MONO_TABLE_FIELD].rows; method_last = cols_next [MONO_TYPEDEF_METHOD_LIST] ? cols_next [MONO_TYPEDEF_METHOD_LIST] - 1 : image->tables [MONO_TABLE_METHOD].rows; } else { @@ -642,10 +642,12 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError method_last = image->tables [MONO_TABLE_METHOD].rows; } + /* validate for both fields and methods that class has non-null list entries */ if (cols [MONO_TYPEDEF_FIELD_LIST] && cols [MONO_TYPEDEF_FIELD_LIST] <= image->tables [MONO_TABLE_FIELD].rows) mono_class_set_field_count (klass, field_last - first_field_idx); - if (cols [MONO_TYPEDEF_METHOD_LIST] <= image->tables [MONO_TABLE_METHOD].rows) + if (cols [MONO_TYPEDEF_METHOD_LIST] && + cols [MONO_TYPEDEF_METHOD_LIST] <= image->tables [MONO_TABLE_METHOD].rows) mono_class_set_method_count (klass, method_last - first_method_idx); /* reserve space to store vector pointer in arrays */