Don't throw NRE when custom formatter returns null
authorMarek Safar <marek.safar@gmail.com>
Thu, 9 Aug 2012 09:51:03 +0000 (10:51 +0100)
committerMarek Safar <marek.safar@gmail.com>
Thu, 9 Aug 2012 09:51:03 +0000 (10:51 +0100)
mcs/class/corlib/System/String.cs
mcs/class/corlib/Test/System/StringTest.cs

index 1ab450e1c47e01aec936ae25491384e45c2168d5..9b345f17d72ab9859b397882cb6de215e238c375 100644 (file)
@@ -1953,6 +1953,8 @@ namespace System
 
                        int ptr = 0;
                        int start = ptr;
+                       var formatter = provider != null ? provider.GetFormat (typeof (ICustomFormatter)) as ICustomFormatter : null;
+
                        while (ptr < format.length) {
                                char c = format[ptr ++];
 
@@ -1981,21 +1983,21 @@ namespace System
                                        object arg = args[n];
 
                                        string str;
-                                       ICustomFormatter formatter = null;
-                                       if (provider != null)
-                                               formatter = provider.GetFormat (typeof (ICustomFormatter))
-                                                       as ICustomFormatter;
                                        if (arg == null)
                                                str = Empty;
                                        else if (formatter != null)
                                                str = formatter.Format (arg_format, arg, provider);
-                                       else if (arg is IFormattable)
-                                               str = ((IFormattable)arg).ToString (arg_format, provider);
                                        else
-                                               str = arg.ToString ();
+                                               str = null;
 
-                                       // pad formatted string and append to result
+                                       if (str == null) {
+                                               if (arg is IFormattable)
+                                                       str = ((IFormattable)arg).ToString (arg_format, provider);
+                                               else
+                                                       str = arg.ToString ();
+                                       }
 
+                                       // pad formatted string and append to result
                                        if (width > str.length) {
                                                const char padchar = ' ';
                                                int padlen = width - str.length;
@@ -2008,9 +2010,9 @@ namespace System
                                                        result.Append (padchar, padlen);
                                                        result.Append (str);
                                                }
-                                       }
-                                       else
+                                       } else {
                                                result.Append (str);
+                                       }
 
                                        start = ptr;
                                }
index 429ff654f0ae92c055a4fc106c4bbc936e5a6019..ef92166c2815ce63f4fe6609b7ba7375724c2153 100644 (file)
@@ -24,6 +24,20 @@ namespace MonoTests.System
 [TestFixture]
 public class StringTest
 {
+       class NullFormatter : IFormatProvider, ICustomFormatter
+       {
+               public string Format (string format, object arg, IFormatProvider provider)
+               {
+                       return null;
+               }
+
+               public object GetFormat (Type formatType)
+               {
+                       return this;
+               }
+       }
+
+
        private CultureInfo orgCulture;
 
        [SetUp]
@@ -1161,6 +1175,13 @@ public class StringTest
                }
        }
 
+       [Test]
+       public void Format ()
+       {
+               var s = String.Format (new NullFormatter (), "{0:}", "test");
+               Assert.AreEqual ("test", s);
+       }
+
        [Test]
        public void TestGetEnumerator ()
        {