forked from VahidN/iTextSharp.LGPLv2.Core
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathParserBase.cs
More file actions
144 lines (125 loc) · 4.48 KB
/
ParserBase.cs
File metadata and controls
144 lines (125 loc) · 4.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using System.util;
using System.Xml;
namespace iTextSharp.text.xml;
/// <summary>
/// The ParserBase -class provides XML document parsing.
/// </summary>
public abstract class ParserBase
{
/// <summary>
/// Secure XML reader settings that prevent XXE attacks (CVE-2017-9096)
/// by disabling DTD processing and external entity resolution.
/// </summary>
public static readonly XmlReaderSettings SecureXmlReaderSettings = new XmlReaderSettings
{
DtdProcessing = DtdProcessing.Prohibit,
XmlResolver = null
};
/// <summary>
/// This method gets called when characters are encountered.
/// </summary>
/// <param name="content">an array of characters</param>
/// <param name="start">the start position in the array</param>
/// <param name="length">the number of characters to read from the array</param>
public abstract void Characters(string content, int start, int length);
/// <summary>
/// This method gets called when an end tag is encountered.
/// </summary>
/// <param name="uri"></param>
/// <param name="lname"></param>
/// <param name="name">the name of the tag that ends</param>
public abstract void EndElement(string uri, string lname, string name);
public void Parse(XmlDocument xDoc)
{
if (xDoc == null)
{
throw new ArgumentNullException(nameof(xDoc));
}
var xml = xDoc.OuterXml;
var stringReader = new StringReader(xml);
var reader = XmlReader.Create(stringReader, SecureXmlReaderSettings);
Parse(reader);
}
public void Parse(XmlReader reader)
{
if (reader == null)
{
throw new ArgumentNullException(nameof(reader));
}
try
{
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
var namespaceUri = reader.NamespaceURI;
var name = reader.Name;
var isEmpty = reader.IsEmptyElement;
var attributes = new NullValueDictionary<string, string>();
if (reader.HasAttributes)
{
for (var i = 0; i < reader.AttributeCount; i++)
{
reader.MoveToAttribute(i);
attributes.Add(reader.Name, reader.Value);
}
}
StartElement(namespaceUri, name, name, attributes);
if (isEmpty)
{
EndElement(namespaceUri, name, name);
}
break;
case XmlNodeType.EndElement:
EndElement(reader.NamespaceURI, reader.Name, reader.Name);
break;
case XmlNodeType.Text:
Characters(reader.Value, start: 0, reader.Value.Length);
break;
// There are many other types of nodes, but
// we are not interested in them
case XmlNodeType.Whitespace:
Characters(reader.Value, start: 0, reader.Value.Length);
break;
}
}
}
catch (XmlException)
{
// ...
}
finally
{
if (reader != null)
{
#if NET40
reader.Close();
#else
reader.Dispose();
#endif
}
}
}
/// <summary>
/// Begins the process of processing an XML document
/// </summary>
/// <param name="url">the XML document to parse</param>
public void Parse(string url)
{
var stringReader = new StringReader(File.ReadAllText(url));
var reader = XmlReader.Create(stringReader, SecureXmlReaderSettings);
Parse(reader);
}
/// <summary>
/// This method gets called when a start tag is encountered.
/// </summary>
/// <param name="uri"></param>
/// <param name="lname"></param>
/// <param name="name">the name of the tag that is encountered</param>
/// <param name="attrs">the list of attributes</param>
public abstract void StartElement(string uri,
string lname,
string name,
INullValueDictionary<string, string> attrs);
}