xref: /aosp_15_r20/external/libxml2/testparser.c (revision 7c5688314b92172186c154356a6374bf7684c3ca)
1 /*
2  * testparser.c: Additional parser tests
3  *
4  * See Copyright for the status of this software.
5  */
6 
7 #define XML_DEPRECATED
8 
9 #include "libxml.h"
10 #include <libxml/parser.h>
11 #include <libxml/parserInternals.h>
12 #include <libxml/uri.h>
13 #include <libxml/xmlreader.h>
14 #include <libxml/xmlsave.h>
15 #include <libxml/xmlwriter.h>
16 #include <libxml/HTMLparser.h>
17 
18 #include <string.h>
19 
20 static int
testNewDocNode(void)21 testNewDocNode(void) {
22     xmlNodePtr node;
23     int err = 0;
24 
25     node = xmlNewDocNode(NULL, NULL, BAD_CAST "c", BAD_CAST "");
26     if (node->children != NULL) {
27         fprintf(stderr, "empty node has children\n");
28         err = 1;
29     }
30     xmlFreeNode(node);
31 
32     return err;
33 }
34 
35 static int
testStandaloneWithEncoding(void)36 testStandaloneWithEncoding(void) {
37     xmlDocPtr doc;
38     const char *str =
39         "<?xml version=\"1.0\" standalone=\"yes\"?>\n"
40         "<doc></doc>\n";
41     int err = 0;
42 
43     xmlResetLastError();
44 
45     doc = xmlReadDoc(BAD_CAST str, NULL, "UTF-8", 0);
46     if (doc == NULL) {
47         fprintf(stderr, "xmlReadDoc failed\n");
48         err = 1;
49     }
50     xmlFreeDoc(doc);
51 
52     return err;
53 }
54 
55 static int
testUnsupportedEncoding(void)56 testUnsupportedEncoding(void) {
57     xmlDocPtr doc;
58     const xmlError *error;
59     int err = 0;
60 
61     xmlResetLastError();
62 
63     doc = xmlReadDoc(BAD_CAST "<doc/>", NULL, "#unsupported",
64                      XML_PARSE_NOWARNING);
65     if (doc == NULL) {
66         fprintf(stderr, "xmlReadDoc failed with unsupported encoding\n");
67         err = 1;
68     }
69     xmlFreeDoc(doc);
70 
71     error = xmlGetLastError();
72     if (error == NULL ||
73         error->code != XML_ERR_UNSUPPORTED_ENCODING ||
74         error->level != XML_ERR_WARNING ||
75         strcmp(error->message, "Unsupported encoding: #unsupported\n") != 0)
76     {
77         fprintf(stderr, "xmlReadDoc failed to raise correct error\n");
78         err = 1;
79     }
80 
81     return err;
82 }
83 
84 static int
testNodeGetContent(void)85 testNodeGetContent(void) {
86     xmlDocPtr doc;
87     xmlChar *content;
88     int err = 0;
89 
90     doc = xmlReadDoc(BAD_CAST "<doc/>", NULL, NULL, 0);
91     xmlAddChild(doc->children, xmlNewReference(doc, BAD_CAST "lt"));
92     content = xmlNodeGetContent((xmlNodePtr) doc);
93     if (strcmp((char *) content, "<") != 0) {
94         fprintf(stderr, "xmlNodeGetContent failed\n");
95         err = 1;
96     }
97     xmlFree(content);
98     xmlFreeDoc(doc);
99 
100     return err;
101 }
102 
103 static int
testCFileIO(void)104 testCFileIO(void) {
105     xmlDocPtr doc;
106     int err = 0;
107 
108     /* Deprecated FILE-based API */
109     xmlRegisterInputCallbacks(xmlFileMatch, xmlFileOpen, xmlFileRead,
110                               xmlFileClose);
111     doc = xmlReadFile("test/ent1", NULL, 0);
112 
113     if (doc == NULL) {
114         err = 1;
115     } else {
116         xmlNodePtr root = xmlDocGetRootElement(doc);
117 
118         if (root == NULL || !xmlStrEqual(root->name, BAD_CAST "EXAMPLE"))
119             err = 1;
120     }
121 
122     xmlFreeDoc(doc);
123     xmlPopInputCallbacks();
124 
125     if (err)
126         fprintf(stderr, "xmlReadFile failed with FILE input callbacks\n");
127 
128     return err;
129 }
130 
131 #ifdef LIBXML_OUTPUT_ENABLED
132 static xmlChar *
dumpNodeList(xmlNodePtr list)133 dumpNodeList(xmlNodePtr list) {
134     xmlBufferPtr buffer;
135     xmlSaveCtxtPtr save;
136     xmlNodePtr cur;
137     xmlChar *ret;
138 
139     buffer = xmlBufferCreate();
140     save = xmlSaveToBuffer(buffer, "UTF-8", 0);
141     for (cur = list; cur != NULL; cur = cur->next)
142         xmlSaveTree(save, cur);
143     xmlSaveClose(save);
144 
145     ret = xmlBufferDetach(buffer);
146     xmlBufferFree(buffer);
147     return ret;
148 }
149 
150 static int
testCtxtParseContent(void)151 testCtxtParseContent(void) {
152     xmlParserCtxtPtr ctxt;
153     xmlParserInputPtr input;
154     xmlDocPtr doc;
155     xmlNodePtr node, list;
156     const char *content;
157     xmlChar *output;
158     int i, j;
159     int err = 0;
160 
161     static const char *const tests[] = {
162         "<!-- c -->\xF0\x9F\x98\x84<a/><b/>end",
163         "text<a:foo><b:foo/></a:foo>text<!-- c -->"
164     };
165 
166     doc = xmlReadDoc(BAD_CAST "<doc xmlns:a='a'><elem xmlns:b='b'/></doc>",
167                      NULL, NULL, 0);
168     node = doc->children->children;
169 
170     ctxt = xmlNewParserCtxt();
171 
172     for (i = 0; (size_t) i < sizeof(tests) / sizeof(tests[0]); i++) {
173         content = tests[i];
174 
175         for (j = 0; j < 2; j++) {
176             if (j == 0) {
177                 input = xmlNewInputFromString(NULL, content,
178                                               XML_INPUT_BUF_STATIC);
179                 list = xmlCtxtParseContent(ctxt, input, node, 0);
180             } else {
181                 xmlParseInNodeContext(node, content, strlen(content), 0,
182                                       &list);
183             }
184 
185             output = dumpNodeList(list);
186 
187             if ((j == 0 && ctxt->nsWellFormed == 0) ||
188                 strcmp((char *) output, content) != 0) {
189                 fprintf(stderr, "%s failed test %d, got:\n%s\n",
190                         j == 0 ?
191                             "xmlCtxtParseContent" :
192                             "xmlParseInNodeContext",
193                         i, output);
194                 err = 1;
195             }
196 
197             xmlFree(output);
198             xmlFreeNodeList(list);
199         }
200     }
201 
202     xmlFreeParserCtxt(ctxt);
203     xmlFreeDoc(doc);
204 
205     return err;
206 }
207 #endif /* LIBXML_OUTPUT_ENABLED */
208 
209 #ifdef LIBXML_SAX1_ENABLED
210 static int
testBalancedChunk(void)211 testBalancedChunk(void) {
212     xmlNodePtr list;
213     xmlNodePtr elem;
214     int ret;
215     int err = 0;
216 
217     ret = xmlParseBalancedChunkMemory(NULL, NULL, NULL, 0,
218             BAD_CAST "start <node xml:lang='en'>abc</node> end", &list);
219 
220     if ((ret != XML_ERR_OK) ||
221         (list == NULL) ||
222         ((elem = list->next) == NULL) ||
223         (elem->type != XML_ELEMENT_NODE) ||
224         (elem->nsDef == NULL) ||
225         (!xmlStrEqual(elem->nsDef->href, XML_XML_NAMESPACE))) {
226         fprintf(stderr, "xmlParseBalancedChunkMemory failed\n");
227         err = 1;
228     }
229 
230     xmlFreeNodeList(list);
231 
232     return(err);
233 }
234 #endif
235 
236 #ifdef LIBXML_PUSH_ENABLED
237 static int
testHugePush(void)238 testHugePush(void) {
239     xmlParserCtxtPtr ctxt;
240     int err, i;
241 
242     ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
243 
244     /*
245      * Push parse a document larger than XML_MAX_LOOKUP_LIMIT
246      * (10,000,000 bytes). This mainly tests whether shrinking the
247      * buffer works when push parsing.
248      */
249     xmlParseChunk(ctxt, "<doc>", 5, 0);
250     for (i = 0; i < 1000000; i++)
251         xmlParseChunk(ctxt, "<elem>text</elem>", 17, 0);
252     xmlParseChunk(ctxt, "</doc>", 6, 1);
253 
254     err = ctxt->wellFormed ? 0 : 1;
255     xmlFreeDoc(ctxt->myDoc);
256     xmlFreeParserCtxt(ctxt);
257 
258     return err;
259 }
260 
261 static int
testHugeEncodedChunk(void)262 testHugeEncodedChunk(void) {
263     xmlBufferPtr buf;
264     xmlChar *chunk;
265     xmlParserCtxtPtr ctxt;
266     int err, i;
267 
268     /*
269      * Test the push parser with a built-in encoding handler like ISO-8859-1
270      * and a chunk larger than the initial decoded buffer (currently 4 KB).
271      */
272     buf = xmlBufferCreate();
273     xmlBufferCat(buf,
274             BAD_CAST "<?xml version='1.0' encoding='ISO-8859-1'?>\n");
275     xmlBufferCat(buf, BAD_CAST "<doc><!-- ");
276     for (i = 0; i < 2000; i++)
277         xmlBufferCat(buf, BAD_CAST "0123456789");
278     xmlBufferCat(buf, BAD_CAST " --></doc>");
279     chunk = xmlBufferDetach(buf);
280     xmlBufferFree(buf);
281 
282     ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
283 
284     xmlParseChunk(ctxt, (char *) chunk, xmlStrlen(chunk), 0);
285     xmlParseChunk(ctxt, NULL, 0, 1);
286 
287     err = ctxt->wellFormed ? 0 : 1;
288     xmlFreeDoc(ctxt->myDoc);
289     xmlFreeParserCtxt(ctxt);
290     xmlFree(chunk);
291 
292     return err;
293 }
294 #endif
295 
296 #ifdef LIBXML_HTML_ENABLED
297 static int
testHtmlIds(void)298 testHtmlIds(void) {
299     const char *htmlContent =
300         "<html><body><div id='myId'>Hello, World!</div></body></html>";
301     htmlDocPtr doc;
302     xmlAttrPtr node;
303 
304     doc = htmlReadDoc(BAD_CAST htmlContent, NULL, NULL, 0);
305     if (doc == NULL) {
306         fprintf(stderr, "could not parse HTML content\n");
307         return 1;
308     }
309 
310     node = xmlGetID(doc, BAD_CAST "myId");
311     if (node == NULL) {
312         fprintf(stderr, "xmlGetID doesn't work on HTML\n");
313         return 1;
314     }
315 
316     xmlFreeDoc(doc);
317     return 0;
318 }
319 
320 #ifdef LIBXML_PUSH_ENABLED
321 static int
testHtmlPushWithEncoding(void)322 testHtmlPushWithEncoding(void) {
323     htmlParserCtxtPtr ctxt;
324     htmlDocPtr doc;
325     htmlNodePtr node;
326     int err = 0;
327 
328     ctxt = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL,
329                                     XML_CHAR_ENCODING_UTF8);
330     htmlParseChunk(ctxt, "-\xC3\xA4-", 4, 1);
331 
332     doc = ctxt->myDoc;
333     if (!xmlStrEqual(doc->encoding, BAD_CAST "UTF-8")) {
334         fprintf(stderr, "testHtmlPushWithEncoding failed\n");
335         err = 1;
336     }
337 
338     node = xmlDocGetRootElement(doc)->children->children->children;
339     if (!xmlStrEqual(node->content, BAD_CAST "-\xC3\xA4-")) {
340         fprintf(stderr, "testHtmlPushWithEncoding failed\n");
341         err = 1;
342     }
343 
344     xmlFreeDoc(doc);
345     htmlFreeParserCtxt(ctxt);
346     return err;
347 }
348 #endif
349 #endif
350 
351 #ifdef LIBXML_READER_ENABLED
352 static int
testReaderEncoding(void)353 testReaderEncoding(void) {
354     xmlBuffer *buf;
355     xmlTextReader *reader;
356     xmlChar *xml;
357     const xmlChar *encoding;
358     int err = 0;
359     int i;
360 
361     buf = xmlBufferCreate();
362     xmlBufferCCat(buf, "<?xml version='1.0' encoding='ISO-8859-1'?>\n");
363     xmlBufferCCat(buf, "<doc>");
364     for (i = 0; i < 8192; i++)
365         xmlBufferCCat(buf, "x");
366     xmlBufferCCat(buf, "</doc>");
367     xml = xmlBufferDetach(buf);
368     xmlBufferFree(buf);
369 
370     reader = xmlReaderForDoc(BAD_CAST xml, NULL, NULL, 0);
371     xmlTextReaderRead(reader);
372     encoding = xmlTextReaderConstEncoding(reader);
373 
374     if (!xmlStrEqual(encoding, BAD_CAST "ISO-8859-1")) {
375         fprintf(stderr, "testReaderEncoding failed\n");
376         err = 1;
377     }
378 
379     xmlFreeTextReader(reader);
380     xmlFree(xml);
381     return err;
382 }
383 
384 static int
testReaderContent(void)385 testReaderContent(void) {
386     xmlTextReader *reader;
387     const xmlChar *xml = BAD_CAST "<d>x<e>y</e><f>z</f></d>";
388     xmlChar *string;
389     int err = 0;
390 
391     reader = xmlReaderForDoc(xml, NULL, NULL, 0);
392     xmlTextReaderRead(reader);
393 
394     string = xmlTextReaderReadOuterXml(reader);
395     if (!xmlStrEqual(string, xml)) {
396         fprintf(stderr, "xmlTextReaderReadOuterXml failed\n");
397         err = 1;
398     }
399     xmlFree(string);
400 
401     string = xmlTextReaderReadInnerXml(reader);
402     if (!xmlStrEqual(string, BAD_CAST "x<e>y</e><f>z</f>")) {
403         fprintf(stderr, "xmlTextReaderReadInnerXml failed\n");
404         err = 1;
405     }
406     xmlFree(string);
407 
408     string = xmlTextReaderReadString(reader);
409     if (!xmlStrEqual(string, BAD_CAST "xyz")) {
410         fprintf(stderr, "xmlTextReaderReadString failed\n");
411         err = 1;
412     }
413     xmlFree(string);
414 
415     xmlFreeTextReader(reader);
416     return err;
417 }
418 
419 #ifdef LIBXML_XINCLUDE_ENABLED
420 typedef struct {
421     char *message;
422     int code;
423 } testReaderErrorCtxt;
424 
425 static void
testReaderError(void * arg,const char * msg,xmlParserSeverities severity ATTRIBUTE_UNUSED,xmlTextReaderLocatorPtr locator ATTRIBUTE_UNUSED)426 testReaderError(void *arg, const char *msg,
427                 xmlParserSeverities severity ATTRIBUTE_UNUSED,
428                 xmlTextReaderLocatorPtr locator ATTRIBUTE_UNUSED) {
429     testReaderErrorCtxt *ctxt = arg;
430 
431     if (ctxt->message != NULL)
432         xmlFree(ctxt->message);
433     ctxt->message = xmlMemStrdup(msg);
434 }
435 
436 static void
testStructuredReaderError(void * arg,const xmlError * error)437 testStructuredReaderError(void *arg, const xmlError *error) {
438     testReaderErrorCtxt *ctxt = arg;
439 
440     if (ctxt->message != NULL)
441         xmlFree(ctxt->message);
442     ctxt->message = xmlMemStrdup(error->message);
443     ctxt->code = error->code;
444 }
445 
446 static int
testReaderXIncludeError(void)447 testReaderXIncludeError(void) {
448     /*
449      * Test whether XInclude errors are reported to the custom error
450      * handler of a reader.
451      */
452     const char *doc =
453         "<doc xmlns:xi='http://www.w3.org/2001/XInclude'>\n"
454         "  <xi:include/>\n"
455         "</doc>\n";
456     xmlTextReader *reader;
457     testReaderErrorCtxt errorCtxt;
458     int err = 0;
459 
460     reader = xmlReaderForDoc(BAD_CAST doc, NULL, NULL, XML_PARSE_XINCLUDE);
461     xmlTextReaderSetErrorHandler(reader, testReaderError, &errorCtxt);
462     errorCtxt.message = NULL;
463     errorCtxt.code = 0;
464     while (xmlTextReaderRead(reader) > 0)
465         ;
466 
467     if (errorCtxt.message == NULL ||
468         strstr(errorCtxt.message, "href or xpointer") == NULL) {
469         fprintf(stderr, "xmlTextReaderSetErrorHandler failed\n");
470         err = 1;
471     }
472 
473     xmlFree(errorCtxt.message);
474     xmlFreeTextReader(reader);
475 
476     reader = xmlReaderForDoc(BAD_CAST doc, NULL, NULL, XML_PARSE_XINCLUDE);
477     xmlTextReaderSetStructuredErrorHandler(reader, testStructuredReaderError,
478                                            &errorCtxt);
479     errorCtxt.message = NULL;
480     errorCtxt.code = 0;
481     while (xmlTextReaderRead(reader) > 0)
482         ;
483 
484     if (errorCtxt.code != XML_XINCLUDE_NO_HREF ||
485         errorCtxt.message == NULL ||
486         strstr(errorCtxt.message, "href or xpointer") == NULL) {
487         fprintf(stderr, "xmlTextReaderSetStructuredErrorHandler failed\n");
488         err = 1;
489     }
490 
491     xmlFree(errorCtxt.message);
492     xmlFreeTextReader(reader);
493 
494     return err;
495 }
496 #endif
497 #endif
498 
499 #ifdef LIBXML_WRITER_ENABLED
500 static int
testWriterIOWrite(void * ctxt,const char * data,int len)501 testWriterIOWrite(void *ctxt, const char *data, int len) {
502     (void) ctxt;
503     (void) data;
504 
505     return len;
506 }
507 
508 static int
testWriterIOClose(void * ctxt)509 testWriterIOClose(void *ctxt) {
510     (void) ctxt;
511 
512     return XML_IO_ENAMETOOLONG;
513 }
514 
515 static int
testWriterClose(void)516 testWriterClose(void){
517     xmlOutputBufferPtr out;
518     xmlTextWriterPtr writer;
519     int err = 0;
520     int result;
521 
522     out = xmlOutputBufferCreateIO(testWriterIOWrite, testWriterIOClose,
523                                   NULL, NULL);
524     writer = xmlNewTextWriter(out);
525     xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL);
526     xmlTextWriterStartElement(writer, BAD_CAST "elem");
527     xmlTextWriterEndElement(writer);
528     xmlTextWriterEndDocument(writer);
529     result = xmlTextWriterClose(writer);
530 
531     if (result != XML_IO_ENAMETOOLONG) {
532         fprintf(stderr, "xmlTextWriterClose reported wrong error %d\n",
533                 result);
534         err = 1;
535     }
536 
537     xmlFreeTextWriter(writer);
538     return err;
539 }
540 #endif
541 
542 typedef struct {
543     const char *uri;
544     const char *base;
545     const char *result;
546 } xmlRelativeUriTest;
547 
548 static int
testBuildRelativeUri(void)549 testBuildRelativeUri(void) {
550     xmlChar *res;
551     int err = 0;
552     int i;
553 
554     static const xmlRelativeUriTest tests[] = {
555         {
556             "/a/b1/c1",
557             "/a/b2/c2",
558             "../b1/c1"
559         }, {
560             "a/b1/c1",
561             "a/b2/c2",
562             "../b1/c1"
563         }, {
564             "a/././b1/x/y/../z/../.././c1",
565             "./a/./b2/././b2",
566             "../b1/c1"
567         }, {
568             "file:///a/b1/c1",
569             "/a/b2/c2",
570             NULL
571         }, {
572             "/a/b1/c1",
573             "file:///a/b2/c2",
574             NULL
575         }, {
576             "a/b1/c1",
577             "/a/b2/c2",
578             NULL
579         }, {
580             "/a/b1/c1",
581             "a/b2/c2",
582             NULL
583         }, {
584             "http://example.org/a/b1/c1",
585             "http://example.org/a/b2/c2",
586             "../b1/c1"
587         }, {
588             "http://example.org/a/b1/c1",
589             "https://example.org/a/b2/c2",
590             NULL
591         }, {
592             "http://example.org/a/b1/c1",
593             "http://localhost/a/b2/c2",
594             NULL
595         }, {
596             "with space/x x/y y",
597             "with space/b2/c2",
598             "../x%20x/y%20y"
599         }, {
600             "with space/x x/y y",
601             "/b2/c2",
602             "with%20space/x%20x/y%20y"
603         }
604 #if defined(_WIN32) || defined(__CYGWIN__)
605         , {
606             "\\a\\b1\\c1",
607             "\\a\\b2\\c2",
608             "../b1/c1"
609         }, {
610             "\\a\\b1\\c1",
611             "/a/b2/c2",
612             "../b1/c1"
613         }, {
614             "a\\b1\\c1",
615             "a/b2/c2",
616             "../b1/c1"
617         }, {
618             "file://server/a/b1/c1",
619             "\\\\?\\UNC\\server\\a\\b2\\c2",
620             "../b1/c1"
621         }, {
622             "file://server/a/b1/c1",
623             "\\\\server\\a\\b2\\c2",
624             "../b1/c1"
625         }, {
626             "file:///x:/a/b1/c1",
627             "x:\\a\\b2\\c2",
628             "../b1/c1"
629         }, {
630             "file:///x:/a/b1/c1",
631             "\\\\?\\x:\\a\\b2\\c2",
632             "../b1/c1"
633         }, {
634             "file:///x:/a/b1/c1",
635             "file:///y:/a/b2/c2",
636             NULL
637         }, {
638             "x:/a/b1/c1",
639             "y:/a/b2/c2",
640             "file:///x:/a/b1/c1"
641         }, {
642             "/a/b1/c1",
643             "y:/a/b2/c2",
644             NULL
645         }, {
646             "\\\\server\\a\\b1\\c1",
647             "a/b2/c2",
648             "file://server/a/b1/c1"
649         }
650 #endif
651     };
652 
653     for (i = 0; (size_t) i < sizeof(tests) / sizeof(tests[0]); i++) {
654         const xmlRelativeUriTest *test = tests + i;
655         const char *expect;
656 
657         res = xmlBuildRelativeURI(BAD_CAST test->uri, BAD_CAST test->base);
658         expect = test->result ? test->result : test->uri;
659         if (!xmlStrEqual(res, BAD_CAST expect)) {
660             fprintf(stderr, "xmlBuildRelativeURI failed uri=%s base=%s "
661                     "result=%s expected=%s\n", test->uri, test->base,
662                     res, expect);
663             err = 1;
664         }
665         xmlFree(res);
666     }
667 
668     return err;
669 }
670 
671 static int charEncConvImplError;
672 
673 static int
rot13Convert(unsigned char * out,int * outlen,const unsigned char * in,int * inlen,void * vctxt)674 rot13Convert(unsigned char *out, int *outlen,
675              const unsigned char *in, int *inlen, void *vctxt) {
676     int *ctxt = vctxt;
677     int inSize = *inlen;
678     int outSize = *outlen;
679     int rot, i;
680 
681     rot = *ctxt;
682 
683     for (i = 0; i < inSize && i < outSize; i++) {
684         int c = in[i];
685 
686         if (c >= 'A' && c <= 'Z')
687             c = 'A' + (c - 'A' + rot) % 26;
688         else if (c >= 'a' && c <= 'z')
689             c = 'a' + (c - 'a' + rot) % 26;
690 
691         out[i] = c;
692     }
693 
694     *inlen = i;
695     *outlen = i;
696 
697     return XML_ENC_ERR_SUCCESS;
698 }
699 
700 static void
rot13ConvCtxtDtor(void * vctxt)701 rot13ConvCtxtDtor(void *vctxt) {
702     xmlFree(vctxt);
703 }
704 
705 static int
rot13ConvImpl(void * vctxt ATTRIBUTE_UNUSED,const char * name,xmlCharEncConverter * conv)706 rot13ConvImpl(void *vctxt ATTRIBUTE_UNUSED, const char *name,
707               xmlCharEncConverter *conv) {
708     int *inputCtxt;
709 
710     if (strcmp(name, "rot13") != 0) {
711         fprintf(stderr, "rot13ConvImpl received wrong name\n");
712         charEncConvImplError = 1;
713 
714         return XML_ERR_UNSUPPORTED_ENCODING;
715     }
716 
717     conv->input = rot13Convert;
718     conv->output = rot13Convert;
719     conv->ctxtDtor = rot13ConvCtxtDtor;
720 
721     inputCtxt = xmlMalloc(sizeof(*inputCtxt));
722     *inputCtxt = 13;
723     conv->inputCtxt = inputCtxt;
724 
725     return XML_ERR_OK;
726 }
727 
728 static int
testCharEncConvImpl(void)729 testCharEncConvImpl(void) {
730     xmlParserCtxtPtr ctxt;
731     xmlDocPtr doc;
732     xmlNodePtr root;
733     int err = 0;
734 
735     ctxt = xmlNewParserCtxt();
736     xmlCtxtSetCharEncConvImpl(ctxt, rot13ConvImpl, NULL);
737     charEncConvImplError = 0;
738     doc = xmlCtxtReadDoc(ctxt, BAD_CAST "<?kzy irefvba='1.0'?><qbp/>", NULL,
739                          "rot13", 0);
740     if (charEncConvImplError)
741         err = 1;
742     xmlFreeParserCtxt(ctxt);
743 
744     root = xmlDocGetRootElement(doc);
745     if (root == NULL || strcmp((char *) root->name, "doc") != 0) {
746         fprintf(stderr, "testCharEncConvImpl failed\n");
747         err = 1;
748     }
749 
750     xmlFreeDoc(doc);
751 
752     return err;
753 }
754 
755 int
main(void)756 main(void) {
757     int err = 0;
758 
759     err |= testNewDocNode();
760     err |= testStandaloneWithEncoding();
761     err |= testUnsupportedEncoding();
762     err |= testNodeGetContent();
763     err |= testCFileIO();
764 #ifdef LIBXML_OUTPUT_ENABLED
765     err |= testCtxtParseContent();
766 #endif
767 #ifdef LIBXML_SAX1_ENABLED
768     err |= testBalancedChunk();
769 #endif
770 #ifdef LIBXML_PUSH_ENABLED
771     err |= testHugePush();
772     err |= testHugeEncodedChunk();
773 #endif
774 #ifdef LIBXML_HTML_ENABLED
775     err |= testHtmlIds();
776 #ifdef LIBXML_PUSH_ENABLED
777     err |= testHtmlPushWithEncoding();
778 #endif
779 #endif
780 #ifdef LIBXML_READER_ENABLED
781     err |= testReaderEncoding();
782     err |= testReaderContent();
783 #ifdef LIBXML_XINCLUDE_ENABLED
784     err |= testReaderXIncludeError();
785 #endif
786 #endif
787 #ifdef LIBXML_WRITER_ENABLED
788     err |= testWriterClose();
789 #endif
790     err |= testBuildRelativeUri();
791     err |= testCharEncConvImpl();
792 
793     return err;
794 }
795 
796