[runtime] Mark array types with more than 32 dimensions as invalid. Move the check...
authorZoltan Varga <vargaz@gmail.com>
Mon, 13 Mar 2017 20:02:25 +0000 (16:02 -0400)
committerGitHub <noreply@github.com>
Mon, 13 Mar 2017 20:02:25 +0000 (16:02 -0400)
mcs/class/corlib/Test/System/ArrayTest.cs
mcs/class/corlib/Test/System/TypeTest.cs
mono/metadata/class.c
mono/metadata/icall.c

index 351d312c92d63c5d217d3f9df04524402671680b..f8d33b932faaff3ce22b010e82b0a73673e2de14 100644 (file)
@@ -779,6 +779,14 @@ public class ArrayTest
                Array.CreateInstance (typeof (Int32), (long[])null);
        }
 
+       [Test]
+       public void CreateInstanceVoid ()
+       {
+               Assert.Throws<NotSupportedException> (delegate () {
+                               Array.CreateInstance (typeof (void), 1);
+                       });
+       }
+
        [Test]
        public void TestGetEnumerator() {
                String[] s1 = {"this", "is", "a", "test"};
index 100f1c362742134360fd3562f632b1192f0d50c3..72300155135e4f7b93d04f914b52d093a997ac10 100644 (file)
@@ -3068,6 +3068,14 @@ namespace MonoTests.System
                        object o = Array.CreateInstance (typeof (global::System.TypedReference), 1);
                }
 
+               [Test]
+               public void MakeArrayTypeLargeRank ()
+               {
+                       Assert.Throws<TypeLoadException> (delegate () {
+                                       typeof (int).MakeArrayType (33);
+                               });
+               }
+
                [ComVisible (true)]
                public class ComFoo<T> {
                }
index 0d0952b0c9ff467bb054e8eec296a6571915db12..24e9afa16d5c400765431100fafa54a57056930e 100644 (file)
@@ -6520,11 +6520,11 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded)
        klass->parent = parent;
        klass->instance_size = mono_class_instance_size (klass->parent);
 
-       if (eclass->byval_arg.type == MONO_TYPE_TYPEDBYREF || eclass->byval_arg.type == MONO_TYPE_VOID) {
+       if (eclass->byval_arg.type == MONO_TYPE_TYPEDBYREF) {
                /*Arrays of those two types are invalid.*/
                MonoError prepared_error;
                error_init (&prepared_error);
-               mono_error_set_invalid_program (&prepared_error, "Arrays of void or System.TypedReference types are invalid.");
+               mono_error_set_invalid_program (&prepared_error, "Arrays of System.TypedReference types are invalid.");
                mono_class_set_failure (klass, mono_error_box (&prepared_error, klass->image));
                mono_error_cleanup (&prepared_error);
        } else if (eclass->enumtype && !mono_class_enum_basetype (eclass)) {
@@ -6597,6 +6597,16 @@ mono_bounded_array_class_get (MonoClass *eclass, guint32 rank, gboolean bounded)
        klass->this_arg = klass->byval_arg;
        klass->this_arg.byref = 1;
 
+       if (rank > 32) {
+               MonoError prepared_error;
+               error_init (&prepared_error);
+               name = mono_type_get_full_name (klass);
+               mono_error_set_type_load_class (&prepared_error, klass, "%s has too many dimensions.", name);
+               mono_class_set_failure (klass, mono_error_box (&prepared_error, klass->image));
+               mono_error_cleanup (&prepared_error);
+               g_free (name);
+       }
+
        mono_loader_lock ();
 
        /* Check cache again */
index 181273de534a87a0075d9b5e28e59db1295fe0db..2f3b7f7f27fc1a5dec9a8c1d2adb5193ed908486 100644 (file)
@@ -582,6 +582,11 @@ ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *
        if (mono_error_set_pending_exception (&error))
                return NULL;
 
+       if (klass->element_class->byval_arg.type == MONO_TYPE_VOID) {
+               mono_set_pending_exception (mono_get_exception_not_supported ("Arrays of System.Void are not supported."));
+               return NULL;
+       }
+
        if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
                /* vectors are not the same as one dimensional arrays with no-zero bounds */
                bounded = TRUE;
@@ -6097,6 +6102,7 @@ check_for_invalid_type (MonoClass *klass, MonoError *error)
        name = mono_type_get_full_name (klass);
        mono_error_set_type_load_name (error, name, g_strdup (""), "");
 }
+
 ICALL_EXPORT MonoReflectionTypeHandle
 ves_icall_RuntimeType_make_array_type (MonoReflectionTypeHandle ref_type, int rank, MonoError *error)
 {
@@ -6114,6 +6120,11 @@ ves_icall_RuntimeType_make_array_type (MonoReflectionTypeHandle ref_type, int ra
        else
                aklass = mono_bounded_array_class_get (klass, rank, TRUE);
 
+       if (mono_class_has_failure (aklass)) {
+               mono_error_set_for_class_failure (error, aklass);
+               return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
+       }
+
        MonoDomain *domain = MONO_HANDLE_DOMAIN (ref_type);
        return mono_type_get_object_handle (domain, &aklass->byval_arg, error);
 }