From: Robert Jordan Date: Sun, 24 Jan 2010 01:04:18 +0000 (-0000) Subject: In System.Collections.Generic: X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=c42abafd5bbed80b819904e95ae6b5af58e0be88;p=mono.git In System.Collections.Generic: 2010-01-24 Robert Jordan * Dictionary.cs: Fix deserialization compatibility with MS.NET. Fixes bug #474009. In Test/System.Collections.Generic: 2010-01-24 Robert Jordan * DictionaryTest.cs: Add test case for bug #474009. svn path=/trunk/mcs/; revision=150089 --- diff --git a/mcs/class/corlib/System.Collections.Generic/ChangeLog b/mcs/class/corlib/System.Collections.Generic/ChangeLog index 6bce4cfb66d..2ff36e7a854 100644 --- a/mcs/class/corlib/System.Collections.Generic/ChangeLog +++ b/mcs/class/corlib/System.Collections.Generic/ChangeLog @@ -1,3 +1,8 @@ +2010-01-24 Robert Jordan + + * Dictionary.cs: Fix deserialization compatibility with MS.NET. + Fixes bug #474009. + 2010-01-20 Miguel de Icaza * Dictionary.cs: Always create the keys, fixes compatibility diff --git a/mcs/class/corlib/System.Collections.Generic/Dictionary.cs b/mcs/class/corlib/System.Collections.Generic/Dictionary.cs index 91d3cc312bc..65d88dbde37 100644 --- a/mcs/class/corlib/System.Collections.Generic/Dictionary.cs +++ b/mcs/class/corlib/System.Collections.Generic/Dictionary.cs @@ -501,8 +501,11 @@ namespace System.Collections.Generic { info.AddValue ("Version", generation); info.AddValue ("Comparer", hcp); - KeyValuePair [] data = null; - data = new KeyValuePair [count]; + // MS.NET expects either *no* KeyValuePairs field (when count = 0) + // or a non-null KeyValuePairs field. We don't omit the field to + // remain compatible with older monos, but we also doesn't serialize + // it as null to make MS.NET happy. + KeyValuePair [] data = new KeyValuePair [count]; if (count > 0) CopyTo (data, 0); info.AddValue ("HashSize", table.Length); @@ -514,14 +517,34 @@ namespace System.Collections.Generic { if (serialization_info == null) return; - generation = serialization_info.GetInt32 ("Version"); - hcp = (IEqualityComparer) serialization_info.GetValue ("Comparer", typeof (IEqualityComparer)); + int hashSize = 0; + KeyValuePair [] data = null; + + // We must use the enumerator because MS.NET doesn't + // serialize "KeyValuePairs" for count = 0. + SerializationInfoEnumerator e = serialization_info.GetEnumerator (); + while (e.MoveNext ()) { + switch (e.Name) { + case "Version": + generation = (int) e.Value; + break; + + case "Comparer": + hcp = (IEqualityComparer) e.Value; + break; - int hashSize = serialization_info.GetInt32 ("HashSize"); - KeyValuePair [] data = - (KeyValuePair []) - serialization_info.GetValue ("KeyValuePairs", typeof (KeyValuePair [])); + case "HashSize": + hashSize = (int) e.Value; + break; + + case "KeyValuePairs": + data = (KeyValuePair []) e.Value; + break; + } + } + if (hcp == null) + hcp = EqualityComparer.Default; if (hashSize < INITIAL_SIZE) hashSize = INITIAL_SIZE; InitArrays (hashSize); diff --git a/mcs/class/corlib/Test/System.Collections.Generic/ChangeLog b/mcs/class/corlib/Test/System.Collections.Generic/ChangeLog index 70172f0ce04..be9b884695b 100644 --- a/mcs/class/corlib/Test/System.Collections.Generic/ChangeLog +++ b/mcs/class/corlib/Test/System.Collections.Generic/ChangeLog @@ -1,3 +1,7 @@ +2010-01-24 Robert Jordan + + * DictionaryTest.cs: Add test case for bug #474009. + 2009-09-22 Raja R Harinath * DictionaryTest.cs (ICollectionCopyTo): Test various odd diff --git a/mcs/class/corlib/Test/System.Collections.Generic/DictionaryTest.cs b/mcs/class/corlib/Test/System.Collections.Generic/DictionaryTest.cs index 0afa477bfc4..b429c6437ef 100644 --- a/mcs/class/corlib/Test/System.Collections.Generic/DictionaryTest.cs +++ b/mcs/class/corlib/Test/System.Collections.Generic/DictionaryTest.cs @@ -1166,6 +1166,70 @@ namespace MonoTests.System.Collections.Generic { ICollection c = d.Values; c.CopyTo (new MyClass [1], 0); } + + [Test] // bug 474009 + public void DeserializeEmptyDictionary () + { + // contains a Dictionary with Count = 0 + // serialized with MS.NET 3.5 + string data = +@"AAEAAAD/////AQAAAAAAAAAEAQAAAOEBU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuRGljdGlv +bmFyeWAyW1tTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJl +PW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldLFtTeXN0ZW0uSW50MzIs +IG1zY29ybGliLCBWZXJzaW9uPTIuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9r +ZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAwAAAAdWZXJzaW9uCENvbXBhcmVyCEhhc2hTaXplAAMACJIB +U3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuR2VuZXJpY0VxdWFsaXR5Q29tcGFyZXJgMVtbU3lz +dGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249Mi4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQ +dWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0IAAAAAAkCAAAAAAAAAAQCAAAAkgFTeXN0 +ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5HZW5lcmljRXF1YWxpdHlDb21wYXJlcmAxW1tTeXN0ZW0u +U3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1Ymxp +Y0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQAAAAAL"; + + var stream = new MemoryStream (Convert.FromBase64String (data)); + var fmt = new BinaryFormatter (); + var dict = (Dictionary ) fmt.Deserialize (stream); + Assert.AreEqual (0, dict.Count); + } + + [Test] + public void DeserializeNonEmptyDictionary () + { + // contains a Dictionary with Count = 2 + // and dict [i.ToString()] == i for each i. + // serialized with MS.NET 3.5 + string data = +@"AAEAAAD/////AQAAAAAAAAAEAQAAAOEBU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuRGljdGlv +bmFyeWAyW1tTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJl +PW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldLFtTeXN0ZW0uSW50MzIs +IG1zY29ybGliLCBWZXJzaW9uPTIuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9r +ZW49Yjc3YTVjNTYxOTM0ZTA4OV1dBAAAAAdWZXJzaW9uCENvbXBhcmVyCEhhc2hTaXplDUtleVZh +bHVlUGFpcnMAAwADCJIBU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuR2VuZXJpY0VxdWFsaXR5 +Q29tcGFyZXJgMVtbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249Mi4wLjAuMCwgQ3Vs +dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0I5QFTeXN0ZW0u +Q29sbGVjdGlvbnMuR2VuZXJpYy5LZXlWYWx1ZVBhaXJgMltbU3lzdGVtLlN0cmluZywgbXNjb3Js +aWIsIFZlcnNpb249Mi4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdh +NWM1NjE5MzRlMDg5XSxbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj0yLjAuMC4wLCBD +dWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXVtdAgAAAAkC +AAAAAwAAAAkDAAAABAIAAACSAVN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkdlbmVyaWNFcXVh +bGl0eUNvbXBhcmVyYDFbW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTIuMC4wLjAs +IEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAAAAAAcD +AAAAAAEAAAACAAAAA+MBU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuS2V5VmFsdWVQYWlyYDJb +W1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTIuMC4wLjAsIEN1bHR1cmU9bmV1dHJh +bCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV0sW1N5c3RlbS5JbnQzMiwgbXNjb3Js +aWIsIFZlcnNpb249Mi4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdh +NWM1NjE5MzRlMDg5XV0E/P///+MBU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuS2V5VmFsdWVQ +YWlyYDJbW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTIuMC4wLjAsIEN1bHR1cmU9 +bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV0sW1N5c3RlbS5JbnQzMiwg +bXNjb3JsaWIsIFZlcnNpb249Mi4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tl +bj1iNzdhNWM1NjE5MzRlMDg5XV0CAAAAA2tleQV2YWx1ZQEACAYFAAAAATAAAAAAAfr////8//// +BgcAAAABMQEAAAAL"; + var stream = new MemoryStream (Convert.FromBase64String (data)); + var fmt = new BinaryFormatter (); + var dict = (Dictionary ) fmt.Deserialize (stream); + Assert.AreEqual (2, dict.Count); + for (int i = 0; i < dict.Count; i++) + Assert.AreEqual (i, dict[i.ToString ()]); + } } }