[mono/mono] [3 commits] 4a656ad2: [runtime]When setting a loader error, clear the previous one to avoid the leak.

"Rodrigo Kumpera ([email protected])" <[email protected]> Thu, 14 Nov 2013 17:32:01 +0000
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <0000014257ab6cbc-0dde6c86-b35e-4be1-b2c5-522e10e0946d-000000@email.amazonses.com>
   Branch: refs/heads/master
     Home: https://github.com/mono/mono
  Compare: https://github.com/mono/mono/compare/a7348279926d...18aa5e3bf059

   Commit: 4a656ad29e3f8134b1441f5abe2d4ef50a01e5d5
   Author: Rodrigo Kumpera <[email protected]> (kumpera)
     Date: 2013-11-14 17:28:52 GMT
      URL: https://github.com/mono/mono/commit/4a656ad29e3f8134b1441f5abe2d4ef50a01e5d5

[runtime]When setting a loader error, clear the previous one to avoid the leak.

Changed paths:
  M mono/metadata/loader.c

Modified: mono/metadata/loader.c
===================================================================
@@ -129,6 +129,7 @@
 static void
 set_loader_error (MonoLoaderError *error)
 {
+	mono_loader_clear_error ();
 	mono_native_tls_set_value (loader_error_thread_id, error);
 }
 

   Commit: bd741f0aacfd7ce246aec35e19e1ffac462bb1dd
   Author: Rodrigo Kumpera <[email protected]> (kumpera)
     Date: 2013-11-14 17:28:52 GMT
      URL: https://github.com/mono/mono/commit/bd741f0aacfd7ce246aec35e19e1ffac462bb1dd

[runtime]Type parsing of generics should not rely on the presence of a backtick. Fixes #15124.

We previously depended on the presence of a backtick in a generic type name to try to
parse a generics argument list. This is not what the spec says and F# breaks this expectation.

The right way to handle this is to probe for array syntax.

Changed paths:
  M mono/metadata/reflection.c

Modified: mono/metadata/reflection.c
===================================================================
@@ -7228,9 +7228,9 @@ struct StreamDesc {
 _mono_reflection_parse_type (char *name, char **endptr, gboolean is_recursed,
 			     MonoTypeNameParse *info)
 {
-	char *start, *p, *w, *temp, *last_point, *startn;
+	char *start, *p, *w, *last_point, *startn;
 	int in_modifiers = 0;
-	int isbyref = 0, rank, arity = 0, i;
+	int isbyref = 0, rank = 0;
 
 	start = p = w = name;
 
@@ -7277,14 +7277,6 @@ struct StreamDesc {
 		case ']':
 			in_modifiers = 1;
 			break;
-		case '`':
-			++p;
-			i = strtol (p, &temp, 10);
-			arity += i;
-			if (p == temp)
-				return 0;
-			p = temp-1;
-			break;
 		default:
 			break;
 		}
@@ -7318,10 +7310,32 @@ struct StreamDesc {
 			*p++ = 0;
 			break;
 		case '[':
-			if (arity != 0) {
-				*p++ = 0;
+			//Decide if it's an array of a generic argument list
+			*p++ = 0;
+
+			if (!*p) //XXX test
+				return 0;
+			if (*p  == ',' || *p == '*' || *p == ']') { //array
+				rank = 1;
+				while (*p) {
+					if (*p == ']')
+						break;
+					if (*p == ',')
+						rank++;
+					else if (*p == '*') /* '*' means unknown lower bound */
+						info->modifiers = g_list_append (info->modifiers, GUINT_TO_POINTER (-2));
+					else
+						return 0;
+					++p;
+				}
+				if (*p++ != ']')
+					return 0;
+				info->modifiers = g_list_append (info->modifiers, GUINT_TO_POINTER (rank));
+			} else {
+				if (rank) /* generic args after array spec*/ //XXX test
+					return 0;
 				info->type_arguments = g_ptr_array_new ();
-				for (i = 0; i < arity; i++) {
+				while (*p) {
 					MonoTypeNameParse *subinfo = g_new0 (MonoTypeNameParse, 1);
 					gboolean fqname = FALSE;
 
@@ -7364,36 +7378,15 @@ struct StreamDesc {
 					} else if (fqname && (*p == ']')) {
 						*p++ = 0;
 					}
-
-					if (i + 1 < arity) {
-						if (*p != ',')
-							return 0;
-					} else {
-						if (*p != ']')
-							return 0;
+					if (*p == ']') {
+						*p++ = 0;
+						break;
+					} else if (!*p) {
+						return 0;
 					}
 					*p++ = 0;
 				}
-
-				arity = 0;
-				break;
 			}
-			rank = 1;
-			*p++ = 0;
-			while (*p) {
-				if (*p == ']')
-					break;
-				if (*p == ',')
-					rank++;
-				else if (*p == '*') /* '*' means unknown lower bound */
-					info->modifiers = g_list_append (info->modifiers, GUINT_TO_POINTER (-2));
-				else
-					return 0;
-				++p;
-			}
-			if (*p++ != ']')
-				return 0;
-			info->modifiers = g_list_append (info->modifiers, GUINT_TO_POINTER (rank));
 			break;
 		case ']':
 			if (is_recursed)

   Commit: 18aa5e3bf059ad124b88f07a6f6790a39d53e3e5
   Author: Rodrigo Kumpera <[email protected]> (kumpera)
     Date: 2013-11-14 17:28:53 GMT
      URL: https://github.com/mono/mono/commit/18aa5e3bf059ad124b88f07a6f6790a39d53e3e5

Add some tests for #15124.

Changed paths:
  M mcs/class/corlib/Test/System/TypeTest.cs

Modified: mcs/class/corlib/Test/System/TypeTest.cs
===================================================================
@@ -4024,6 +4024,25 @@ public void GetTypeWithDelegatesAndUserTypes ()
 		}
 #endif
 
+		[Test]
+		public void GetTypeParseGenericCorrectly () { //Bug #15124
+			Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1"), typeof (Foo<>), "#1");
+			Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[System.Int32]"), typeof (Foo<int>), "#2");
+			Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[[System.Int32]]"), typeof (Foo<int>), "#3");
+			Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[System.Int32][]"), typeof (Foo<int>[]), "#4");
+			Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[][System.Int32]"), null, "#5");
+			Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[System.Int32][,]"), typeof (Foo<int>[,]), "#6");
+			Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[]"), typeof (Foo<>).MakeArrayType(), "#7");
+			Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[,]"), typeof (Foo<>).MakeArrayType (2), "#8");
+			Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[][]"), typeof (Foo<>).MakeArrayType ().MakeArrayType (), "#9");
+			Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1["), null, "#10");
+			Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[["), null, "#11");
+			Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[[]"), null, "#12");
+			Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[,"), null, "#13");
+			Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[*"), null, "#14");
+			Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[System.Int32"), null, "#15");
+		}
+
 		public abstract class Stream : IDisposable
 		{
 			public void Dispose ()


_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches