/src/libxml2/fuzz/reader.c
Line | Count | Source |
1 | | /* |
2 | | * reader.c: a libFuzzer target to test the XML Reader API. |
3 | | * |
4 | | * See Copyright for the status of this software. |
5 | | */ |
6 | | |
7 | | #include <libxml/catalog.h> |
8 | | #include <libxml/parser.h> |
9 | | #include <libxml/tree.h> |
10 | | #include <libxml/xmlerror.h> |
11 | | #include <libxml/xmlreader.h> |
12 | | #include <libxml/xmlsave.h> |
13 | | #include "fuzz.h" |
14 | | |
15 | | #include <string.h> |
16 | | |
17 | | #if 0 |
18 | | #define DEBUG |
19 | | #endif |
20 | | |
21 | | typedef enum { |
22 | | OP_READ = 1, |
23 | | OP_READ_INNER_XML, |
24 | | OP_READ_OUTER_XML, |
25 | | OP_READ_STRING, |
26 | | OP_READ_ATTRIBUTE_VALUE, |
27 | | OP_ATTRIBUTE_COUNT, |
28 | | OP_DEPTH, |
29 | | OP_HAS_ATTRIBUTES, |
30 | | OP_HAS_VALUE, |
31 | | OP_IS_DEFAULT, |
32 | | OP_IS_EMPTY_ELEMENT, |
33 | | OP_NODE_TYPE, |
34 | | OP_QUOTE_CHAR, |
35 | | OP_READ_STATE, |
36 | | OP_IS_NAMESPACE_DECL, |
37 | | OP_CONST_BASE_URI, |
38 | | OP_CONST_LOCAL_NAME, |
39 | | OP_CONST_NAME, |
40 | | OP_CONST_NAMESPACE_URI, |
41 | | OP_CONST_PREFIX, |
42 | | OP_CONST_XML_LANG, |
43 | | OP_CONST_VALUE, |
44 | | OP_BASE_URI, |
45 | | OP_LOCAL_NAME, |
46 | | OP_NAME, |
47 | | OP_NAMESPACE_URI, |
48 | | OP_PREFIX, |
49 | | OP_XML_LANG, |
50 | | OP_VALUE, |
51 | | OP_CLOSE, |
52 | | OP_GET_ATTRIBUTE_NO, |
53 | | OP_GET_ATTRIBUTE, |
54 | | OP_GET_ATTRIBUTE_NS, |
55 | | OP_GET_REMAINDER, |
56 | | OP_LOOKUP_NAMESPACE, |
57 | | OP_MOVE_TO_ATTRIBUTE_NO, |
58 | | OP_MOVE_TO_ATTRIBUTE, |
59 | | OP_MOVE_TO_ATTRIBUTE_NS, |
60 | | OP_MOVE_TO_FIRST_ATTRIBUTE, |
61 | | OP_MOVE_TO_NEXT_ATTRIBUTE, |
62 | | OP_MOVE_TO_ELEMENT, |
63 | | OP_NORMALIZATION, |
64 | | OP_CONST_ENCODING, |
65 | | OP_GET_PARSER_PROP, |
66 | | OP_CURRENT_NODE, |
67 | | OP_GET_PARSER_LINE_NUMBER, |
68 | | OP_GET_PARSER_COLUMN_NUMBER, |
69 | | OP_PRESERVE, |
70 | | OP_CURRENT_DOC, |
71 | | OP_EXPAND, |
72 | | OP_NEXT, |
73 | | OP_NEXT_SIBLING, |
74 | | OP_IS_VALID, |
75 | | OP_CONST_XML_VERSION, |
76 | | OP_STANDALONE, |
77 | | OP_BYTE_CONSUMED, |
78 | | |
79 | | OP_MAX |
80 | | } opType; |
81 | | |
82 | | static void |
83 | 778k | startOp(const char *name) { |
84 | 778k | (void) name; |
85 | | #ifdef DEBUG |
86 | | fprintf(stderr, "%s\n", name); |
87 | | #endif |
88 | 778k | } |
89 | | |
90 | | int |
91 | | LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED, |
92 | 2 | char ***argv ATTRIBUTE_UNUSED) { |
93 | 2 | xmlFuzzMemSetup(); |
94 | 2 | xmlInitParser(); |
95 | 2 | #ifdef LIBXML_CATALOG_ENABLED |
96 | 2 | xmlInitializeCatalog(); |
97 | 2 | xmlCatalogSetDefaults(XML_CATA_ALLOW_NONE); |
98 | 2 | #endif |
99 | | |
100 | 2 | return 0; |
101 | 2 | } |
102 | | |
103 | | int |
104 | 36.3k | LLVMFuzzerTestOneInput(const char *data, size_t size) { |
105 | 36.3k | xmlTextReaderPtr reader; |
106 | 36.3k | xmlDocPtr doc = NULL; |
107 | 36.3k | const xmlError *error; |
108 | 36.3k | const char *docBuffer; |
109 | 36.3k | const unsigned char *program; |
110 | 36.3k | size_t failurePos, docSize, programSize, i; |
111 | 36.3k | size_t totalStringSize = 0; |
112 | 36.3k | int opts; |
113 | 36.3k | int oomReport = 0; |
114 | | |
115 | 36.3k | xmlFuzzDataInit(data, size); |
116 | 36.3k | opts = (int) xmlFuzzReadInt(4); |
117 | 36.3k | failurePos = xmlFuzzReadInt(4) % (size + 100); |
118 | | |
119 | 36.3k | program = (const unsigned char *) xmlFuzzReadString(&programSize); |
120 | 36.3k | if (programSize > 1000) |
121 | 52 | programSize = 1000; |
122 | | |
123 | 36.3k | xmlFuzzReadEntities(); |
124 | 36.3k | docBuffer = xmlFuzzMainEntity(&docSize); |
125 | 36.3k | if (docBuffer == NULL) |
126 | 113 | goto exit; |
127 | | |
128 | | #ifdef DEBUG |
129 | | fprintf(stderr, "Input document (%d bytes):\n", (int) docSize); |
130 | | for (i = 0; (size_t) i < docSize; i++) { |
131 | | int c = (unsigned char) docBuffer[i]; |
132 | | |
133 | | if ((c == '\n' || (c >= 0x20 && c <= 0x7E))) |
134 | | putc(c, stderr); |
135 | | else |
136 | | fprintf(stderr, "\\x%02X", c); |
137 | | } |
138 | | fprintf(stderr, "\nEOF\n"); |
139 | | #endif |
140 | | |
141 | 36.1k | xmlFuzzInjectFailure(failurePos); |
142 | 36.1k | reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts); |
143 | 36.1k | if (reader == NULL) |
144 | 70 | goto exit; |
145 | | |
146 | 36.1k | xmlTextReaderSetStructuredErrorHandler(reader, xmlFuzzSErrorFunc, NULL); |
147 | 36.1k | xmlTextReaderSetResourceLoader(reader, xmlFuzzResourceLoader, NULL); |
148 | | |
149 | 36.1k | i = 0; |
150 | 813k | while (i < programSize) { |
151 | 778k | int op = program[i++]; |
152 | | |
153 | 778k | #define READ_BYTE() (i < programSize ? program[i++] : 0) |
154 | 778k | #define FREE_STRING(str) \ |
155 | 778k | do { \ |
156 | 167k | if (str != NULL) { \ |
157 | 49.7k | totalStringSize += strlen((char *) str); \ |
158 | 49.7k | xmlFree(str); \ |
159 | 49.7k | } \ |
160 | 167k | } while (0) |
161 | | |
162 | 778k | switch (op & 0x3F) { |
163 | 56.4k | case OP_READ: |
164 | 265k | default: |
165 | 265k | startOp("Read"); |
166 | 265k | xmlTextReaderRead(reader); |
167 | 265k | break; |
168 | | |
169 | 13.5k | case OP_READ_INNER_XML: { |
170 | 13.5k | xmlChar *result; |
171 | | |
172 | 13.5k | startOp("ReadInnerXml"); |
173 | 13.5k | result = xmlTextReaderReadInnerXml(reader); |
174 | 13.5k | FREE_STRING(result); |
175 | 13.5k | break; |
176 | 56.4k | } |
177 | | |
178 | 30.5k | case OP_READ_OUTER_XML: { |
179 | 30.5k | xmlChar *result; |
180 | | |
181 | 30.5k | startOp("ReadOuterXml"); |
182 | 30.5k | result = xmlTextReaderReadOuterXml(reader); |
183 | 30.5k | FREE_STRING(result); |
184 | 30.5k | break; |
185 | 56.4k | } |
186 | | |
187 | 10.4k | case OP_READ_STRING: { |
188 | 10.4k | xmlChar *result; |
189 | | |
190 | 10.4k | startOp("ReadString"); |
191 | 10.4k | result = xmlTextReaderReadString(reader); |
192 | 10.4k | FREE_STRING(result); |
193 | 10.4k | break; |
194 | 56.4k | } |
195 | | |
196 | 10.2k | case OP_READ_ATTRIBUTE_VALUE: |
197 | 10.2k | startOp("ReadAttributeValue"); |
198 | 10.2k | xmlTextReaderReadAttributeValue(reader); |
199 | 10.2k | break; |
200 | | |
201 | 9.19k | case OP_ATTRIBUTE_COUNT: |
202 | 9.19k | startOp("AttributeCount"); |
203 | 9.19k | xmlTextReaderAttributeCount(reader); |
204 | 9.19k | break; |
205 | | |
206 | 4.30k | case OP_DEPTH: |
207 | 4.30k | startOp("Depth"); |
208 | 4.30k | xmlTextReaderDepth(reader); |
209 | 4.30k | break; |
210 | | |
211 | 3.05k | case OP_HAS_ATTRIBUTES: |
212 | 3.05k | startOp("HasAttributes"); |
213 | 3.05k | xmlTextReaderHasAttributes(reader); |
214 | 3.05k | break; |
215 | | |
216 | 13.2k | case OP_HAS_VALUE: |
217 | 13.2k | startOp("HasValue"); |
218 | 13.2k | xmlTextReaderHasValue(reader); |
219 | 13.2k | break; |
220 | | |
221 | 5.70k | case OP_IS_DEFAULT: |
222 | 5.70k | startOp("IsDefault"); |
223 | 5.70k | xmlTextReaderIsDefault(reader); |
224 | 5.70k | break; |
225 | | |
226 | 10.5k | case OP_IS_EMPTY_ELEMENT: |
227 | 10.5k | startOp("IsEmptyElement"); |
228 | 10.5k | xmlTextReaderIsEmptyElement(reader); |
229 | 10.5k | break; |
230 | | |
231 | 11.5k | case OP_NODE_TYPE: |
232 | 11.5k | startOp("NodeType"); |
233 | 11.5k | xmlTextReaderNodeType(reader); |
234 | 11.5k | break; |
235 | | |
236 | 3.44k | case OP_QUOTE_CHAR: |
237 | 3.44k | startOp("QuoteChar"); |
238 | 3.44k | xmlTextReaderQuoteChar(reader); |
239 | 3.44k | break; |
240 | | |
241 | 7.25k | case OP_READ_STATE: |
242 | 7.25k | startOp("ReadState"); |
243 | 7.25k | xmlTextReaderReadState(reader); |
244 | 7.25k | break; |
245 | | |
246 | 3.85k | case OP_IS_NAMESPACE_DECL: |
247 | 3.85k | startOp("IsNamespaceDecl"); |
248 | 3.85k | xmlTextReaderIsNamespaceDecl(reader); |
249 | 3.85k | break; |
250 | | |
251 | 44.0k | case OP_CONST_BASE_URI: |
252 | 44.0k | startOp("ConstBaseUri"); |
253 | 44.0k | xmlTextReaderConstBaseUri(reader); |
254 | 44.0k | break; |
255 | | |
256 | 3.00k | case OP_CONST_LOCAL_NAME: |
257 | 3.00k | startOp("ConstLocalName"); |
258 | 3.00k | xmlTextReaderConstLocalName(reader); |
259 | 3.00k | break; |
260 | | |
261 | 4.89k | case OP_CONST_NAME: |
262 | 4.89k | startOp("ConstName"); |
263 | 4.89k | xmlTextReaderConstName(reader); |
264 | 4.89k | break; |
265 | | |
266 | 5.61k | case OP_CONST_NAMESPACE_URI: |
267 | 5.61k | startOp("ConstNamespaceUri"); |
268 | 5.61k | xmlTextReaderConstNamespaceUri(reader); |
269 | 5.61k | break; |
270 | | |
271 | 13.2k | case OP_CONST_PREFIX: |
272 | 13.2k | startOp("ConstPrefix"); |
273 | 13.2k | xmlTextReaderConstPrefix(reader); |
274 | 13.2k | break; |
275 | | |
276 | 6.85k | case OP_CONST_XML_LANG: |
277 | 6.85k | startOp("ConstXmlLang"); |
278 | 6.85k | xmlTextReaderConstXmlLang(reader); |
279 | 6.85k | oomReport = -1; |
280 | 6.85k | break; |
281 | | |
282 | 7.07k | case OP_CONST_VALUE: |
283 | 7.07k | startOp("ConstValue"); |
284 | 7.07k | xmlTextReaderConstValue(reader); |
285 | 7.07k | break; |
286 | | |
287 | 8.60k | case OP_BASE_URI: { |
288 | 8.60k | xmlChar *result; |
289 | | |
290 | 8.60k | startOp("BaseUri"); |
291 | 8.60k | result = xmlTextReaderBaseUri(reader); |
292 | 8.60k | FREE_STRING(result); |
293 | 8.60k | break; |
294 | 56.4k | } |
295 | | |
296 | 4.88k | case OP_LOCAL_NAME: { |
297 | 4.88k | xmlChar *result; |
298 | | |
299 | 4.88k | startOp("LocalName"); |
300 | 4.88k | result = xmlTextReaderLocalName(reader); |
301 | 4.88k | FREE_STRING(result); |
302 | 4.88k | break; |
303 | 56.4k | } |
304 | | |
305 | 7.47k | case OP_NAME: { |
306 | 7.47k | xmlChar *result; |
307 | | |
308 | 7.47k | startOp("Name"); |
309 | 7.47k | result = xmlTextReaderName(reader); |
310 | 7.47k | FREE_STRING(result); |
311 | 7.47k | break; |
312 | 56.4k | } |
313 | | |
314 | 4.02k | case OP_NAMESPACE_URI: { |
315 | 4.02k | xmlChar *result; |
316 | | |
317 | 4.02k | startOp("NamespaceUri"); |
318 | 4.02k | result = xmlTextReaderNamespaceUri(reader); |
319 | 4.02k | FREE_STRING(result); |
320 | 4.02k | break; |
321 | 56.4k | } |
322 | | |
323 | 4.61k | case OP_PREFIX: { |
324 | 4.61k | xmlChar *result; |
325 | | |
326 | 4.61k | startOp("Prefix"); |
327 | 4.61k | result = xmlTextReaderPrefix(reader); |
328 | 4.61k | FREE_STRING(result); |
329 | 4.61k | break; |
330 | 56.4k | } |
331 | | |
332 | 3.32k | case OP_XML_LANG: { |
333 | 3.32k | xmlChar *result; |
334 | | |
335 | 3.32k | startOp("XmlLang"); |
336 | 3.32k | result = xmlTextReaderXmlLang(reader); |
337 | 3.32k | oomReport = -1; |
338 | 3.32k | FREE_STRING(result); |
339 | 3.32k | break; |
340 | 56.4k | } |
341 | | |
342 | 10.2k | case OP_VALUE: { |
343 | 10.2k | xmlChar *result; |
344 | | |
345 | 10.2k | startOp("Value"); |
346 | 10.2k | result = xmlTextReaderValue(reader); |
347 | 10.2k | FREE_STRING(result); |
348 | 10.2k | break; |
349 | 56.4k | } |
350 | | |
351 | 1.35k | case OP_CLOSE: |
352 | 1.35k | startOp("Close"); |
353 | 1.35k | if (doc == NULL) |
354 | 476 | doc = xmlTextReaderCurrentDoc(reader); |
355 | 1.35k | xmlTextReaderClose(reader); |
356 | 1.35k | break; |
357 | | |
358 | 4.57k | case OP_GET_ATTRIBUTE_NO: { |
359 | 4.57k | xmlChar *result; |
360 | 4.57k | int no = READ_BYTE(); |
361 | | |
362 | 4.57k | startOp("GetAttributeNo"); |
363 | 4.57k | result = xmlTextReaderGetAttributeNo(reader, no); |
364 | 4.57k | FREE_STRING(result); |
365 | 4.57k | break; |
366 | 56.4k | } |
367 | | |
368 | 33.6k | case OP_GET_ATTRIBUTE: { |
369 | 33.6k | const xmlChar *name = xmlTextReaderConstName(reader); |
370 | 33.6k | xmlChar *result; |
371 | | |
372 | 33.6k | startOp("GetAttribute"); |
373 | 33.6k | result = xmlTextReaderGetAttribute(reader, name); |
374 | 33.6k | FREE_STRING(result); |
375 | 33.6k | break; |
376 | 56.4k | } |
377 | | |
378 | 23.7k | case OP_GET_ATTRIBUTE_NS: { |
379 | 23.7k | const xmlChar *localName, *namespaceUri; |
380 | 23.7k | xmlChar *result; |
381 | | |
382 | 23.7k | startOp("GetAttributeNs"); |
383 | 23.7k | localName = xmlTextReaderConstLocalName(reader); |
384 | 23.7k | namespaceUri = xmlTextReaderConstNamespaceUri(reader); |
385 | 23.7k | result = xmlTextReaderGetAttributeNs(reader, localName, |
386 | 23.7k | namespaceUri); |
387 | 23.7k | FREE_STRING(result); |
388 | 23.7k | break; |
389 | 56.4k | } |
390 | | |
391 | 3.59k | case OP_GET_REMAINDER: |
392 | 3.59k | startOp("GetRemainder"); |
393 | 3.59k | if (doc == NULL) |
394 | 1.69k | doc = xmlTextReaderCurrentDoc(reader); |
395 | 3.59k | xmlFreeParserInputBuffer(xmlTextReaderGetRemainder(reader)); |
396 | 3.59k | break; |
397 | | |
398 | 7.72k | case OP_LOOKUP_NAMESPACE: { |
399 | 7.72k | const xmlChar *prefix = xmlTextReaderConstPrefix(reader); |
400 | 7.72k | xmlChar *result; |
401 | | |
402 | 7.72k | startOp("LookupNamespace"); |
403 | 7.72k | result = xmlTextReaderLookupNamespace(reader, prefix); |
404 | 7.72k | FREE_STRING(result); |
405 | 7.72k | break; |
406 | 56.4k | } |
407 | | |
408 | 7.78k | case OP_MOVE_TO_ATTRIBUTE_NO: { |
409 | 7.78k | int no = READ_BYTE(); |
410 | | |
411 | 7.78k | startOp("MoveToAttributeNo"); |
412 | 7.78k | xmlTextReaderMoveToAttributeNo(reader, no); |
413 | 7.78k | break; |
414 | 56.4k | } |
415 | | |
416 | 14.7k | case OP_MOVE_TO_ATTRIBUTE: { |
417 | 14.7k | const xmlChar *name = xmlTextReaderConstName(reader); |
418 | | |
419 | 14.7k | startOp("MoveToAttribute"); |
420 | 14.7k | xmlTextReaderMoveToAttribute(reader, name); |
421 | 14.7k | break; |
422 | 56.4k | } |
423 | | |
424 | 10.3k | case OP_MOVE_TO_ATTRIBUTE_NS: { |
425 | 10.3k | const xmlChar *localName, *namespaceUri; |
426 | | |
427 | 10.3k | startOp("MoveToAttributeNs"); |
428 | 10.3k | localName = xmlTextReaderConstLocalName(reader); |
429 | 10.3k | namespaceUri = xmlTextReaderConstNamespaceUri(reader); |
430 | 10.3k | xmlTextReaderMoveToAttributeNs(reader, localName, |
431 | 10.3k | namespaceUri); |
432 | 10.3k | break; |
433 | 56.4k | } |
434 | | |
435 | 12.4k | case OP_MOVE_TO_FIRST_ATTRIBUTE: |
436 | 12.4k | startOp("MoveToFirstAttribute"); |
437 | 12.4k | xmlTextReaderMoveToFirstAttribute(reader); |
438 | 12.4k | break; |
439 | | |
440 | 8.19k | case OP_MOVE_TO_NEXT_ATTRIBUTE: |
441 | 8.19k | startOp("MoveToNextAttribute"); |
442 | 8.19k | xmlTextReaderMoveToNextAttribute(reader); |
443 | 8.19k | break; |
444 | | |
445 | 5.60k | case OP_MOVE_TO_ELEMENT: |
446 | 5.60k | startOp("MoveToElement"); |
447 | 5.60k | xmlTextReaderMoveToElement(reader); |
448 | 5.60k | break; |
449 | | |
450 | 1.62k | case OP_NORMALIZATION: |
451 | 1.62k | startOp("Normalization"); |
452 | 1.62k | xmlTextReaderNormalization(reader); |
453 | 1.62k | break; |
454 | | |
455 | 3.30k | case OP_CONST_ENCODING: |
456 | 3.30k | startOp("ConstEncoding"); |
457 | 3.30k | xmlTextReaderConstEncoding(reader); |
458 | 3.30k | break; |
459 | | |
460 | 8.24k | case OP_GET_PARSER_PROP: { |
461 | 8.24k | int prop = READ_BYTE(); |
462 | | |
463 | 8.24k | startOp("GetParserProp"); |
464 | 8.24k | xmlTextReaderGetParserProp(reader, prop); |
465 | 8.24k | break; |
466 | 56.4k | } |
467 | | |
468 | 11.9k | case OP_CURRENT_NODE: |
469 | 11.9k | startOp("CurrentNode"); |
470 | 11.9k | xmlTextReaderCurrentNode(reader); |
471 | 11.9k | break; |
472 | | |
473 | 6.09k | case OP_GET_PARSER_LINE_NUMBER: |
474 | 6.09k | startOp("GetParserLineNumber"); |
475 | 6.09k | xmlTextReaderGetParserLineNumber(reader); |
476 | 6.09k | break; |
477 | | |
478 | 8.28k | case OP_GET_PARSER_COLUMN_NUMBER: |
479 | 8.28k | startOp("GetParserColumnNumber"); |
480 | 8.28k | xmlTextReaderGetParserColumnNumber(reader); |
481 | 8.28k | break; |
482 | | |
483 | 8.32k | case OP_PRESERVE: |
484 | 8.32k | startOp("Preserve"); |
485 | 8.32k | xmlTextReaderPreserve(reader); |
486 | 8.32k | break; |
487 | | |
488 | 7.58k | case OP_CURRENT_DOC: { |
489 | 7.58k | xmlDocPtr result; |
490 | | |
491 | 7.58k | startOp("CurrentDoc"); |
492 | 7.58k | result = xmlTextReaderCurrentDoc(reader); |
493 | 7.58k | if (doc == NULL) |
494 | 2.81k | doc = result; |
495 | 7.58k | break; |
496 | 56.4k | } |
497 | | |
498 | 7.67k | case OP_EXPAND: |
499 | 7.67k | startOp("Expand"); |
500 | 7.67k | xmlTextReaderExpand(reader); |
501 | 7.67k | break; |
502 | | |
503 | 22.3k | case OP_NEXT: |
504 | 22.3k | startOp("Next"); |
505 | 22.3k | xmlTextReaderNext(reader); |
506 | 22.3k | break; |
507 | | |
508 | 8.58k | case OP_NEXT_SIBLING: |
509 | 8.58k | startOp("NextSibling"); |
510 | 8.58k | xmlTextReaderNextSibling(reader); |
511 | 8.58k | break; |
512 | | |
513 | 4.18k | case OP_IS_VALID: |
514 | 4.18k | startOp("IsValid"); |
515 | 4.18k | xmlTextReaderIsValid(reader); |
516 | 4.18k | break; |
517 | | |
518 | 5.13k | case OP_CONST_XML_VERSION: |
519 | 5.13k | startOp("ConstXmlVersion"); |
520 | 5.13k | xmlTextReaderConstXmlVersion(reader); |
521 | 5.13k | break; |
522 | | |
523 | 5.38k | case OP_STANDALONE: |
524 | 5.38k | startOp("Standalone"); |
525 | 5.38k | xmlTextReaderStandalone(reader); |
526 | 5.38k | break; |
527 | | |
528 | 5.67k | case OP_BYTE_CONSUMED: |
529 | 5.67k | startOp("ByteConsumed"); |
530 | 5.67k | xmlTextReaderByteConsumed(reader); |
531 | 5.67k | oomReport = -1; |
532 | 5.67k | break; |
533 | 778k | } |
534 | | |
535 | 778k | if (totalStringSize > docSize * 2) |
536 | 1.12k | break; |
537 | 778k | } |
538 | | |
539 | 36.1k | error = xmlTextReaderGetLastError(reader); |
540 | 36.1k | if (error->code == XML_ERR_NO_MEMORY) |
541 | 8.13k | oomReport = 1; |
542 | 36.1k | xmlFuzzCheckFailureReport("reader", oomReport, error->code == XML_IO_EIO); |
543 | | |
544 | 36.1k | xmlFreeTextReader(reader); |
545 | | |
546 | 36.1k | if (doc != NULL) |
547 | 3.53k | xmlFreeDoc(doc); |
548 | | |
549 | 36.3k | exit: |
550 | 36.3k | xmlFuzzInjectFailure(0); |
551 | 36.3k | xmlFuzzDataCleanup(); |
552 | 36.3k | xmlResetLastError(); |
553 | 36.3k | return(0); |
554 | 36.1k | } |
555 | | |
556 | | size_t |
557 | | LLVMFuzzerCustomMutator(char *data, size_t size, size_t maxSize, |
558 | 0 | unsigned seed) { |
559 | 0 | static const xmlFuzzChunkDesc chunks[] = { |
560 | 0 | { 4, XML_FUZZ_PROB_ONE / 10 }, /* opts */ |
561 | 0 | { 4, XML_FUZZ_PROB_ONE / 10 }, /* failurePos */ |
562 | 0 | { 0, 0 } |
563 | 0 | }; |
564 | |
|
565 | 0 | return xmlFuzzMutateChunks(chunks, data, size, maxSize, seed, |
566 | 0 | LLVMFuzzerMutate); |
567 | 0 | } |
568 | | |