1*6777b538SAndroid Build Coastguard Worker /*
2*6777b538SAndroid Build Coastguard Worker * testparser.c: Additional parser tests
3*6777b538SAndroid Build Coastguard Worker *
4*6777b538SAndroid Build Coastguard Worker * See Copyright for the status of this software.
5*6777b538SAndroid Build Coastguard Worker */
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <libxml/parser.h>
8*6777b538SAndroid Build Coastguard Worker #include <libxml/xmlreader.h>
9*6777b538SAndroid Build Coastguard Worker #include <libxml/xmlwriter.h>
10*6777b538SAndroid Build Coastguard Worker
11*6777b538SAndroid Build Coastguard Worker #include <string.h>
12*6777b538SAndroid Build Coastguard Worker
13*6777b538SAndroid Build Coastguard Worker static int
testStandaloneWithEncoding(void)14*6777b538SAndroid Build Coastguard Worker testStandaloneWithEncoding(void) {
15*6777b538SAndroid Build Coastguard Worker xmlDocPtr doc;
16*6777b538SAndroid Build Coastguard Worker const char *str =
17*6777b538SAndroid Build Coastguard Worker "<?xml version=\"1.0\" standalone=\"yes\"?>\n"
18*6777b538SAndroid Build Coastguard Worker "<doc></doc>\n";
19*6777b538SAndroid Build Coastguard Worker int err = 0;
20*6777b538SAndroid Build Coastguard Worker
21*6777b538SAndroid Build Coastguard Worker xmlResetLastError();
22*6777b538SAndroid Build Coastguard Worker
23*6777b538SAndroid Build Coastguard Worker doc = xmlReadDoc(BAD_CAST str, NULL, "UTF-8", 0);
24*6777b538SAndroid Build Coastguard Worker if (doc == NULL) {
25*6777b538SAndroid Build Coastguard Worker fprintf(stderr, "xmlReadDoc failed\n");
26*6777b538SAndroid Build Coastguard Worker err = 1;
27*6777b538SAndroid Build Coastguard Worker }
28*6777b538SAndroid Build Coastguard Worker xmlFreeDoc(doc);
29*6777b538SAndroid Build Coastguard Worker
30*6777b538SAndroid Build Coastguard Worker return err;
31*6777b538SAndroid Build Coastguard Worker }
32*6777b538SAndroid Build Coastguard Worker
33*6777b538SAndroid Build Coastguard Worker static int
testUnsupportedEncoding(void)34*6777b538SAndroid Build Coastguard Worker testUnsupportedEncoding(void) {
35*6777b538SAndroid Build Coastguard Worker xmlDocPtr doc;
36*6777b538SAndroid Build Coastguard Worker const xmlError *error;
37*6777b538SAndroid Build Coastguard Worker int err = 0;
38*6777b538SAndroid Build Coastguard Worker
39*6777b538SAndroid Build Coastguard Worker xmlResetLastError();
40*6777b538SAndroid Build Coastguard Worker
41*6777b538SAndroid Build Coastguard Worker doc = xmlReadDoc(BAD_CAST "<doc/>", NULL, "#unsupported",
42*6777b538SAndroid Build Coastguard Worker XML_PARSE_NOWARNING);
43*6777b538SAndroid Build Coastguard Worker if (doc == NULL) {
44*6777b538SAndroid Build Coastguard Worker fprintf(stderr, "xmlReadDoc failed with unsupported encoding\n");
45*6777b538SAndroid Build Coastguard Worker err = 1;
46*6777b538SAndroid Build Coastguard Worker }
47*6777b538SAndroid Build Coastguard Worker xmlFreeDoc(doc);
48*6777b538SAndroid Build Coastguard Worker
49*6777b538SAndroid Build Coastguard Worker error = xmlGetLastError();
50*6777b538SAndroid Build Coastguard Worker if (error->code != XML_ERR_UNSUPPORTED_ENCODING ||
51*6777b538SAndroid Build Coastguard Worker error->level != XML_ERR_WARNING ||
52*6777b538SAndroid Build Coastguard Worker strcmp(error->message, "Unsupported encoding: #unsupported\n") != 0)
53*6777b538SAndroid Build Coastguard Worker {
54*6777b538SAndroid Build Coastguard Worker fprintf(stderr, "xmlReadDoc failed to raise correct error\n");
55*6777b538SAndroid Build Coastguard Worker err = 1;
56*6777b538SAndroid Build Coastguard Worker }
57*6777b538SAndroid Build Coastguard Worker
58*6777b538SAndroid Build Coastguard Worker return err;
59*6777b538SAndroid Build Coastguard Worker }
60*6777b538SAndroid Build Coastguard Worker
61*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
62*6777b538SAndroid Build Coastguard Worker static int
testBalancedChunk(void)63*6777b538SAndroid Build Coastguard Worker testBalancedChunk(void) {
64*6777b538SAndroid Build Coastguard Worker xmlNodePtr list;
65*6777b538SAndroid Build Coastguard Worker xmlNodePtr elem;
66*6777b538SAndroid Build Coastguard Worker int ret;
67*6777b538SAndroid Build Coastguard Worker int err = 0;
68*6777b538SAndroid Build Coastguard Worker
69*6777b538SAndroid Build Coastguard Worker ret = xmlParseBalancedChunkMemory(NULL, NULL, NULL, 0,
70*6777b538SAndroid Build Coastguard Worker BAD_CAST "start <node xml:lang='en'>abc</node> end", &list);
71*6777b538SAndroid Build Coastguard Worker
72*6777b538SAndroid Build Coastguard Worker if ((ret != XML_ERR_OK) ||
73*6777b538SAndroid Build Coastguard Worker (list == NULL) ||
74*6777b538SAndroid Build Coastguard Worker ((elem = list->next) == NULL) ||
75*6777b538SAndroid Build Coastguard Worker (elem->type != XML_ELEMENT_NODE) ||
76*6777b538SAndroid Build Coastguard Worker (elem->nsDef == NULL) ||
77*6777b538SAndroid Build Coastguard Worker (!xmlStrEqual(elem->nsDef->href, XML_XML_NAMESPACE))) {
78*6777b538SAndroid Build Coastguard Worker fprintf(stderr, "xmlParseBalancedChunkMemory failed\n");
79*6777b538SAndroid Build Coastguard Worker err = 1;
80*6777b538SAndroid Build Coastguard Worker }
81*6777b538SAndroid Build Coastguard Worker
82*6777b538SAndroid Build Coastguard Worker xmlFreeNodeList(list);
83*6777b538SAndroid Build Coastguard Worker
84*6777b538SAndroid Build Coastguard Worker return(err);
85*6777b538SAndroid Build Coastguard Worker }
86*6777b538SAndroid Build Coastguard Worker #endif
87*6777b538SAndroid Build Coastguard Worker
88*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_PUSH_ENABLED
89*6777b538SAndroid Build Coastguard Worker static int
testHugePush(void)90*6777b538SAndroid Build Coastguard Worker testHugePush(void) {
91*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
92*6777b538SAndroid Build Coastguard Worker int err, i;
93*6777b538SAndroid Build Coastguard Worker
94*6777b538SAndroid Build Coastguard Worker ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
95*6777b538SAndroid Build Coastguard Worker
96*6777b538SAndroid Build Coastguard Worker /*
97*6777b538SAndroid Build Coastguard Worker * Push parse a document larger than XML_MAX_LOOKUP_LIMIT
98*6777b538SAndroid Build Coastguard Worker * (10,000,000 bytes). This mainly tests whether shrinking the
99*6777b538SAndroid Build Coastguard Worker * buffer works when push parsing.
100*6777b538SAndroid Build Coastguard Worker */
101*6777b538SAndroid Build Coastguard Worker xmlParseChunk(ctxt, "<doc>", 5, 0);
102*6777b538SAndroid Build Coastguard Worker for (i = 0; i < 1000000; i++)
103*6777b538SAndroid Build Coastguard Worker xmlParseChunk(ctxt, "<elem>text</elem>", 17, 0);
104*6777b538SAndroid Build Coastguard Worker xmlParseChunk(ctxt, "</doc>", 6, 1);
105*6777b538SAndroid Build Coastguard Worker
106*6777b538SAndroid Build Coastguard Worker err = ctxt->wellFormed ? 0 : 1;
107*6777b538SAndroid Build Coastguard Worker xmlFreeDoc(ctxt->myDoc);
108*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
109*6777b538SAndroid Build Coastguard Worker
110*6777b538SAndroid Build Coastguard Worker return err;
111*6777b538SAndroid Build Coastguard Worker }
112*6777b538SAndroid Build Coastguard Worker
113*6777b538SAndroid Build Coastguard Worker static int
testHugeEncodedChunk(void)114*6777b538SAndroid Build Coastguard Worker testHugeEncodedChunk(void) {
115*6777b538SAndroid Build Coastguard Worker xmlBufferPtr buf;
116*6777b538SAndroid Build Coastguard Worker xmlChar *chunk;
117*6777b538SAndroid Build Coastguard Worker xmlParserCtxtPtr ctxt;
118*6777b538SAndroid Build Coastguard Worker int err, i;
119*6777b538SAndroid Build Coastguard Worker
120*6777b538SAndroid Build Coastguard Worker /*
121*6777b538SAndroid Build Coastguard Worker * Test the push parser with a built-in encoding handler like ISO-8859-1
122*6777b538SAndroid Build Coastguard Worker * and a chunk larger than the initial decoded buffer (currently 4 KB).
123*6777b538SAndroid Build Coastguard Worker */
124*6777b538SAndroid Build Coastguard Worker buf = xmlBufferCreate();
125*6777b538SAndroid Build Coastguard Worker xmlBufferCat(buf,
126*6777b538SAndroid Build Coastguard Worker BAD_CAST "<?xml version='1.0' encoding='ISO-8859-1'?>\n");
127*6777b538SAndroid Build Coastguard Worker xmlBufferCat(buf, BAD_CAST "<doc><!-- ");
128*6777b538SAndroid Build Coastguard Worker for (i = 0; i < 2000; i++)
129*6777b538SAndroid Build Coastguard Worker xmlBufferCat(buf, BAD_CAST "0123456789");
130*6777b538SAndroid Build Coastguard Worker xmlBufferCat(buf, BAD_CAST " --></doc>");
131*6777b538SAndroid Build Coastguard Worker chunk = xmlBufferDetach(buf);
132*6777b538SAndroid Build Coastguard Worker xmlBufferFree(buf);
133*6777b538SAndroid Build Coastguard Worker
134*6777b538SAndroid Build Coastguard Worker ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
135*6777b538SAndroid Build Coastguard Worker
136*6777b538SAndroid Build Coastguard Worker xmlParseChunk(ctxt, (char *) chunk, xmlStrlen(chunk), 0);
137*6777b538SAndroid Build Coastguard Worker xmlParseChunk(ctxt, NULL, 0, 1);
138*6777b538SAndroid Build Coastguard Worker
139*6777b538SAndroid Build Coastguard Worker err = ctxt->wellFormed ? 0 : 1;
140*6777b538SAndroid Build Coastguard Worker xmlFreeDoc(ctxt->myDoc);
141*6777b538SAndroid Build Coastguard Worker xmlFreeParserCtxt(ctxt);
142*6777b538SAndroid Build Coastguard Worker xmlFree(chunk);
143*6777b538SAndroid Build Coastguard Worker
144*6777b538SAndroid Build Coastguard Worker return err;
145*6777b538SAndroid Build Coastguard Worker }
146*6777b538SAndroid Build Coastguard Worker #endif
147*6777b538SAndroid Build Coastguard Worker
148*6777b538SAndroid Build Coastguard Worker #if defined(LIBXML_READER_ENABLED) && defined(LIBXML_XINCLUDE_ENABLED)
149*6777b538SAndroid Build Coastguard Worker typedef struct {
150*6777b538SAndroid Build Coastguard Worker char *message;
151*6777b538SAndroid Build Coastguard Worker int code;
152*6777b538SAndroid Build Coastguard Worker } testReaderErrorCtxt;
153*6777b538SAndroid Build Coastguard Worker
154*6777b538SAndroid Build Coastguard Worker static void
testReaderError(void * arg,const char * msg,xmlParserSeverities severity ATTRIBUTE_UNUSED,xmlTextReaderLocatorPtr locator ATTRIBUTE_UNUSED)155*6777b538SAndroid Build Coastguard Worker testReaderError(void *arg, const char *msg,
156*6777b538SAndroid Build Coastguard Worker xmlParserSeverities severity ATTRIBUTE_UNUSED,
157*6777b538SAndroid Build Coastguard Worker xmlTextReaderLocatorPtr locator ATTRIBUTE_UNUSED) {
158*6777b538SAndroid Build Coastguard Worker testReaderErrorCtxt *ctxt = arg;
159*6777b538SAndroid Build Coastguard Worker
160*6777b538SAndroid Build Coastguard Worker if (ctxt->message != NULL)
161*6777b538SAndroid Build Coastguard Worker xmlFree(ctxt->message);
162*6777b538SAndroid Build Coastguard Worker ctxt->message = xmlMemStrdup(msg);
163*6777b538SAndroid Build Coastguard Worker }
164*6777b538SAndroid Build Coastguard Worker
165*6777b538SAndroid Build Coastguard Worker static void
testStructuredReaderError(void * arg,const xmlError * error)166*6777b538SAndroid Build Coastguard Worker testStructuredReaderError(void *arg, const xmlError *error) {
167*6777b538SAndroid Build Coastguard Worker testReaderErrorCtxt *ctxt = arg;
168*6777b538SAndroid Build Coastguard Worker
169*6777b538SAndroid Build Coastguard Worker if (ctxt->message != NULL)
170*6777b538SAndroid Build Coastguard Worker xmlFree(ctxt->message);
171*6777b538SAndroid Build Coastguard Worker ctxt->message = xmlMemStrdup(error->message);
172*6777b538SAndroid Build Coastguard Worker ctxt->code = error->code;
173*6777b538SAndroid Build Coastguard Worker }
174*6777b538SAndroid Build Coastguard Worker
175*6777b538SAndroid Build Coastguard Worker static int
testReaderXIncludeError(void)176*6777b538SAndroid Build Coastguard Worker testReaderXIncludeError(void) {
177*6777b538SAndroid Build Coastguard Worker /*
178*6777b538SAndroid Build Coastguard Worker * Test whether XInclude errors are reported to the custom error
179*6777b538SAndroid Build Coastguard Worker * handler of a reader.
180*6777b538SAndroid Build Coastguard Worker */
181*6777b538SAndroid Build Coastguard Worker const char *doc =
182*6777b538SAndroid Build Coastguard Worker "<doc xmlns:xi='http://www.w3.org/2001/XInclude'>\n"
183*6777b538SAndroid Build Coastguard Worker " <xi:include/>\n"
184*6777b538SAndroid Build Coastguard Worker "</doc>\n";
185*6777b538SAndroid Build Coastguard Worker xmlTextReader *reader;
186*6777b538SAndroid Build Coastguard Worker testReaderErrorCtxt errorCtxt;
187*6777b538SAndroid Build Coastguard Worker int err = 0;
188*6777b538SAndroid Build Coastguard Worker
189*6777b538SAndroid Build Coastguard Worker reader = xmlReaderForDoc(BAD_CAST doc, NULL, NULL, XML_PARSE_XINCLUDE);
190*6777b538SAndroid Build Coastguard Worker xmlTextReaderSetErrorHandler(reader, testReaderError, &errorCtxt);
191*6777b538SAndroid Build Coastguard Worker errorCtxt.message = NULL;
192*6777b538SAndroid Build Coastguard Worker errorCtxt.code = 0;
193*6777b538SAndroid Build Coastguard Worker while (xmlTextReaderRead(reader) > 0)
194*6777b538SAndroid Build Coastguard Worker ;
195*6777b538SAndroid Build Coastguard Worker
196*6777b538SAndroid Build Coastguard Worker if (errorCtxt.message == NULL ||
197*6777b538SAndroid Build Coastguard Worker strstr(errorCtxt.message, "href or xpointer") == NULL) {
198*6777b538SAndroid Build Coastguard Worker fprintf(stderr, "xmlTextReaderSetErrorHandler failed\n");
199*6777b538SAndroid Build Coastguard Worker err = 1;
200*6777b538SAndroid Build Coastguard Worker }
201*6777b538SAndroid Build Coastguard Worker
202*6777b538SAndroid Build Coastguard Worker xmlFree(errorCtxt.message);
203*6777b538SAndroid Build Coastguard Worker xmlFreeTextReader(reader);
204*6777b538SAndroid Build Coastguard Worker
205*6777b538SAndroid Build Coastguard Worker reader = xmlReaderForDoc(BAD_CAST doc, NULL, NULL, XML_PARSE_XINCLUDE);
206*6777b538SAndroid Build Coastguard Worker xmlTextReaderSetStructuredErrorHandler(reader, testStructuredReaderError,
207*6777b538SAndroid Build Coastguard Worker &errorCtxt);
208*6777b538SAndroid Build Coastguard Worker errorCtxt.message = NULL;
209*6777b538SAndroid Build Coastguard Worker errorCtxt.code = 0;
210*6777b538SAndroid Build Coastguard Worker while (xmlTextReaderRead(reader) > 0)
211*6777b538SAndroid Build Coastguard Worker ;
212*6777b538SAndroid Build Coastguard Worker
213*6777b538SAndroid Build Coastguard Worker if (errorCtxt.code != XML_XINCLUDE_NO_HREF ||
214*6777b538SAndroid Build Coastguard Worker errorCtxt.message == NULL ||
215*6777b538SAndroid Build Coastguard Worker strstr(errorCtxt.message, "href or xpointer") == NULL) {
216*6777b538SAndroid Build Coastguard Worker fprintf(stderr, "xmlTextReaderSetStructuredErrorHandler failed\n");
217*6777b538SAndroid Build Coastguard Worker err = 1;
218*6777b538SAndroid Build Coastguard Worker }
219*6777b538SAndroid Build Coastguard Worker
220*6777b538SAndroid Build Coastguard Worker xmlFree(errorCtxt.message);
221*6777b538SAndroid Build Coastguard Worker xmlFreeTextReader(reader);
222*6777b538SAndroid Build Coastguard Worker
223*6777b538SAndroid Build Coastguard Worker return err;
224*6777b538SAndroid Build Coastguard Worker }
225*6777b538SAndroid Build Coastguard Worker #endif
226*6777b538SAndroid Build Coastguard Worker
227*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_WRITER_ENABLED
228*6777b538SAndroid Build Coastguard Worker static int
testWriterIOWrite(void * ctxt,const char * data,int len)229*6777b538SAndroid Build Coastguard Worker testWriterIOWrite(void *ctxt, const char *data, int len) {
230*6777b538SAndroid Build Coastguard Worker (void) ctxt;
231*6777b538SAndroid Build Coastguard Worker (void) data;
232*6777b538SAndroid Build Coastguard Worker
233*6777b538SAndroid Build Coastguard Worker return len;
234*6777b538SAndroid Build Coastguard Worker }
235*6777b538SAndroid Build Coastguard Worker
236*6777b538SAndroid Build Coastguard Worker static int
testWriterIOClose(void * ctxt)237*6777b538SAndroid Build Coastguard Worker testWriterIOClose(void *ctxt) {
238*6777b538SAndroid Build Coastguard Worker (void) ctxt;
239*6777b538SAndroid Build Coastguard Worker
240*6777b538SAndroid Build Coastguard Worker return XML_IO_ENAMETOOLONG;
241*6777b538SAndroid Build Coastguard Worker }
242*6777b538SAndroid Build Coastguard Worker
243*6777b538SAndroid Build Coastguard Worker static int
testWriterClose(void)244*6777b538SAndroid Build Coastguard Worker testWriterClose(void){
245*6777b538SAndroid Build Coastguard Worker xmlOutputBufferPtr out;
246*6777b538SAndroid Build Coastguard Worker xmlTextWriterPtr writer;
247*6777b538SAndroid Build Coastguard Worker int err = 0;
248*6777b538SAndroid Build Coastguard Worker int result;
249*6777b538SAndroid Build Coastguard Worker
250*6777b538SAndroid Build Coastguard Worker out = xmlOutputBufferCreateIO(testWriterIOWrite, testWriterIOClose,
251*6777b538SAndroid Build Coastguard Worker NULL, NULL);
252*6777b538SAndroid Build Coastguard Worker writer = xmlNewTextWriter(out);
253*6777b538SAndroid Build Coastguard Worker xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL);
254*6777b538SAndroid Build Coastguard Worker xmlTextWriterStartElement(writer, BAD_CAST "elem");
255*6777b538SAndroid Build Coastguard Worker xmlTextWriterEndElement(writer);
256*6777b538SAndroid Build Coastguard Worker xmlTextWriterEndDocument(writer);
257*6777b538SAndroid Build Coastguard Worker result = xmlTextWriterClose(writer);
258*6777b538SAndroid Build Coastguard Worker
259*6777b538SAndroid Build Coastguard Worker if (result != XML_IO_ENAMETOOLONG) {
260*6777b538SAndroid Build Coastguard Worker fprintf(stderr, "xmlTextWriterClose reported wrong error %d\n",
261*6777b538SAndroid Build Coastguard Worker result);
262*6777b538SAndroid Build Coastguard Worker err = 1;
263*6777b538SAndroid Build Coastguard Worker }
264*6777b538SAndroid Build Coastguard Worker
265*6777b538SAndroid Build Coastguard Worker xmlFreeTextWriter(writer);
266*6777b538SAndroid Build Coastguard Worker return err;
267*6777b538SAndroid Build Coastguard Worker }
268*6777b538SAndroid Build Coastguard Worker #endif
269*6777b538SAndroid Build Coastguard Worker
270*6777b538SAndroid Build Coastguard Worker int
main(void)271*6777b538SAndroid Build Coastguard Worker main(void) {
272*6777b538SAndroid Build Coastguard Worker int err = 0;
273*6777b538SAndroid Build Coastguard Worker
274*6777b538SAndroid Build Coastguard Worker err |= testStandaloneWithEncoding();
275*6777b538SAndroid Build Coastguard Worker err |= testUnsupportedEncoding();
276*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_SAX1_ENABLED
277*6777b538SAndroid Build Coastguard Worker err |= testBalancedChunk();
278*6777b538SAndroid Build Coastguard Worker #endif
279*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_PUSH_ENABLED
280*6777b538SAndroid Build Coastguard Worker err |= testHugePush();
281*6777b538SAndroid Build Coastguard Worker err |= testHugeEncodedChunk();
282*6777b538SAndroid Build Coastguard Worker #endif
283*6777b538SAndroid Build Coastguard Worker #if defined(LIBXML_READER_ENABLED) && defined(LIBXML_XINCLUDE_ENABLED)
284*6777b538SAndroid Build Coastguard Worker err |= testReaderXIncludeError();
285*6777b538SAndroid Build Coastguard Worker #endif
286*6777b538SAndroid Build Coastguard Worker #ifdef LIBXML_WRITER_ENABLED
287*6777b538SAndroid Build Coastguard Worker err |= testWriterClose();
288*6777b538SAndroid Build Coastguard Worker #endif
289*6777b538SAndroid Build Coastguard Worker
290*6777b538SAndroid Build Coastguard Worker return err;
291*6777b538SAndroid Build Coastguard Worker }
292*6777b538SAndroid Build Coastguard Worker
293