2 // XmlSimpleDictionaryReaderTest.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2007 Novell, Inc. http://www.novell.com
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using NUnit.Framework;
36 namespace MonoTests.System.Xml
39 public class XmlBinaryDictionaryReaderTest
41 void Read (byte [] buf)
43 XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader (new MemoryStream (buf), new XmlDictionaryReaderQuotas ());
47 // FIXME: use this instead; right now some tests are broken.
48 //XmlDocument doc = new XmlDocument ();
49 //doc.AppendChild (doc.CreateElement ("root"));
51 // doc.DocumentElement.AppendChild (doc.ReadNode (reader));
54 void AssertNode (XmlNodeType nodeType, string localName, string ns, string value, int depth, XmlReader reader, string label)
56 Assert.AreEqual (nodeType, reader.NodeType, label + ".Node");
57 Assert.AreEqual (localName, reader.LocalName, label + ".LocalName");
58 Assert.AreEqual (ns, reader.NamespaceURI, label + ".NS");
59 Assert.AreEqual (value, reader.Value, label + ".Value");
60 Assert.AreEqual (depth, reader.Depth, label + ".Depth");
64 [ExpectedException (typeof (ArgumentNullException))]
65 public void NullQuotas ()
67 XmlDictionaryReader.CreateBinaryReader (usecase1,null);
71 public void UseCase1 ()
73 string xml = @"<?xml version=""1.0"" encoding=""utf-16""?><root a=""""><!----> <AAA xmlns=""urn:AAA""></AAA><ePfix:AAA xmlns:ePfix=""urn:AAABBB""></ePfix:AAA><AAA>CCC" + "\u3005\u4E00" + @"CCCAAA&AAADDD&DDD" + '\u4E01' + @"<!--COMMENT--></AAA><AAA BBB=""bbb"" pfix:BBB=""bbbbb"" xml:lang=""ja"" xml:space=""preserve"" xml:base=""local:hogehoge"" xmlns:pfix=""urn:bbb"">CCCICAg/4Aw</AAA></root>";
75 XmlDictionaryReader reader =
76 XmlDictionaryReader.CreateBinaryReader (usecase1,new XmlDictionaryReaderQuotas ());
77 StringWriter sw = new StringWriter ();
78 XmlWriter xw = XmlWriter.Create (sw);
81 xw.WriteNode (reader, false);
83 Assert.AreEqual (xml, sw.ToString ());
88 static readonly byte [] usecase1 = new byte [] {
89 // $!root$! a....!__ ___.!AAA $!urn:AA A$$!ePfi
90 0x40, 0x04, 0x72, 0x6F, 0x6F, 0x74, 0x04, 0x01,
91 0x61, 0xA8, 0x02, 0x00, 0x98, 0x05, 0x20, 0x20,
92 0x20, 0x20, 0x20, 0x40, 0x03, 0x41, 0x41, 0x41,
93 0x08, 0x07, 0x75, 0x72, 0x6E, 0x3A, 0x41, 0x41,
94 0x41, 0x01, 0x41, 0x05, 0x65, 0x50, 0x66, 0x69,// 40
95 // x!AAA$!e Pfix!urn :AAABBB$ $!AAA$!C CC......
96 0x78, 0x03, 0x41, 0x41, 0x41, 0x09, 0x05, 0x65,
97 0x50, 0x66, 0x69, 0x78, 0x0A, 0x75, 0x72, 0x6E,
98 0x3A, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x01,
99 0x40, 0x03, 0x41, 0x41, 0x41, 0x98, 0x0C, 0x43,
100 0x43, 0x43, 0xE3, 0x80, 0x85, 0xE4, 0xB8, 0x80,// 80
101 // AAA$!DDD $AAA$!DD D$DDD... ..$!COMM ENT$$!AA
102 0x43, 0x43, 0x43, 0x98, 0x07, 0x41, 0x41, 0x41,
103 0x26, 0x41, 0x41, 0x41, 0x98, 0x07, 0x44, 0x44,
104 0x44, 0x26, 0x44, 0x44, 0x44, 0x98, 0x03, 0xE4,
105 0xB8, 0x81, 0x02, 0x07, 0x43, 0x4F, 0x4D, 0x4D,
106 0x45, 0x4E, 0x54, 0x01, 0x40, 0x03, 0x41, 0x41,// 120
107 // A$!BBB$! bbb$!pfi x!BBB$!b bbbb$!xm l!lang$!
108 0x41, 0x04, 0x03, 0x42, 0x42, 0x42, 0x98, 0x03,
109 0x62, 0x62, 0x62, 0x05, 0x04, 0x70, 0x66, 0x69,
110 0x78, 0x03, 0x42, 0x42, 0x42, 0x98, 0x05, 0x62,
111 0x62, 0x62, 0x62, 0x62, 0x05, 0x03, 0x78, 0x6D,
112 0x6C, 0x04, 0x6C, 0x61, 0x6E, 0x67, 0x98, 0x02,// 160
113 // ja$!xml! space$!p reserve
114 0x6A, 0x61, 0x05, 0x03, 0x78, 0x6D, 0x6C, 0x05,
115 0x73, 0x70, 0x61, 0x63, 0x65, 0x98, 0x08, 0x70,
116 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x05,
117 0x03, 0x78, 0x6D, 0x6C, 0x04, 0x62, 0x61, 0x73,
118 0x65, 0x98, 0x0E, 0x6C, 0x6F, 0x63, 0x61, 0x6C,// 200
119 // ..hogehog e$!pfix! urn:bbb$ $CCC$!BA SE64$
120 0x3A, 0x68, 0x6F, 0x67, 0x65, 0x68, 0x6F, 0x67,
121 0x65, 0x09, 0x04, 0x70, 0x66, 0x69, 0x78, 0x07,
122 0x75, 0x72, 0x6E, 0x3A, 0x62, 0x62, 0x62, 0x98,
123 0x03, 0x43, 0x43, 0x43, 0x9F, 0x06, 0x20, 0x20,
124 0x20, 0xFF, 0x80, 0x30, 0x01,
128 public void UseCase2 ()
130 XmlDictionary dic = new XmlDictionary ();
132 dic.Add (String.Empty);
137 XmlDictionaryReader reader =
138 XmlDictionaryReader.CreateBinaryReader (new MemoryStream (usecase2), dic, new XmlDictionaryReaderQuotas ());
144 // / : especially. EndElement
146 // @ : dictionary index
147 // ^ : missing ns decl?
148 static readonly byte [] usecase2 = new byte [] {
149 // $@$!BAR$ @$@///$@ ^@$!ppp! $!ppp@$! xyz$!bbb
150 0x42, 2, 0x40, 3, 0x42, 0x41, 0x52, 0x42,
151 2, 0x42, 4, 1, 1, 1, 0x42, 4,
152 10, 6, 0x43, 3, 0x70, 0x70, 0x70, 4,
153 11, 3, 0x70, 0x70, 0x70, 6, 0x99, 3,
154 0x78, 0x79, 0x7A, 0x98, 4, 0x62, 0x62, 0x62,
155 // b$!ccc$G UIDGUIDG UIDGUID$ !FOO$!GU IDGUIDGU
156 0x62, 0x98, 3, 0x63, 0x63, 0x63, 0xB1, 0x22,
157 0x22, 0x11, 0x11, 0x33, 0x33, 0x44, 0x44, 0x55,
158 0x55, 0x66, 0x66, 0x77, 0x77, 0x88, 0x88, 0x40,
159 3, 0x46, 0x4F, 0x4F, 0x04, 3, 0x41, 0x41,
160 0x41, 0xB0, 0x22, 0x22, 0x11, 0x11, 0x33, 0x33,
161 // IDGUIDGU ID$!BBB$T IMESPAN $!CC$!UN IQUEIDUN
162 0x44, 0x44, 0x55, 0x55, 0x66, 0x66, 0x77, 0x77,
163 0x88, 0x88, 0x04, 3, 0x42, 0x42, 0x42, 0xAE,
164 0, 0, 0, 0, 0, 0, 0, 0,
165 0x04, 2, 0x43, 0x43, 0x98, 0x2B, 0x75, 0x75,
166 0x69, 0x64, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x30,
167 // IQUEIDUN IQUEIDUN IQUEIDUN IQUEID.. .$!XX$$$!
168 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30,
169 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30,
170 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x30,
171 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2D,
172 0x31, 0x40, 2, 0x58, 0x58, 0x86, 0x85, 0x41, 2,
173 // xx!aaa$!x x!urn:xxx
174 0x78, 0x78, 3, 0x61, 0x61, 0x61, 0x09, 2, 0x78,
175 0x78, 0x07, 0x75, 0x72, 0x6E, 0x3A, 0x7A, 0x7A,
180 public void ElementWithNS ()
182 byte [] bytes = new byte [] {
183 0x42, 0, 10, 2, 0x98, 3, 0x61, 0x61,
184 0x61, 0x42, 0, 0x42, 2, 1, 1, 1};
186 XmlDictionary dic = new XmlDictionary ();
190 XmlDictionaryReader reader =
191 XmlDictionaryReader.CreateBinaryReader (new MemoryStream (bytes), dic, new XmlDictionaryReaderQuotas ());
197 public void ContainsInvalidIndex ()
199 byte [] bytes = new byte [] {
200 0x42, 1, 10, 2, 0x98, 3, 0x61, 0x61,
201 0x61, 0x42, 0, 0x42, 2, 1, 1, 1};
203 XmlDictionary dic = new XmlDictionary ();
207 XmlDictionaryReader dr = XmlDictionaryReader.CreateBinaryReader (new MemoryStream (bytes), dic, new XmlDictionaryReaderQuotas ());
210 Assert.Fail ("dictionary index 1 should be regarded as invalid.");
211 } catch (XmlException) {
216 public void Beyond128DictionaryEntries ()
218 XmlDictionaryString ds;
219 MemoryStream ms = new MemoryStream ();
220 XmlDictionary dic = new XmlDictionary ();
221 for (int i = 0; i < 260; i++)
222 Assert.AreEqual (i, dic.Add ("n" + i).Key, "dic");
223 XmlDictionary dic2 = new XmlDictionary ();
224 XmlBinaryReaderSession session = new XmlBinaryReaderSession ();
226 for (int i = 0; i < 260; i++)
227 Assert.AreEqual (i, session.Add (i, "s" + i).Key, "session");
229 byte [] bytes = new byte [] {
230 // so, when it went beyond 128, the index
231 // becomes 2 bytes, where
232 // - the first byte always becomes > 80, and
233 // - the second byte becomes (n / 0x80) * 2.
234 0x42, 0x80, 2, 0x0A, 0x82, 2,
235 0x42, 0x85, 2, 0x0A, 0x87, 2,
236 0x42, 0x88, 2, 0x0A, 0x8B, 2,
237 0x42, 0x80, 4, 0x0A, 0x81, 4,
240 XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader (new MemoryStream (bytes), dic, new XmlDictionaryReaderQuotas (), session);
241 Assert.IsTrue (reader.Read (), "#r1");
242 Assert.AreEqual ("n128", reader.LocalName, "#l1");
243 Assert.IsTrue (reader.Read (), "#r2");
244 Assert.AreEqual ("s130", reader.LocalName, "#l1");
245 Assert.IsTrue (reader.Read (), "#r3");
246 Assert.AreEqual ("n132", reader.LocalName, "#l1");
247 Assert.IsTrue (reader.Read (), "#r4");
248 Assert.AreEqual ("n256", reader.LocalName, "#l1");
249 for (int i = 0; i < 4; i++) {
250 Assert.IsTrue (reader.Read (), "#re" + i);
251 Assert.AreEqual (XmlNodeType.EndElement, reader.NodeType, "#ne" + i);
253 Assert.IsFalse (reader.Read ()); // EOF
257 public void GlobalAttributes ()
259 XmlDictionary dic = new XmlDictionary ();
268 // 0x0C nameidx (value) 0x0D nameidx (value)
269 // 0x07 (prefix) nameidx (value)
270 // 0x05 (prefix) (name) (value)
271 // 0x04... 0x06... 0x05...
273 // 0x0B (prefix) nsidx
275 // 0x09 (prefix) (ns)
276 byte [] bytes = new byte [] {
279 // $!aaa!$! bbb$urn:foo$
282 0x0D, 6, 0x98, 1, 0x76,
283 0x07, 3, 0x61, 0x61, 0x61, 8, 0xA8, // 16
284 0x05, 3, 0x62, 0x62, 0x62, 2, 0x6E, 0x35, 0xA8,
285 0x04, 2, 0x6E, 0x36, 0xA8, // 30
287 0x05, 3, 0x62, 0x62, 0x62, 2, 0x6E, 0x38, 0xA8,
289 0x0B, 1, 0x61, 10, // 48
291 0x0B, 3, 0x61, 0x61, 0x61, 10,
292 0x09, 3, 0x62, 0x62, 0x62,
293 0x07, 0x75, 0x72, 0x6E, 0x3A, 0x66, 0x6F, 0x6F,
296 XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader (new MemoryStream (bytes), dic, new XmlDictionaryReaderQuotas ());
302 public void AttributeXmlns ()
304 // equivalent to WriteXmlnsAttribute()
305 XmlDictionaryString ds;
306 XmlDictionary dic = new XmlDictionary ();
308 dic.Add ("http://www.w3.org/2000/xmlns/");
310 byte [] bytes = new byte [] {
311 // 40 (root) 04 (a) A8
312 // 09 (foo) (urn:foo) 08 (urn:bar)
313 0x40, 4, 0x72, 0x6F, 0x6F, 0x74,
315 0x09, 3, 0x66, 0x6F, 0x6F, 7, 0x75, 0x72, 0x6E, 0x3A, 0x66, 0x6F, 0x6F,
316 0x08, 7, 0x75, 0x72, 0x6E, 0x3A, 0x62, 0x61, 0x72, 1
321 XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader (new MemoryStream (bytes), new XmlDictionaryReaderQuotas ());
322 Assert.IsTrue (reader.Read (), "#1-1");
323 AssertNode (XmlNodeType.Element, "root", "urn:bar", "", 0, reader, "#1");
324 reader.MoveToAttribute (0);
325 if (reader.LocalName != "a")
326 reader.MoveToAttribute (1);
327 AssertNode (XmlNodeType.Attribute, "a", "", "", 1, reader, "#2");
328 Assert.IsTrue (reader.ReadAttributeValue (), "#3");
329 AssertNode (XmlNodeType.Text, "a", "", "", 2, reader, "#4");
330 Assert.IsFalse (reader.ReadAttributeValue (), "#5");
334 public void ReadTypedValues ()
339 byte [] typed_values = new byte [] {
340 0x40, 4, 0x72, 0x6F, 0x6F, 0x74,
343 0x8C, 0xBC, 0x92, 0, 0, // int
344 0x8C, 0x2C, 0xEB, 0x6D, 0x08, // 20
345 0x8E, 0x80, 0x55, 0xF5, 0x51, 0x01, 0, 0, 0,
346 0x90, 0xD7, 0xB3, 0xDD, 0x3F, // float
347 0x92, 0x4C, 0x15, 0x31, 0x91, 0x77, 0xE3, 0x01, 0x40, // 43
348 0x94, 0, 0, 6, 0, 0, 0, 0, 0, 0xD8, 0xEF, 0x2F, 0, 0, 0, 0, 0,
349 0x97, 0x80, 0x40, 0xA3, 0x29, 0xE5, 0x22, 0xC1, 8
353 public void ReadShortPrefixedElement ()
355 Read (short_prefixed_elem_value);
358 static readonly byte [] short_prefixed_elem_value = {
359 0x6D, 4, 0x72, 0x6F, 0x6F, 0x74,
360 0x09, 1, 0x70, 7, 0x75, 0x72, 0x6E, 0x3A, 0x66, 0x6F, 0x6F,
361 0x99, 4, 0x74, 0x65, 0x73, 0x74,
365 public void ReadInt16Array ()
369 XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader (new MemoryStream (array_int16), new XmlDictionaryReaderQuotas ());
370 Assert.IsTrue (reader.Read (), "#1-1");
371 AssertNode (XmlNodeType.Element, "el", "", "", 0, reader, "#1-2");
372 Assert.IsTrue (reader.Read (), "#2-1");
373 AssertNode (XmlNodeType.Text, "", "", "4", 1, reader, "#2-2");
374 Assert.IsTrue (reader.Read (), "#3-1");
375 AssertNode (XmlNodeType.EndElement, "el", "", "", 0, reader, "#3-2");
376 Assert.IsTrue (reader.Read (), "#4-1");
377 AssertNode (XmlNodeType.Element, "el", "", "", 0, reader, "#4-2");
378 Assert.IsTrue (reader.Read (), "#5-1");
379 AssertNode (XmlNodeType.Text, "", "", "6", 1, reader, "#5-2");
380 Assert.IsTrue (reader.Read (), "#6-1");
381 AssertNode (XmlNodeType.EndElement, "el", "", "", 0, reader, "#6-2");
382 for (int i = 0; i < 3; i++) // 6, 8, 10
383 for (int j = 0; j < 3; j++) // el / text / endel
384 Assert.IsTrue (reader.Read (), "#x-" + i + j);
385 Assert.IsFalse (reader.Read (), "End");
388 static readonly byte [] array_int16 = {
389 0x03, 0x40, 2, 0x65, 0x6C, 0x01,
390 0x8B, 5, 4, 0, 6, 0, 8, 0, 10, 0, 12, 0,
394 public void ReadInt32Array ()
399 // make sure that 0 is not written in shortened format.
400 static readonly byte [] array_int32 = {
401 0x03, 0x40, 2, 0x65, 0x6C, 0x01,
402 0x8D, 3, 0, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0,
406 public void ReadUtf16Array ()
408 // example of SOAP fault returned by .NET.
409 var buffer = new byte [] {
410 0x56,0x02,0x0B,0x01,0x73,0x04,0x0B,0x01,0x61,0x06,0x56,0x08,0x44,0x0A,0x1E,0x00,
411 0x82,0x99,0x2F,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x77,0x33,
412 0x2E,0x6F,0x72,0x67,0x2F,0x32,0x30,0x30,0x35,0x2F,0x30,0x38,0x2F,0x61,0x64,0x64,
413 0x72,0x65,0x73,0x73,0x69,0x6E,0x67,0x2F,0x73,0x6F,0x61,0x70,0x2F,0x66,0x61,0x75,
414 0x6C,0x74,0x44,0x0C,0x1E,0x00,0x82,0xAB,0x14,0x01,0x56,0x0E,0x56,0x86,0x01,0x56,
415 0x8E,0x01,0x56,0x9A,0x01,0x98,0x01,0x73,0x98,0x01,0x3A,0x99,0x06,0x53,0x65,0x6E,
416 0x64,0x65,0x72,0x56,0x9C,0x01,0x56,0x9A,0x01,0x98,0x01,0x61,0x98,0x01,0x3A,0x99,
417 0x16,0x44,0x65,0x73,0x74,0x69,0x6E,0x61,0x74,0x69,0x6F,0x6E,0x55,0x6E,0x72,0x65,
418 0x61,0x63,0x68,0x61,0x62,0x6C,0x65,0x01,0x01,0x56,0x90,0x01,0x56,0x92,0x01,0x05,
419 0x03,0x78,0x6D,0x6C,0x04,0x6C,0x61,0x6E,0x67,0x98,0x05,0x6A,0x61,0x2D,0x4A,0x50,
420 0xB7,0xEA,0x45,0x00,0x6E,0x00,0x64,0x00,0x70,0x00,0x6F,0x00,0x69,0x00,0x6E,0x00,
421 0x74,0x00,0x44,0x00,0x69,0x00,0x73,0x00,0x70,0x00,0x61,0x00,0x74,0x00,0x63,0x00,
422 0x68,0x00,0x65,0x00,0x72,0x00,0x20,0x00,0x67,0x30,0x20,0x00,0x41,0x00,0x64,0x00,
423 0x64,0x00,0x72,0x00,0x65,0x00,0x73,0x00,0x73,0x00,0x46,0x00,0x69,0x00,0x6C,0x00,
424 0x74,0x00,0x65,0x00,0x72,0x00,0x20,0x00,0x4C,0x30,0x00,0x4E,0xF4,0x81,0x57,0x30,
425 0x66,0x30,0x44,0x30,0x6A,0x30,0x44,0x30,0x5F,0x30,0x81,0x30,0x01,0x30,0x54,0x00,
426 0x6F,0x00,0x20,0x00,0x27,0x00,0x27,0x00,0x20,0x00,0x92,0x30,0x2B,0x54,0x80,0x30,
427 0xE1,0x30,0xC3,0x30,0xBB,0x30,0xFC,0x30,0xB8,0x30,0x92,0x30,0xD7,0x53,0xE1,0x4F,
428 0x74,0x50,0x67,0x30,0xE6,0x51,0x06,0x74,0x67,0x30,0x4D,0x30,0x7E,0x30,0x5B,0x30,
429 0x93,0x30,0x02,0x30,0x01,0x90,0xE1,0x4F,0x74,0x50,0x68,0x30,0xD7,0x53,0xE1,0x4F,
430 0x74,0x50,0x6E,0x30,0x20,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x70,0x00,0x6F,0x00,
431 0x69,0x00,0x6E,0x00,0x74,0x00,0x41,0x00,0x64,0x00,0x64,0x00,0x72,0x00,0x65,0x00,
432 0x73,0x00,0x73,0x00,0x20,0x00,0x4C,0x30,0x00,0x4E,0xF4,0x81,0x57,0x30,0x66,0x30,
433 0x44,0x30,0x8B,0x30,0x53,0x30,0x68,0x30,0x92,0x30,0xBA,0x78,0x8D,0x8A,0x57,0x30,
434 0x66,0x30,0x4F,0x30,0x60,0x30,0x55,0x30,0x44,0x30,0x02,0x30,0x01,0x01,0x01,0x01};
435 var dic = new XmlDictionary ();
436 for (int i = 0; i < 128; i++) dic.Add ("s" + i);
437 var xr = XmlDictionaryReader.CreateBinaryReader (new MemoryStream (buffer), dic, new XmlDictionaryReaderQuotas ());
440 if (xr.NodeType == XmlNodeType.EndElement && xr.LocalName == String.Empty)
441 Assert.Fail ("EndElement has empty name");