Merge pull request #495 from nicolas-raoul/fix-for-issue2907-with-no-formatting-changes
authorMiguel de Icaza <miguel@gnome.org>
Fri, 7 Dec 2012 21:57:58 +0000 (13:57 -0800)
committerMiguel de Icaza <miguel@gnome.org>
Fri, 7 Dec 2012 21:57:58 +0000 (13:57 -0800)
Fix for issue 2907: XML "choice" not correctly processed during deserialization

mcs/class/System.XML/System.Xml.Serialization/XmlSerializationReaderInterpreter.cs
mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapping.cs

index db1f19d0bf7b722231b6f33f6026e39026c5086f..3659e1d638fe3eeaf1666cc0e451d81d456295b3 100644 (file)
@@ -329,12 +329,12 @@ namespace System.Xml.Serialization
                        object[] flatLists = null;
                        object[] flatListsChoices = null;
                        Fixup fixup = null;
-                       int ind = 0;
+                       int ind = -1;
                        int maxInd;
 
                        if (readBySoapOrder) {
                                if (map.ElementMembers != null) maxInd = map.ElementMembers.Count;
-                               else maxInd = 0;
+                               else maxInd = -1;
                        }
                        else
                                maxInd = int.MaxValue;
@@ -373,14 +373,15 @@ namespace System.Xml.Serialization
                                AddFixup (fixup);
                        }
 
-                       while (Reader.NodeType != System.Xml.XmlNodeType.EndElement && (ind < maxInd)) 
+                       XmlTypeMapMember previousMember = null;
+                       while (Reader.NodeType != System.Xml.XmlNodeType.EndElement && (ind < maxInd - 1))
                        {
                                if (Reader.NodeType == System.Xml.XmlNodeType.Element) 
                                {
                                        XmlTypeMapElementInfo info;
                                        
                                        if (readBySoapOrder) {
-                                               info = map.GetElement (ind++);
+                                               info = map.GetElement (Reader.LocalName, Reader.NamespaceURI);
                                        }
                                        else if (hasAnyReturnMember) {
                                                info = (XmlTypeMapElementInfo) ((XmlTypeMapMemberElement)map.ReturnMember).ElementInfo[0];
@@ -388,9 +389,7 @@ namespace System.Xml.Serialization
                                        }
                                        else {
                                                if (map.IsOrderDependentMap) {
-                                                       while ((info = map.GetElement (ind++)) != null)
-                                                               if (info.ElementName == Reader.LocalName && info.Namespace == Reader.NamespaceURI)
-                                                                       break;
+                                                       info = map.GetElement (Reader.LocalName, Reader.NamespaceURI);
                                                }
                                                else
                                                        info = map.GetElement (Reader.LocalName, Reader.NamespaceURI, -1);
@@ -398,6 +397,16 @@ namespace System.Xml.Serialization
 
                                        if (info != null && !readFlag[info.Member.Index] )
                                        {
+                                               if (info.Member != previousMember)
+                                               {
+                                                       ind++;
+                                                       previousMember = info.Member;
+                                               }
+
+                                               if (readBySoapOrder && info.ExplicitOrder != ind)
+                                                       throw new InvalidOperationException(string.Format("Element '{0}' has wrong order in sequence (expected - {1}, actual - {2}", Reader.LocalName, info.ExplicitOrder, ind));
+
+
                                                if (info.Member.GetType() == typeof (XmlTypeMapMemberList))
                                                {
                                                        if (_format == SerializationFormat.Encoded && info.MultiReferenceType)
index 859042fd7e34d404f8bcc489a1cd91c5b3fc500a..2b0f8bd829d2768ed76993523618639fae3e1f0c 100644 (file)
@@ -405,6 +405,17 @@ namespace System.Xml.Serialization
                        if (_elements == null) return null;
                        return (XmlTypeMapElementInfo)_elements [BuildKey (name,ns, order)];
                }
+
+               public XmlTypeMapElementInfo GetElement(string name, string ns)
+               {
+                       if (_elements == null) return null;
+
+                       foreach (XmlTypeMapElementInfo info in _elements.Values)
+                               if (info.ElementName == name && info.Namespace == ns)
+                                       return info;
+
+                       return null;
+               }
                
                public XmlTypeMapElementInfo GetElement (int index)
                {