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