aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorOren Hurvitz2015-07-05 16:05:01 +0300
committerOren Hurvitz2015-08-11 07:35:37 +0100
commit4ad1468165b80f67439399e36688d36944996312 (patch)
tree541cfb87ecae92a3bff53aaa8875b06d83878a35 /OpenSim
parentFixed mistakes in string format specifiers (e.g., "{0)" instead of {0}") (diff)
downloadopensim-SC_OLD-4ad1468165b80f67439399e36688d36944996312.zip
opensim-SC_OLD-4ad1468165b80f67439399e36688d36944996312.tar.gz
opensim-SC_OLD-4ad1468165b80f67439399e36688d36944996312.tar.bz2
opensim-SC_OLD-4ad1468165b80f67439399e36688d36944996312.tar.xz
Better handling of invalid XML: a) prevent infinite loop on EOF; b) better logging
If the XML was truncated for some reason then ExecuteReadProcessors() would get into an infinite loop, using high CPU. Now it detects EOF (and several other error cases) and aborts. The rest of the changes just improve logging of XML in case of errors, so that we can see what the bad XML is.
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs40
-rw-r--r--OpenSim/Framework/Util.cs10
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs19
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs109
5 files changed, 115 insertions, 69 deletions
diff --git a/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs b/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs
index 1254086..55640ac 100644
--- a/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs
+++ b/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics;
30using System.IO; 31using System.IO;
31using System.Reflection; 32using System.Reflection;
32using System.Xml; 33using System.Xml;
@@ -47,7 +48,7 @@ namespace OpenSim.Framework.Serialization.External
47 /// Populate a node with data read from xml using a dictinoary of processors 48 /// Populate a node with data read from xml using a dictinoary of processors
48 /// </summary> 49 /// </summary>
49 /// <param name="nodeToFill"></param> 50 /// <param name="nodeToFill"></param>
50 /// <param name="processors">/param> 51 /// <param name="processors"></param>
51 /// <param name="xtr"></param> 52 /// <param name="xtr"></param>
52 /// <returns>true on successful, false if there were any processing failures</returns> 53 /// <returns>true on successful, false if there were any processing failures</returns>
53 public static bool ExecuteReadProcessors<NodeType>( 54 public static bool ExecuteReadProcessors<NodeType>(
@@ -57,10 +58,10 @@ namespace OpenSim.Framework.Serialization.External
57 nodeToFill, 58 nodeToFill,
58 processors, 59 processors,
59 xtr, 60 xtr,
60 (o, name, e) 61 (o, nodeName, e) => {
61 => m_log.DebugFormat( 62 m_log.Debug(string.Format("[ExternalRepresentationUtils]: Error while parsing element {0} ",
62 "[ExternalRepresentationUtils]: Exception while parsing element {0}, continuing. Exception {1}{2}", 63 nodeName), e);
63 name, e.Message, e.StackTrace)); 64 });
64 } 65 }
65 66
66 /// <summary> 67 /// <summary>
@@ -80,18 +81,22 @@ namespace OpenSim.Framework.Serialization.External
80 Action<NodeType, string, Exception> parseExceptionAction) 81 Action<NodeType, string, Exception> parseExceptionAction)
81 { 82 {
82 bool errors = false; 83 bool errors = false;
84 int numErrors = 0;
85
86 Stopwatch timer = new Stopwatch();
87 timer.Start();
83 88
84 string nodeName = string.Empty; 89 string nodeName = string.Empty;
85 while (xtr.NodeType != XmlNodeType.EndElement) 90 while (xtr.NodeType != XmlNodeType.EndElement)
86 { 91 {
87 nodeName = xtr.Name; 92 nodeName = xtr.Name;
88 93
89// m_log.DebugFormat("[ExternalRepresentationUtils]: Processing: {0}", nodeName); 94 // m_log.DebugFormat("[ExternalRepresentationUtils]: Processing node: {0}", nodeName);
90 95
91 Action<NodeType, XmlReader> p = null; 96 Action<NodeType, XmlReader> p = null;
92 if (processors.TryGetValue(xtr.Name, out p)) 97 if (processors.TryGetValue(xtr.Name, out p))
93 { 98 {
94// m_log.DebugFormat("[ExternalRepresentationUtils]: Found {0} processor, nodeName); 99 // m_log.DebugFormat("[ExternalRepresentationUtils]: Found processor for {0}", nodeName);
95 100
96 try 101 try
97 { 102 {
@@ -101,6 +106,18 @@ namespace OpenSim.Framework.Serialization.External
101 { 106 {
102 errors = true; 107 errors = true;
103 parseExceptionAction(nodeToFill, nodeName, e); 108 parseExceptionAction(nodeToFill, nodeName, e);
109
110 if (xtr.EOF)
111 {
112 m_log.Debug("[ExternalRepresentationUtils]: Aborting ExecuteReadProcessors due to unexpected end of XML");
113 break;
114 }
115
116 if (++numErrors == 10)
117 {
118 m_log.Debug("[ExternalRepresentationUtils]: Aborting ExecuteReadProcessors due to too many parsing errors");
119 break;
120 }
104 121
105 if (xtr.NodeType == XmlNodeType.EndElement) 122 if (xtr.NodeType == XmlNodeType.EndElement)
106 xtr.Read(); 123 xtr.Read();
@@ -108,9 +125,16 @@ namespace OpenSim.Framework.Serialization.External
108 } 125 }
109 else 126 else
110 { 127 {
111 // m_log.DebugFormat("[LandDataSerializer]: caught unknown element {0}", nodeName); 128 // m_log.DebugFormat("[ExternalRepresentationUtils]: found unknown element \"{0}\"", nodeName);
112 xtr.ReadOuterXml(); // ignore 129 xtr.ReadOuterXml(); // ignore
113 } 130 }
131
132 if (timer.Elapsed.TotalSeconds >= 60)
133 {
134 m_log.Debug("[ExternalRepresentationUtils]: Aborting ExecuteReadProcessors due to timeout");
135 errors = true;
136 break;
137 }
114 } 138 }
115 139
116 return errors; 140 return errors;
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 875f4ad..a5f798d 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -2910,6 +2910,16 @@ namespace OpenSim.Framework
2910 2910
2911 return name; 2911 return name;
2912 } 2912 }
2913
2914 public static void LogFailedXML(string message, string xml)
2915 {
2916 int length = xml.Length;
2917 if (length > 2000)
2918 xml = xml.Substring(0, 2000) + "...";
2919
2920 m_log.ErrorFormat("{0} Failed XML ({1} bytes) = {2}", message, length, xml);
2921 }
2922
2913 } 2923 }
2914 2924
2915 public class DoubleQueue<T> where T:class 2925 public class DoubleQueue<T> where T:class
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index ac27716..b838177 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -2243,13 +2243,25 @@ namespace OpenSim.Region.Framework.Scenes
2243 2243
2244 if (isSingleObject || isAttachment) 2244 if (isSingleObject || isAttachment)
2245 { 2245 {
2246 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(reader); 2246 SceneObjectGroup g;
2247 try
2248 {
2249 g = SceneObjectSerializer.FromOriginalXmlFormat(reader);
2250 }
2251 catch (Exception e)
2252 {
2253 m_log.Error("[AGENT INVENTORY]: Deserialization of xml failed ", e);
2254 Util.LogFailedXML("[AGENT INVENTORY]:", xmlData);
2255 g = null;
2256 }
2257
2247 if (g != null) 2258 if (g != null)
2248 { 2259 {
2249 objlist.Add(g); 2260 objlist.Add(g);
2250 veclist.Add(Vector3.Zero); 2261 veclist.Add(Vector3.Zero);
2251 bbox = g.GetAxisAlignedBoundingBox(out offsetHeight); 2262 bbox = g.GetAxisAlignedBoundingBox(out offsetHeight);
2252 } 2263 }
2264
2253 return true; 2265 return true;
2254 } 2266 }
2255 else 2267 else
@@ -2291,9 +2303,8 @@ namespace OpenSim.Region.Framework.Scenes
2291 } 2303 }
2292 catch (Exception e) 2304 catch (Exception e)
2293 { 2305 {
2294 m_log.Error( 2306 m_log.Error("[AGENT INVENTORY]: Deserialization of xml failed when looking for CoalescedObject tag ", e);
2295 "[AGENT INVENTORY]: Deserialization of xml failed when looking for CoalescedObject tag. Exception ", 2307 Util.LogFailedXML("[AGENT INVENTORY]:", xmlData);
2296 e);
2297 } 2308 }
2298 2309
2299 return true; 2310 return true;
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs
index a556f9d..998789d 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs
@@ -178,10 +178,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
178 } 178 }
179 catch (Exception e) 179 catch (Exception e)
180 { 180 {
181 m_log.Error(string.Format( 181 m_log.Error("[COALESCED SCENE OBJECTS SERIALIZER]: Deserialization of xml failed ", e);
182 "[COALESCED SCENE OBJECTS SERIALIZER]: Deserialization of xml failed with {0} ", 182 Util.LogFailedXML("[COALESCED SCENE OBJECTS SERIALIZER]:", xml);
183 e.Message), e);
184
185 return false; 183 return false;
186 } 184 }
187 185
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 463ef22..4caa9cb 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -62,8 +62,20 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
62 { 62 {
63 String fixedData = ExternalRepresentationUtils.SanitizeXml(xmlData); 63 String fixedData = ExternalRepresentationUtils.SanitizeXml(xmlData);
64 using (XmlTextReader wrappedReader = new XmlTextReader(fixedData, XmlNodeType.Element, null)) 64 using (XmlTextReader wrappedReader = new XmlTextReader(fixedData, XmlNodeType.Element, null))
65 {
65 using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment })) 66 using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment }))
66 return FromOriginalXmlFormat(reader); 67 {
68 try {
69 return FromOriginalXmlFormat(reader);
70 }
71 catch (Exception e)
72 {
73 m_log.Error("[SERIALIZER]: Deserialization of xml failed ", e);
74 Util.LogFailedXML("[SERIALIZER]:", fixedData);
75 return null;
76 }
77 }
78 }
67 } 79 }
68 80
69 /// <summary> 81 /// <summary>
@@ -76,43 +88,33 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
76 //m_log.DebugFormat("[SOG]: Starting deserialization of SOG"); 88 //m_log.DebugFormat("[SOG]: Starting deserialization of SOG");
77 //int time = System.Environment.TickCount; 89 //int time = System.Environment.TickCount;
78 90
79 SceneObjectGroup sceneObject = null; 91 int linkNum;
80 92
81 try 93 reader.ReadToFollowing("RootPart");
82 { 94 reader.ReadToFollowing("SceneObjectPart");
83 int linkNum; 95 SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader));
96 reader.ReadToFollowing("OtherParts");
84 97
85 reader.ReadToFollowing("RootPart"); 98 if (reader.ReadToDescendant("Part"))
86 reader.ReadToFollowing("SceneObjectPart"); 99 {
87 sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader)); 100 do
88 reader.ReadToFollowing("OtherParts");
89
90 if (reader.ReadToDescendant("Part"))
91 { 101 {
92 do 102 if (reader.ReadToDescendant("SceneObjectPart"))
93 { 103 {
94 if (reader.ReadToDescendant("SceneObjectPart")) 104 SceneObjectPart part = SceneObjectPart.FromXml(reader);
95 { 105 linkNum = part.LinkNum;
96 SceneObjectPart part = SceneObjectPart.FromXml(reader); 106 sceneObject.AddPart(part);
97 linkNum = part.LinkNum; 107 part.LinkNum = linkNum;
98 sceneObject.AddPart(part); 108 part.TrimPermissions();
99 part.LinkNum = linkNum; 109 }
100 part.TrimPermissions(); 110 }
101 } 111 while (reader.ReadToNextSibling("Part"));
102 }
103 while (reader.ReadToNextSibling("Part"));
104 }
105
106 // Script state may, or may not, exist. Not having any, is NOT
107 // ever a problem.
108 sceneObject.LoadScriptState(reader);
109 }
110 catch (Exception e)
111 {
112 m_log.ErrorFormat("[SERIALIZER]: Deserialization of xml failed. Exception {0}", e);
113 return null;
114 } 112 }
115 113
114 // Script state may, or may not, exist. Not having any, is NOT
115 // ever a problem.
116 sceneObject.LoadScriptState(reader);
117
116 return sceneObject; 118 return sceneObject;
117 } 119 }
118 120
@@ -236,7 +238,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
236 238
237 if (parts.Count == 0) 239 if (parts.Count == 0)
238 { 240 {
239 m_log.ErrorFormat("[SERIALIZER]: Deserialization of xml failed: No SceneObjectPart nodes. xml was " + xmlData); 241 m_log.Error("[SERIALIZER]: Deserialization of xml failed: No SceneObjectPart nodes");
242 Util.LogFailedXML("[SERIALIZER]:", xmlData);
240 return null; 243 return null;
241 } 244 }
242 245
@@ -280,7 +283,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
280 } 283 }
281 catch (Exception e) 284 catch (Exception e)
282 { 285 {
283 m_log.ErrorFormat("[SERIALIZER]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData); 286 m_log.Error("[SERIALIZER]: Deserialization of xml failed ", e);
287 Util.LogFailedXML("[SERIALIZER]:", xmlData);
284 return null; 288 return null;
285 } 289 }
286 } 290 }
@@ -708,7 +712,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
708 private static void ProcessShape(SceneObjectPart obj, XmlReader reader) 712 private static void ProcessShape(SceneObjectPart obj, XmlReader reader)
709 { 713 {
710 List<string> errorNodeNames; 714 List<string> errorNodeNames;
711 obj.Shape = ReadShape(reader, "Shape", out errorNodeNames); 715 obj.Shape = ReadShape(reader, "Shape", out errorNodeNames, obj);
712 716
713 if (errorNodeNames != null) 717 if (errorNodeNames != null)
714 { 718 {
@@ -1599,18 +1603,21 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1599 1603
1600 reader.ReadStartElement("SceneObjectPart"); 1604 reader.ReadStartElement("SceneObjectPart");
1601 1605
1602 ExternalRepresentationUtils.ExecuteReadProcessors( 1606 bool errors = ExternalRepresentationUtils.ExecuteReadProcessors(
1603 obj, 1607 obj,
1604 m_SOPXmlProcessors, 1608 m_SOPXmlProcessors,
1605 reader, 1609 reader,
1606 (o, nodeName, e) 1610 (o, nodeName, e) => {
1607 => m_log.DebugFormat( 1611 m_log.Debug(string.Format("[SceneObjectSerializer]: Error while parsing element {0} in object {1} {2} ",
1608 "[SceneObjectSerializer]: Exception while parsing {0} in object {1} {2}: {3}{4}", 1612 nodeName, ((SceneObjectPart)o).Name, ((SceneObjectPart)o).UUID), e);
1609 ((SceneObjectPart)o).Name, ((SceneObjectPart)o).UUID, nodeName, e.Message, e.StackTrace)); 1613 });
1614
1615 if (errors)
1616 throw new XmlException(string.Format("Error parsing object {0} {1}", obj.Name, obj.UUID));
1610 1617
1611 reader.ReadEndElement(); // SceneObjectPart 1618 reader.ReadEndElement(); // SceneObjectPart
1612 1619
1613 //m_log.DebugFormat("[XXX]: parsed SOP {0} - {1}", obj.Name, obj.UUID); 1620 // m_log.DebugFormat("[SceneObjectSerializer]: parsed SOP {0} {1}", obj.Name, obj.UUID);
1614 return obj; 1621 return obj;
1615 } 1622 }
1616 1623
@@ -1655,7 +1662,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1655 /// <param name="name">The name of the xml element containing the shape</param> 1662 /// <param name="name">The name of the xml element containing the shape</param>
1656 /// <param name="errors">a list containing the failing node names. If no failures then null.</param> 1663 /// <param name="errors">a list containing the failing node names. If no failures then null.</param>
1657 /// <returns>The shape parsed</returns> 1664 /// <returns>The shape parsed</returns>
1658 public static PrimitiveBaseShape ReadShape(XmlReader reader, string name, out List<string> errorNodeNames) 1665 public static PrimitiveBaseShape ReadShape(XmlReader reader, string name, out List<string> errorNodeNames, SceneObjectPart obj)
1659 { 1666 {
1660 List<string> internalErrorNodeNames = null; 1667 List<string> internalErrorNodeNames = null;
1661 1668
@@ -1674,18 +1681,14 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1674 shape, 1681 shape,
1675 m_ShapeXmlProcessors, 1682 m_ShapeXmlProcessors,
1676 reader, 1683 reader,
1677 (o, nodeName, e) 1684 (o, nodeName, e) => {
1678 => 1685 m_log.Debug(string.Format("[SceneObjectSerializer]: Error while parsing element {0} in Shape property of object {1} {2} ",
1679 { 1686 nodeName, obj.Name, obj.UUID), e);
1680// m_log.DebugFormat(
1681// "[SceneObjectSerializer]: Exception while parsing Shape property {0}: {1}{2}",
1682// nodeName, e.Message, e.StackTrace);
1683 if (internalErrorNodeNames == null)
1684 internalErrorNodeNames = new List<string>();
1685 1687
1686 internalErrorNodeNames.Add(nodeName); 1688 if (internalErrorNodeNames == null)
1687 } 1689 internalErrorNodeNames = new List<string>();
1688 ); 1690 internalErrorNodeNames.Add(nodeName);
1691 });
1689 1692
1690 reader.ReadEndElement(); // Shape 1693 reader.ReadEndElement(); // Shape
1691 1694