diff options
author | Oren Hurvitz | 2015-07-05 16:05:01 +0300 |
---|---|---|
committer | Oren Hurvitz | 2015-08-11 07:35:37 +0100 |
commit | 4ad1468165b80f67439399e36688d36944996312 (patch) | |
tree | 541cfb87ecae92a3bff53aaa8875b06d83878a35 /OpenSim/Framework/Serialization/External | |
parent | Fixed mistakes in string format specifiers (e.g., "{0)" instead of {0}") (diff) | |
download | opensim-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/Framework/Serialization/External')
-rw-r--r-- | OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs | 40 |
1 files changed, 32 insertions, 8 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 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Diagnostics; | ||
30 | using System.IO; | 31 | using System.IO; |
31 | using System.Reflection; | 32 | using System.Reflection; |
32 | using System.Xml; | 33 | using 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; |