blob: 357ef677e99f5ab332bcfcef36594eec03b10072 [file] [log] [blame]
U-Lama\Leee13c3e62011-12-28 14:36:55 -08001#include "tinyxml2.h"
2
3#include <stdio.h>
4#include <stdlib.h>
Lee Thomasonec5a7b42012-02-13 18:16:52 -08005#include <string.h>
U-Lama\Leee13c3e62011-12-28 14:36:55 -08006
Lee Thomason (grinliz)2a1cd272012-02-24 17:37:53 -08007#if defined( _MSC_VER )
Lee Thomason1ff38e02012-02-14 18:18:16 -08008 #include <crtdbg.h>
9 _CrtMemState startMemState;
10 _CrtMemState endMemState;
11#endif
Lee Thomasone9ecdab2012-02-13 18:11:20 -080012
U-Lama\Leee13c3e62011-12-28 14:36:55 -080013using namespace tinyxml2;
Lee Thomasonec5a7b42012-02-13 18:16:52 -080014int gPass = 0;
15int gFail = 0;
16
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -080017
U-Stream\Lee09a11c52012-02-17 08:31:16 -080018bool XMLTest (const char* testString, const char* expected, const char* found, bool echo=true )
Lee Thomason1ff38e02012-02-14 18:18:16 -080019{
20 bool pass = !strcmp( expected, found );
21 if ( pass )
22 printf ("[pass]");
23 else
24 printf ("[fail]");
25
U-Stream\Lee09a11c52012-02-17 08:31:16 -080026 if ( !echo )
Lee Thomason1ff38e02012-02-14 18:18:16 -080027 printf (" %s\n", testString);
28 else
29 printf (" %s [%s][%s]\n", testString, expected, found);
30
31 if ( pass )
32 ++gPass;
33 else
34 ++gFail;
35 return pass;
36}
37
38
U-Stream\Lee09a11c52012-02-17 08:31:16 -080039bool XMLTest( const char* testString, int expected, int found, bool echo=true )
Lee Thomason1ff38e02012-02-14 18:18:16 -080040{
41 bool pass = ( expected == found );
42 if ( pass )
43 printf ("[pass]");
44 else
45 printf ("[fail]");
46
U-Stream\Lee09a11c52012-02-17 08:31:16 -080047 if ( !echo )
Lee Thomason1ff38e02012-02-14 18:18:16 -080048 printf (" %s\n", testString);
49 else
50 printf (" %s [%d][%d]\n", testString, expected, found);
51
52 if ( pass )
53 ++gPass;
54 else
55 ++gFail;
56 return pass;
57}
Lee Thomasonec5a7b42012-02-13 18:16:52 -080058
U-Lama\Leee13c3e62011-12-28 14:36:55 -080059
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -080060void NullLineEndings( char* p )
61{
62 while( p && *p ) {
63 if ( *p == '\n' || *p == '\r' ) {
64 *p = 0;
65 return;
66 }
67 ++p;
68 }
69}
70
71
U-Lama\Leee13c3e62011-12-28 14:36:55 -080072int main( int argc, const char* argv )
73{
Lee Thomason (grinliz)2a1cd272012-02-24 17:37:53 -080074 #if defined( _MSC_VER )
Lee Thomason1ff38e02012-02-14 18:18:16 -080075 _CrtMemCheckpoint( &startMemState );
76 #endif
Lee Thomason8a5dfee2012-01-18 17:43:40 -080077
Lee Thomason8a5dfee2012-01-18 17:43:40 -080078 {
Lee Thomason43f59302012-02-06 18:18:11 -080079 static const char* test[] = { "<element />",
80 "<element></element>",
81 "<element><subelement/></element>",
82 "<element><subelement></subelement></element>",
83 "<element><subelement><subsub/></subelement></element>",
84 "<!--comment beside elements--><element><subelement></subelement></element>",
85 "<!--comment beside elements, this time with spaces--> \n <element> <subelement> \n </subelement> </element>",
86 "<element attrib1='foo' attrib2=\"bar\" ></element>",
87 "<element attrib1='foo' attrib2=\"bar\" ><subelement attrib3='yeehaa' /></element>",
88 "<element>Text inside element.</element>",
89 "<element><b></b></element>",
90 "<element>Text inside and <b>bolded</b> in the element.</element>",
91 "<outer><element>Text inside and <b>bolded</b> in the element.</element></outer>",
Lee Thomason8ee79892012-01-25 17:44:30 -080092 "<element>This &amp; That.</element>",
Lee Thomason18d68bd2012-01-26 18:17:26 -080093 "<element attrib='This&lt;That' />",
Lee Thomasondadcdfa2012-01-18 17:55:48 -080094 0
95 };
Lee Thomason6ee99fc2012-01-21 18:45:16 -080096 for( int i=0; test[i]; ++i ) {
Lee Thomasondadcdfa2012-01-18 17:55:48 -080097 XMLDocument doc;
Lee Thomason6ee99fc2012-01-21 18:45:16 -080098 doc.Parse( test[i] );
Lee Thomason5cae8972012-01-24 18:03:07 -080099 doc.Print();
Lee Thomasonec975ce2012-01-23 11:42:06 -0800100 printf( "----------------------------------------------\n" );
Lee Thomasondadcdfa2012-01-18 17:55:48 -0800101 }
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800102 }
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800103#if 1
Lee Thomasond6277762012-02-22 16:00:12 -0800104 {
105 static const char* test = "<!--hello world\n"
106 " line 2\r"
107 " line 3\r\n"
108 " line 4\n\r"
109 " line 5\r-->";
110
111 XMLDocument doc;
112 doc.Parse( test );
113 doc.Print();
114 }
115
Lee Thomason2c85a712012-01-31 08:24:24 -0800116 {
117 static const char* test = "<element>Text before.</element>";
118 XMLDocument doc;
119 doc.Parse( test );
120 XMLElement* root = doc.FirstChildElement();
121 XMLElement* newElement = doc.NewElement( "Subelement" );
122 root->InsertEndChild( newElement );
123 doc.Print();
124 }
Lee Thomasond1983222012-02-06 08:41:24 -0800125 {
126 XMLDocument* doc = new XMLDocument();
127 static const char* test = "<element><sub/></element>";
128 doc->Parse( test );
129 delete doc;
130 }
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800131 {
Lee Thomason1ff38e02012-02-14 18:18:16 -0800132 // Test: Programmatic DOM
Lee Thomasonec5a7b42012-02-13 18:16:52 -0800133 // Build:
134 // <element>
135 // <!--comment-->
136 // <sub attrib="1" />
137 // <sub attrib="2" />
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800138 // <sub attrib="3" >& Text!</sub>
Lee Thomasonec5a7b42012-02-13 18:16:52 -0800139 // <element>
140
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800141 XMLDocument* doc = new XMLDocument();
Lee Thomason1ff38e02012-02-14 18:18:16 -0800142 XMLNode* element = doc->InsertEndChild( doc->NewElement( "element" ) );
143
144 XMLElement* sub[3] = { doc->NewElement( "sub" ), doc->NewElement( "sub" ), doc->NewElement( "sub" ) };
145 for( int i=0; i<3; ++i ) {
146 sub[i]->SetAttribute( "attrib", i );
147 }
148 element->InsertEndChild( sub[2] );
149 XMLNode* comment = element->InsertFirstChild( doc->NewComment( "comment" ) );
150 element->InsertAfterChild( comment, sub[0] );
151 element->InsertAfterChild( sub[0], sub[1] );
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800152 sub[2]->InsertFirstChild( doc->NewText( "& Text!" ));
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800153 doc->Print();
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800154 XMLTest( "Programmatic DOM", "comment", doc->FirstChildElement( "element" )->FirstChild()->Value() );
155 XMLTest( "Programmatic DOM", "0", doc->FirstChildElement( "element" )->FirstChildElement()->Attribute( "attrib" ) );
156 XMLTest( "Programmatic DOM", 2, doc->FirstChildElement()->LastChildElement( "sub" )->IntAttribute( "attrib" ) );
157 XMLTest( "Programmatic DOM", "& Text!",
158 doc->FirstChildElement()->LastChildElement( "sub" )->FirstChild()->ToText()->Value() );
U-Stream\Leeae25a442012-02-17 17:48:16 -0800159
160 // And now deletion:
161 element->DeleteChild( sub[2] );
162 doc->DeleteNode( comment );
163
164 element->FirstChildElement()->SetAttribute( "attrib", true );
165 element->LastChildElement()->DeleteAttribute( "attrib" );
166
167 XMLTest( "Programmatic DOM", true, doc->FirstChildElement()->FirstChildElement()->BoolAttribute( "attrib" ) );
168 int value = 10;
169 int result = doc->FirstChildElement()->LastChildElement()->QueryIntAttribute( "attrib", &value );
170 XMLTest( "Programmatic DOM", result, NO_ATTRIBUTE );
171 XMLTest( "Programmatic DOM", value, 10 );
172
173 doc->Print();
174
Lee Thomason (grinliz)2a1cd272012-02-24 17:37:53 -0800175 XMLPrinter streamer;
U-Stream\Leeae25a442012-02-17 17:48:16 -0800176 doc->Print( &streamer );
177 printf( "%s", streamer.CStr() );
178
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800179 delete doc;
180 }
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800181 {
182 // Test: Dream
183 // XML1 : 1,187,569 bytes in 31,209 allocations
184 // XML2 : 469,073 bytes in 323 allocations
185 //int newStart = gNew;
186 XMLDocument doc;
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800187 doc.LoadFile( "dream.xml" );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800188
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800189 doc.SaveFile( "dreamout.xml" );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800190 doc.PrintError();
191
192 XMLTest( "Dream", "xml version=\"1.0\"",
193 doc.FirstChild()->ToDeclaration()->Value() );
194 XMLTest( "Dream", true, doc.FirstChild()->NextSibling()->ToUnknown() ? true : false );
195 XMLTest( "Dream", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
196 doc.FirstChild()->NextSibling()->ToUnknown()->Value() );
197 XMLTest( "Dream", "And Robin shall restore amends.",
198 doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
199 XMLTest( "Dream", "And Robin shall restore amends.",
200 doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
201
202 XMLDocument doc2;
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800203 doc2.LoadFile( "dreamout.xml" );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800204 XMLTest( "Dream-out", "xml version=\"1.0\"",
205 doc2.FirstChild()->ToDeclaration()->Value() );
206 XMLTest( "Dream-out", true, doc2.FirstChild()->NextSibling()->ToUnknown() ? true : false );
207 XMLTest( "Dream-out", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
208 doc2.FirstChild()->NextSibling()->ToUnknown()->Value() );
209 XMLTest( "Dream-out", "And Robin shall restore amends.",
210 doc2.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
211
212 //gNewTotal = gNew - newStart;
213 }
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800214 {
215 const char* error = "<?xml version=\"1.0\" standalone=\"no\" ?>\n"
216 "<passages count=\"006\" formatversion=\"20020620\">\n"
217 " <wrong error>\n"
218 "</passages>";
219
220 XMLDocument doc;
221 doc.Parse( error );
222 XMLTest( "Bad XML", doc.ErrorID(), ERROR_PARSING_ATTRIBUTE );
223 }
224
225 {
226 const char* str = "<doc attr0='1' attr1='2.0' attr2='foo' />";
227
228 XMLDocument doc;
229 doc.Parse( str );
230
231 XMLElement* ele = doc.FirstChildElement();
232
233 int iVal, result;
234 double dVal;
235
236 result = ele->QueryDoubleAttribute( "attr0", &dVal );
237 XMLTest( "Query attribute: int as double", result, XML_NO_ERROR );
238 XMLTest( "Query attribute: int as double", (int)dVal, 1 );
239 result = ele->QueryDoubleAttribute( "attr1", &dVal );
240 XMLTest( "Query attribute: double as double", (int)dVal, 2 );
241 result = ele->QueryIntAttribute( "attr1", &iVal );
242 XMLTest( "Query attribute: double as int", result, XML_NO_ERROR );
243 XMLTest( "Query attribute: double as int", iVal, 2 );
244 result = ele->QueryIntAttribute( "attr2", &iVal );
245 XMLTest( "Query attribute: not a number", result, WRONG_ATTRIBUTE_TYPE );
246 result = ele->QueryIntAttribute( "bar", &iVal );
247 XMLTest( "Query attribute: does not exist", result, NO_ATTRIBUTE );
248 }
249
250 {
251 const char* str = "<doc/>";
252
253 XMLDocument doc;
254 doc.Parse( str );
255
256 XMLElement* ele = doc.FirstChildElement();
257
258 int iVal;
259 double dVal;
260
261 ele->SetAttribute( "str", "strValue" );
262 ele->SetAttribute( "int", 1 );
263 ele->SetAttribute( "double", -1.0 );
264
265 const char* cStr = ele->Attribute( "str" );
266 ele->QueryIntAttribute( "int", &iVal );
267 ele->QueryDoubleAttribute( "double", &dVal );
268
269 XMLTest( "Attribute round trip. c-string.", "strValue", cStr );
270 XMLTest( "Attribute round trip. int.", 1, iVal );
271 XMLTest( "Attribute round trip. double.", -1, (int)dVal );
272 }
273
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800274 {
275 XMLDocument doc;
276 doc.LoadFile( "utf8test.xml" );
277
278 // Get the attribute "value" from the "Russian" element and check it.
279 XMLElement* element = doc.FirstChildElement( "document" )->FirstChildElement( "Russian" );
280 const unsigned char correctValue[] = { 0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU,
281 0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 };
282
283 XMLTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ) );
284
285 const unsigned char russianElementName[] = { 0xd0U, 0xa0U, 0xd1U, 0x83U,
286 0xd1U, 0x81U, 0xd1U, 0x81U,
287 0xd0U, 0xbaU, 0xd0U, 0xb8U,
288 0xd0U, 0xb9U, 0 };
289 const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>";
290
291 XMLText* text = doc.FirstChildElement( "document" )->FirstChildElement( (const char*) russianElementName )->FirstChild()->ToText();
292 XMLTest( "UTF-8: Browsing russian element name.",
293 russianText,
294 text->Value() );
295
296 // Now try for a round trip.
297 doc.SaveFile( "utf8testout.xml" );
298
299 // Check the round trip.
300 char savedBuf[256];
301 char verifyBuf[256];
302 int okay = 0;
303
304 FILE* saved = fopen( "utf8testout.xml", "r" );
305 FILE* verify = fopen( "utf8testverify.xml", "r" );
306
307 if ( saved && verify )
308 {
309 okay = 1;
310 while ( fgets( verifyBuf, 256, verify ) )
311 {
312 fgets( savedBuf, 256, saved );
313 NullLineEndings( verifyBuf );
314 NullLineEndings( savedBuf );
315
316 if ( strcmp( verifyBuf, savedBuf ) )
317 {
318 printf( "verify:%s<\n", verifyBuf );
319 printf( "saved :%s<\n", savedBuf );
320 okay = 0;
321 break;
322 }
323 }
324 }
325 if ( saved )
326 fclose( saved );
327 if ( verify )
328 fclose( verify );
329 XMLTest( "UTF-8: Verified multi-language round trip.", 1, okay );
330 }
331
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800332 // --------GetText()-----------
333 {
334 const char* str = "<foo>This is text</foo>";
335 XMLDocument doc;
336 doc.Parse( str );
337 const XMLElement* element = doc.RootElement();
338
339 XMLTest( "GetText() normal use.", "This is text", element->GetText() );
340
341 str = "<foo><b>This is text</b></foo>";
342 doc.Parse( str );
343 element = doc.RootElement();
344
345 XMLTest( "GetText() contained element.", element->GetText() == 0, true );
346 }
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800347
Lee Thomasond6277762012-02-22 16:00:12 -0800348
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800349 // ---------- CDATA ---------------
350 {
351 const char* str = "<xmlElement>"
352 "<![CDATA["
353 "I am > the rules!\n"
354 "...since I make symbolic puns"
355 "]]>"
356 "</xmlElement>";
357 XMLDocument doc;
358 doc.Parse( str );
359 doc.Print();
Lee Thomasond6277762012-02-22 16:00:12 -0800360
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800361 XMLTest( "CDATA parse.", doc.FirstChildElement()->FirstChild()->Value(),
362 "I am > the rules!\n...since I make symbolic puns",
Lee Thomasond6277762012-02-22 16:00:12 -0800363 false );
364 }
365
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800366 // ----------- CDATA -------------
367 {
368 const char* str = "<xmlElement>"
369 "<![CDATA["
370 "<b>I am > the rules!</b>\n"
371 "...since I make symbolic puns"
372 "]]>"
373 "</xmlElement>";
374 XMLDocument doc;
375 doc.Parse( str );
376 doc.Print();
377
378 XMLTest( "CDATA parse. [ tixml1:1480107 ]", doc.FirstChildElement()->FirstChild()->Value(),
379 "<b>I am > the rules!</b>\n...since I make symbolic puns",
380 false );
381 }
382
383 // InsertAfterChild causes crash.
384 {
385 // InsertBeforeChild and InsertAfterChild causes crash.
386 XMLDocument doc;
387 XMLElement* parent = doc.NewElement( "Parent" );
388 doc.InsertFirstChild( parent );
389
390 XMLElement* childText0 = doc.NewElement( "childText0" );
391 XMLElement* childText1 = doc.NewElement( "childText1" );
392
393 XMLNode* childNode0 = parent->InsertEndChild( childText0 );
394 XMLNode* childNode1 = parent->InsertAfterChild( childNode0, childText1 );
395
396 XMLTest( "Test InsertAfterChild on empty node. ", ( childNode1 == parent->LastChild() ), true );
397 }
Lee Thomasond6277762012-02-22 16:00:12 -0800398
399 {
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800400 // Entities not being written correctly.
401 // From Lynn Allen
Lee Thomasond6277762012-02-22 16:00:12 -0800402
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800403 const char* passages =
404 "<?xml version=\"1.0\" standalone=\"no\" ?>"
405 "<passages count=\"006\" formatversion=\"20020620\">"
406 "<psg context=\"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
407 " It also has &lt;, &gt;, and &amp;, as well as a fake copyright &#xA9;.\"> </psg>"
408 "</passages>";
Lee Thomasond6277762012-02-22 16:00:12 -0800409
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800410 XMLDocument doc;
411 doc.Parse( passages );
412 XMLElement* psg = doc.RootElement()->FirstChildElement();
413 const char* context = psg->Attribute( "context" );
414 const char* expected = "Line 5 has \"quotation marks\" and 'apostrophe marks'. It also has <, >, and &, as well as a fake copyright \xC2\xA9.";
Lee Thomasond6277762012-02-22 16:00:12 -0800415
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800416 XMLTest( "Entity transformation: read. ", expected, context, true );
Lee Thomasond6277762012-02-22 16:00:12 -0800417
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800418 FILE* textfile = fopen( "textfile.txt", "w" );
419 if ( textfile )
420 {
Lee Thomason (grinliz)2a1cd272012-02-24 17:37:53 -0800421 XMLPrinter streamer( textfile );
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800422 psg->Accept( &streamer );
423 fclose( textfile );
424 }
425 textfile = fopen( "textfile.txt", "r" );
426 TIXMLASSERT( textfile );
427 if ( textfile )
428 {
429 char buf[ 1024 ];
430 fgets( buf, 1024, textfile );
431 XMLTest( "Entity transformation: write. ",
432 "<psg context=\"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
433 " It also has &lt;, &gt;, and &amp;, as well as a fake copyright \xC2\xA9.\"/>\n",
434 buf, false );
435 }
436 fclose( textfile );
437 }
438
439 {
440 const char* test = "<?xml version='1.0'?><a.elem xmi.version='2.0'/>";
441
442 XMLDocument doc;
443 doc.Parse( test );
444 XMLTest( "dot in names", doc.Error(), 0);
445 XMLTest( "dot in names", doc.FirstChildElement()->Name(), "a.elem" );
446 XMLTest( "dot in names", doc.FirstChildElement()->Attribute( "xmi.version" ), "2.0" );
447 }
448
449 {
450 const char* test = "<element><Name>1.1 Start easy ignore fin thickness&#xA;</Name></element>";
451
452 XMLDocument doc;
453 doc.Parse( test );
454
455 XMLText* text = doc.FirstChildElement()->FirstChildElement()->FirstChild()->ToText();
456 XMLTest( "Entity with one digit.",
457 text->Value(), "1.1 Start easy ignore fin thickness\n",
458 false );
459 }
460
461 {
462 // DOCTYPE not preserved (950171)
463 //
464 const char* doctype =
465 "<?xml version=\"1.0\" ?>"
466 "<!DOCTYPE PLAY SYSTEM 'play.dtd'>"
467 "<!ELEMENT title (#PCDATA)>"
468 "<!ELEMENT books (title,authors)>"
469 "<element />";
470
471 XMLDocument doc;
472 doc.Parse( doctype );
473 doc.SaveFile( "test7.xml" );
474 doc.DeleteChild( doc.RootElement() );
475 doc.LoadFile( "test7.xml" );
476 doc.Print();
477
478 const XMLUnknown* decl = doc.FirstChild()->NextSibling()->ToUnknown();
479 XMLTest( "Correct value of unknown.", "DOCTYPE PLAY SYSTEM 'play.dtd'", decl->Value() );
480
481 }
482
483 {
484 // Comments do not stream out correctly.
485 const char* doctype =
486 "<!-- Somewhat<evil> -->";
487 XMLDocument doc;
488 doc.Parse( doctype );
489
490 XMLComment* comment = doc.FirstChild()->ToComment();
491
492 XMLTest( "Comment formatting.", " Somewhat<evil> ", comment->Value() );
493 }
494 {
495 // Double attributes
496 const char* doctype = "<element attr='red' attr='blue' />";
497
498 XMLDocument doc;
499 doc.Parse( doctype );
500
501 XMLTest( "Parsing repeated attributes.", ERROR_PARSING_ATTRIBUTE, doc.ErrorID() ); // is an error to tinyxml (didn't use to be, but caused issues)
502 }
503
504 {
505 // Embedded null in stream.
506 const char* doctype = "<element att\0r='red' attr='blue' />";
507
508 XMLDocument doc;
509 doc.Parse( doctype );
510 XMLTest( "Embedded null throws error.", true, doc.Error() );
511 }
512
513 {
514 // Empty documents should return TIXML_ERROR_PARSING_EMPTY, bug 1070717
515 const char* str = " ";
516 XMLDocument doc;
517 doc.Parse( str );
518 XMLTest( "Empty document error", ERROR_EMPTY_DOCUMENT, doc.ErrorID() );
519 }
520
521 {
522 // Low entities
523 XMLDocument doc;
524 doc.Parse( "<test>&#x0e;</test>" );
525 const char result[] = { 0x0e, 0 };
526 XMLTest( "Low entities.", doc.FirstChildElement()->GetText(), result );
527 doc.Print();
528 }
529
530 {
531 // Attribute values with trailing quotes not handled correctly
532 XMLDocument doc;
533 doc.Parse( "<foo attribute=bar\" />" );
534 XMLTest( "Throw error with bad end quotes.", doc.Error(), true );
535 }
536
537 {
538 // [ 1663758 ] Failure to report error on bad XML
539 XMLDocument xml;
540 xml.Parse("<x>");
541 XMLTest("Missing end tag at end of input", xml.Error(), true);
542 xml.Parse("<x> ");
543 XMLTest("Missing end tag with trailing whitespace", xml.Error(), true);
544 xml.Parse("<x></y>");
545 XMLTest("Mismatched tags", xml.ErrorID(), ERROR_MISMATCHED_ELEMENT);
546 }
547
548
549 {
550 // [ 1475201 ] TinyXML parses entities in comments
551 XMLDocument xml;
552 xml.Parse("<!-- declarations for <head> & <body> -->"
553 "<!-- far &amp; away -->" );
554
555 XMLNode* e0 = xml.FirstChild();
556 XMLNode* e1 = e0->NextSibling();
557 XMLComment* c0 = e0->ToComment();
558 XMLComment* c1 = e1->ToComment();
559
560 XMLTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true );
561 XMLTest( "Comments ignore entities.", " far &amp; away ", c1->Value(), true );
562 }
563
564 {
565 XMLDocument xml;
566 xml.Parse( "<Parent>"
567 "<child1 att=''/>"
568 "<!-- With this comment, child2 will not be parsed! -->"
569 "<child2 att=''/>"
570 "</Parent>" );
571 xml.Print();
572
573 int count = 0;
574
575 for( XMLNode* ele = xml.FirstChildElement( "Parent" )->FirstChild();
576 ele;
577 ele = ele->NextSibling() )
578 {
579 ++count;
580 }
581
582 XMLTest( "Comments iterate correctly.", 3, count );
583 }
584
585 {
586 // trying to repro ]1874301]. If it doesn't go into an infinite loop, all is well.
587 unsigned char buf[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?><feed><![CDATA[Test XMLblablablalblbl";
588 buf[60] = 239;
589 buf[61] = 0;
590
591 XMLDocument doc;
592 doc.Parse( (const char*)buf);
593 }
594
595
596 {
597 // bug 1827248 Error while parsing a little bit malformed file
598 // Actually not malformed - should work.
599 XMLDocument xml;
600 xml.Parse( "<attributelist> </attributelist >" );
601 XMLTest( "Handle end tag whitespace", false, xml.Error() );
602 }
603
604 {
605 // This one must not result in an infinite loop
606 XMLDocument xml;
607 xml.Parse( "<infinite>loop" );
608 XMLTest( "Infinite loop test.", true, true );
609 }
610#endif
Lee Thomason (grinliz)2a1cd272012-02-24 17:37:53 -0800611
612 #if defined( _MSC_VER )
Lee Thomason1ff38e02012-02-14 18:18:16 -0800613 _CrtMemCheckpoint( &endMemState );
614 //_CrtMemDumpStatistics( &endMemState );
615
616 _CrtMemState diffMemState;
617 _CrtMemDifference( &diffMemState, &startMemState, &endMemState );
618 _CrtMemDumpStatistics( &diffMemState );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800619 //printf( "new total=%d\n", gNewTotal );
Lee Thomason1ff38e02012-02-14 18:18:16 -0800620 #endif
621
622 printf ("\nPass %d, Fail %d\n", gPass, gFail);
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800623 return 0;
624}