• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * api.c: a libFuzzer target to test node-related API functions.
3  *
4  * See Copyright for the status of this software.
5  *
6  * This is a simple virtual machine which runs fuzz data as a program.
7  * An important design goal is to execute as many API calls as possible
8  * per input byte.
9  *
10  * We use a fixed number of registers for basic types like integers
11  * or strings as well as libxml2 objects like xmlNode. The opcodes are
12  * single bytes which typically result in a call to an API function
13  * using the freshest registers for each argument type and storing the
14  * result in the stalest register. This can be implemented using a ring
15  * buffer.
16  *
17  * There are a few other opcodes to initialize or duplicate registers,
18  * so all kinds of API calls can potentially be generated from fuzz
19  * data.
20  *
21  * This architecture is similar to stack machine and benefits from
22  * great code density. The main difference is that values aren't
23  * destroyed when popping arguments from the stack and that the bottom
24  * of the stack is eventually overwritten if the ring buffer overflows.
25  *
26  * The main complication is memory management of nodes. Whenever a
27  * reference between two nodes is removed, whether by an API call or
28  * the VM clearing a register, we must check whether this leaves
29  * unreferenced nodes which can then be freed. There are no opcodes
30  * to free a node explicitly. The FIFO patterns generated by
31  * overflowing the ring buffer and freeing the registers at the end of
32  * a program seem to do a good enough job.
33  */
34 
35 #include <stdlib.h>
36 #include <string.h>
37 
38 #define XML_DEPRECATED
39 
40 #include <libxml/catalog.h>
41 #include <libxml/HTMLtree.h>
42 #include <libxml/parser.h>
43 #include <libxml/tree.h>
44 #include <libxml/xmlerror.h>
45 #include "fuzz.h"
46 
47 #if 0
48   #define DEBUG printf
49 #else
50   #define DEBUG(...)
51 #endif
52 
53 #define MAX_CONTENT     100
54 #define MAX_COPY_NODES   50
55 #define MAX_COPY_OPS     20
56 
57 typedef enum {
58     /* Basic operations */
59     OP_CREATE_INTEGER,
60     OP_CREATE_STRING,
61     OP_DUP_INTEGER,
62     OP_DUP_STRING,
63     OP_DUP_NODE,
64 
65     /*** tree.h ***/
66 
67     /* Tree constructors */
68     OP_XML_NEW_DOC,
69     OP_XML_NEW_NODE,
70     OP_XML_NEW_NODE_EAT_NAME,
71     OP_XML_NEW_DOC_NODE,
72     OP_XML_NEW_DOC_NODE_EAT_NAME,
73     OP_XML_NEW_DOC_RAW_NODE,
74     OP_XML_NEW_CHILD,
75     OP_XML_NEW_TEXT_CHILD,
76     OP_XML_NEW_PROP,
77     OP_XML_NEW_DOC_PROP,
78     OP_XML_NEW_NS_PROP,
79     OP_XML_NEW_NS_PROP_EAT_NAME,
80     OP_XML_NEW_TEXT,
81     OP_XML_NEW_TEXT_LEN,
82     OP_XML_NEW_DOC_TEXT,
83     OP_XML_NEW_DOC_TEXT_LEN,
84     OP_XML_NEW_PI,
85     OP_XML_NEW_DOC_PI,
86     OP_XML_NEW_COMMENT,
87     OP_XML_NEW_DOC_COMMENT,
88     OP_XML_NEW_CDATA_BLOCK,
89     OP_XML_NEW_CHAR_REF,
90     OP_XML_NEW_REFERENCE,
91     OP_XML_NEW_DOC_FRAGMENT,
92     OP_XML_CREATE_INT_SUBSET,
93     OP_XML_NEW_DTD,
94 
95     /* Node copying */
96     OP_XML_COPY_DOC,
97     OP_XML_COPY_NODE,
98     OP_XML_COPY_NODE_LIST,
99     OP_XML_DOC_COPY_NODE,
100     OP_XML_DOC_COPY_NODE_LIST,
101     OP_XML_COPY_PROP,
102     OP_XML_COPY_PROP_LIST,
103     OP_XML_COPY_DTD,
104 
105     /* Node accessors */
106     OP_NODE_PARENT,
107     OP_NODE_NEXT_SIBLING,
108     OP_NODE_PREV_SIBLING,
109     OP_NODE_FIRST_CHILD,
110     OP_XML_GET_LAST_CHILD,
111     OP_NODE_NAME,
112     OP_XML_NODE_SET_NAME,
113     OP_XML_NODE_GET_CONTENT,
114     OP_XML_NODE_SET_CONTENT,
115     OP_XML_NODE_SET_CONTENT_LEN,
116     OP_XML_NODE_ADD_CONTENT,
117     OP_XML_NODE_ADD_CONTENT_LEN,
118     OP_XML_GET_INT_SUBSET,
119     OP_XML_GET_LINE_NO,
120     OP_XML_GET_NODE_PATH,
121     OP_XML_DOC_GET_ROOT_ELEMENT,
122     OP_XML_DOC_SET_ROOT_ELEMENT,
123     OP_XML_NODE_IS_TEXT,
124     OP_XML_NODE_GET_ATTR_VALUE,
125     OP_XML_NODE_GET_LANG,
126     OP_XML_NODE_SET_LANG,
127     OP_XML_NODE_GET_SPACE_PRESERVE,
128     OP_XML_NODE_SET_SPACE_PRESERVE,
129     OP_XML_NODE_GET_BASE,
130     OP_XML_NODE_GET_BASE_SAFE,
131     OP_XML_NODE_SET_BASE,
132     OP_XML_IS_BLANK_NODE,
133 
134     /* Attributes */
135     OP_XML_HAS_PROP,
136     OP_XML_HAS_NS_PROP,
137     OP_XML_GET_PROP,
138     OP_XML_GET_NS_PROP,
139     OP_XML_GET_NO_NS_PROP,
140     OP_XML_SET_PROP,
141     OP_XML_SET_NS_PROP,
142     OP_XML_REMOVE_PROP,
143     OP_XML_UNSET_PROP,
144     OP_XML_UNSET_NS_PROP,
145 
146     /* Namespaces */
147     OP_XML_NEW_NS,
148     OP_XML_SEARCH_NS,
149     OP_XML_SEARCH_NS_BY_HREF,
150     OP_XML_GET_NS_LIST,
151     OP_XML_GET_NS_LIST_SAFE,
152     OP_XML_SET_NS,
153     OP_XML_COPY_NAMESPACE,
154     OP_XML_COPY_NAMESPACE_LIST,
155 
156     /* Tree manipulation */
157     OP_XML_UNLINK_NODE,
158     OP_XML_ADD_CHILD,
159     OP_XML_ADD_CHILD_LIST,
160     OP_XML_REPLACE_NODE,
161     OP_XML_ADD_SIBLING,
162     OP_XML_ADD_PREV_SIBLING,
163     OP_XML_ADD_NEXT_SIBLING,
164 
165     /* String output */
166     OP_XML_DOC_DUMP_MEMORY,
167     OP_XML_DOC_DUMP_MEMORY_ENC,
168     OP_XML_DOC_DUMP_FORMAT_MEMORY,
169     OP_XML_DOC_DUMP_FORMAT_MEMORY_ENC,
170 
171     /* FILE output, TODO, use fmemopen */
172     OP_XML_DOC_DUMP,
173     OP_XML_DOC_FORMAT_DUMP,
174     OP_XML_ELEM_DUMP,
175 
176     /* xmlBuf output, TODO, no public API */
177     OP_XML_BUF_NODE_DUMP,
178     OP_XML_BUF_GET_NODE_CONTENT,
179 
180     /* xmlBuffer output */
181     OP_XML_NODE_DUMP,
182     OP_XML_NODE_BUF_GET_CONTENT,
183     OP_XML_ATTR_SERIALIZE_TXT_CONTENT,
184     OP_XML_DUMP_ELEMENT_DECL,
185     OP_XML_DUMP_ELEMENT_TABLE,
186     OP_XML_DUMP_ATTRIBUTE_DECL,
187     OP_XML_DUMP_ATTRIBUTE_TABLE,
188     OP_XML_DUMP_NOTATION_DECL,
189     OP_XML_DUMP_NOTATION_TABLE,
190     OP_XML_DUMP_ENTITY_DECL,
191     OP_XML_DUMP_ENTITIES_TABLE,
192 
193     /* xmlOutputBuffer */
194     OP_XML_SAVE_FILE_TO,
195     OP_XML_SAVE_FORMAT_FILE_TO,
196     OP_XML_NODE_DUMP_OUTPUT,
197 
198     /* Misc */
199     OP_XML_TEXT_MERGE,
200     OP_XML_TEXT_CONCAT,
201     OP_XML_STRING_GET_NODE_LIST,
202     OP_XML_STRING_LEN_GET_NODE_LIST,
203     OP_XML_NODE_LIST_GET_STRING,
204     OP_XML_NODE_LIST_GET_RAW_STRING,
205     OP_XML_IS_XHTML,
206 
207     /* DOM */
208     OP_XML_DOM_WRAP_RECONCILE_NAMESPACES,
209     OP_XML_DOM_WRAP_ADOPT_NODE,
210     OP_XML_DOM_WRAP_REMOVE_NODE,
211     OP_XML_DOM_WRAP_CLONE_NODE,
212     OP_XML_CHILD_ELEMENT_COUNT,
213     OP_XML_FIRST_ELEMENT_CHILD,
214     OP_XML_LAST_ELEMENT_CHILD,
215     OP_XML_NEXT_ELEMENT_SIBLING,
216     OP_XML_PREVIOUS_ELEMENT_SIBLING,
217 
218     /*** parser.h ***/
219 
220     OP_PARSE_DOCUMENT,
221 
222     /*** valid.h ***/
223 
224     OP_XML_ADD_ELEMENT_DECL,
225     OP_XML_ADD_ATTRIBUTE_DECL,
226     OP_XML_ADD_NOTATION_DECL,
227 
228     OP_XML_GET_DTD_ELEMENT_DESC,
229     OP_XML_GET_DTD_QELEMENT_DESC,
230     OP_XML_GET_DTD_ATTR_DESC,
231     OP_XML_GET_DTD_QATTR_DESC,
232     OP_XML_GET_DTD_NOTATION_DESC,
233 
234     OP_XML_ADD_ID,
235     OP_XML_ADD_ID_SAFE,
236     OP_XML_GET_ID,
237     OP_XML_IS_ID,
238     OP_XML_REMOVE_ID,
239 
240     OP_XML_ADD_REF,
241     OP_XML_GET_REFS,
242     OP_XML_IS_REF,
243     OP_XML_REMOVE_REF,
244 
245     OP_XML_IS_MIXED_ELEMENT,
246 
247     OP_VALIDATE,
248     OP_XML_VALIDATE_ATTRIBUTE_VALUE,
249     OP_XML_VALIDATE_DTD,
250     OP_XML_VALIDATE_NOTATION_USE,
251 
252     OP_XML_VALIDATE_NAME_VALUE,
253     OP_XML_VALIDATE_NAMES_VALUE,
254     OP_XML_VALIDATE_NMTOKEN_VALUE,
255     OP_XML_VALIDATE_NMTOKENS_VALUE,
256 
257     OP_XML_VALID_NORMALIZE_ATTRIBUTE_VALUE,
258     OP_XML_VALID_CTXT_NORMALIZE_ATTRIBUTE_VALUE,
259     OP_XML_VALID_GET_POTENTIAL_CHILDREN,
260     OP_XML_VALID_GET_VALID_ELEMENTS,
261 
262     /*** entities.h ***/
263 
264     OP_XML_NEW_ENTITY,
265     OP_XML_ADD_ENTITY,
266     OP_XML_ADD_DOC_ENTITY,
267     OP_XML_ADD_DTD_ENTITY,
268 
269     OP_XML_GET_PREDEFINED_ENTITY,
270     OP_XML_GET_DOC_ENTITY,
271     OP_XML_GET_DTD_ENTITY,
272     OP_XML_GET_PARAMETER_ENTITY,
273 
274     OP_XML_ENCODE_ENTITIES_REENTRANT,
275     OP_XML_ENCODE_SPECIAL_CHARS,
276 
277     /*** HTMLtree.h ***/
278 
279     OP_HTML_NEW_DOC,
280     OP_HTML_NEW_DOC_NO_DTD,
281     OP_HTML_GET_META_ENCODING,
282     OP_HTML_SET_META_ENCODING,
283     OP_HTML_IS_BOOLEAN_ATTR,
284 
285     OP_HTML_DOC_DUMP_MEMORY,
286     OP_HTML_DOC_DUMP_MEMORY_FORMAT,
287     OP_HTML_DOC_DUMP,
288     OP_HTML_NODE_DUMP_FILE,
289     OP_HTML_NODE_DUMP_FILE_FORMAT,
290     OP_HTML_NODE_DUMP,
291     OP_HTML_DOC_CONTENT_DUMP_OUTPUT,
292     OP_HTML_DOC_CONTENT_DUMP_FORMAT_OUTPUT,
293     OP_HTML_NODE_DUMP_OUTPUT,
294     OP_HTML_NODE_DUMP_FORMAT_OUTPUT,
295 
296     OP_MAX
297 } opType;
298 
299 #define NODE_MASK_TEXT_CONTENT ( \
300     (1 << XML_TEXT_NODE) | \
301     (1 << XML_CDATA_SECTION_NODE) | \
302     (1 << XML_COMMENT_NODE) | \
303     (1 << XML_PI_NODE))
304 
305 #define CHILD_MASK_DOCUMENT ( \
306     (1 << XML_ELEMENT_NODE) | \
307     (1 << XML_PI_NODE) | \
308     (1 << XML_COMMENT_NODE))
309 
310 #define CHILD_MASK_CONTENT ( \
311     (1 << XML_ELEMENT_NODE) | \
312     (1 << XML_TEXT_NODE) | \
313     (1 << XML_CDATA_SECTION_NODE) | \
314     (1 << XML_ENTITY_REF_NODE) | \
315     (1 << XML_PI_NODE) | \
316     (1 << XML_COMMENT_NODE))
317 
318 #define CHILD_MASK_ELEMENT ( \
319     CHILD_MASK_CONTENT | \
320     (1 << XML_ATTRIBUTE_NODE))
321 
322 #define CHILD_MASK_ATTRIBUTE ( \
323     (1 << XML_TEXT_NODE) | \
324     (1 << XML_ENTITY_REF_NODE))
325 
326 #define CHILD_MASK_DTD ( \
327     (1 << XML_ELEMENT_DECL) | \
328     (1 << XML_ATTRIBUTE_DECL) | \
329     (1 << XML_ENTITY_DECL))
330 
331 static const int childMasks[] = {
332     0,
333     CHILD_MASK_ELEMENT, /* XML_ELEMENT_NODE */
334     CHILD_MASK_ATTRIBUTE, /* XML_ATTRIBUTE_NODE */
335     0, /* XML_TEXT_NODE */
336     0, /* XML_CDATA_SECTION_NODE */
337     0, /* XML_ENTITY_REF_NODE */
338     0, /* XML_ENTITY_NODE */
339     0, /* XML_PI_NODE */
340     0, /* XML_COMMENT_NODE */
341     CHILD_MASK_DOCUMENT, /* XML_DOCUMENT_NODE */
342     0, /* XML_DOCUMENT_TYPE_NODE */
343     CHILD_MASK_CONTENT, /* XML_DOCUMENT_FRAG_NODE */
344     0, /* XML_NOTATION_NODE */
345     CHILD_MASK_DOCUMENT, /* XML_HTML_DOCUMENT_NODE */
346     0, /* XML_DTD_NODE */
347     0, /* XML_ELEMENT_DECL */
348     0, /* XML_ATTRIBUTE_DECL */
349     0, /* XML_ENTITY_DECL */
350     0, /* XML_NAMESPACE_DECL */
351     0, /* XML_XINCLUDE_START */
352     0, /* XML_XINCLUDE_END */
353     CHILD_MASK_DOCUMENT /* XML_DOCB_DOCUMENT_NODE */
354 };
355 
356 #define REG_MAX 8
357 #define REG_MASK (REG_MAX - 1)
358 
359 typedef struct {
360     /* Indexes point beyond the most recent item */
361     int intIdx;
362     int stringIdx;
363     int nodeIdx;
364 
365     int numCopyOps;
366 
367     const char *opName;
368 
369     /* Registers */
370     int integers[REG_MAX];
371     xmlChar *strings[REG_MAX];
372     xmlNodePtr nodes[REG_MAX];
373 } xmlFuzzApiVars;
374 
375 static xmlFuzzApiVars varsStruct;
376 static xmlFuzzApiVars *const vars = &varsStruct;
377 
378 /* Debug output */
379 
380 static void
startOp(const char * name)381 startOp(const char *name) {
382     vars->opName = name;
383     DEBUG("%s(", name);
384 }
385 
386 static void
endOp(void)387 endOp(void) {
388     DEBUG(" )\n");
389 }
390 
391 /* Integers */
392 
393 static int
getInt(int offset)394 getInt(int offset) {
395     int idx = (vars->intIdx - offset - 1) & REG_MASK;
396     DEBUG(" %d", vars->integers[idx]);
397     return vars->integers[idx];
398 }
399 
400 static void
setInt(int offset,int n)401 setInt(int offset, int n) {
402     int idx = (vars->intIdx - offset - 1) & REG_MASK;
403     vars->integers[idx] = n;
404 }
405 
406 static void
incIntIdx(void)407 incIntIdx(void) {
408     vars->intIdx = (vars->intIdx + 1) & REG_MASK;
409 }
410 
411 /* Strings */
412 
413 static const xmlChar *
getStr(int offset)414 getStr(int offset) {
415     int idx = (vars->stringIdx - offset - 1) & REG_MASK;
416     const xmlChar *str = vars->strings[idx];
417 
418     if (str == NULL)
419         DEBUG(" NULL");
420     else
421         DEBUG(" \"%.20s\"", str);
422 
423     return str;
424 }
425 
426 static const char *
getCStr(int offset)427 getCStr(int offset) {
428     return (const char *) getStr(offset);
429 }
430 
431 static void
setStr(int offset,xmlChar * str)432 setStr(int offset, xmlChar *str) {
433     xmlChar **strings = vars->strings;
434     int idx = (vars->stringIdx - offset - 1) & REG_MASK;
435     xmlChar *oldString = strings[idx];
436 
437     strings[idx] = str;
438     if (oldString)
439         xmlFree(oldString);
440 }
441 
442 static void
moveStr(int offset,xmlChar * str)443 moveStr(int offset, xmlChar *str) {
444     if (xmlStrlen(str) > 1000) {
445         setStr(offset, NULL);
446         xmlFree(str);
447     } else {
448         setStr(offset, str);
449     }
450 }
451 
452 /*
453  * This doesn't use xmlMalloc and can't fail because of malloc failure
454  * injection.
455  */
456 static xmlChar *
uncheckedStrndup(const xmlChar * str,int size)457 uncheckedStrndup(const xmlChar *str, int size) {
458     xmlChar *copy;
459 
460     if (str == NULL)
461         return NULL;
462 
463     copy = BAD_CAST strndup((const char *) str, size);
464     if (copy == NULL) {
465         fprintf(stderr, "out of memory\n");
466         abort();
467     }
468 
469     return copy;
470 }
471 
472 static xmlChar *
uncheckedStrdup(const xmlChar * str)473 uncheckedStrdup(const xmlChar *str) {
474     return uncheckedStrndup(str, MAX_CONTENT);
475 }
476 
477 static void
copyStr(int offset,const xmlChar * str)478 copyStr(int offset, const xmlChar *str) {
479     setStr(offset, uncheckedStrdup(str));
480 }
481 
482 static void
incStrIdx(void)483 incStrIdx(void) {
484     vars->stringIdx = (vars->stringIdx + 1) & REG_MASK;
485 }
486 
487 /* Nodes */
488 
489 static void
490 dropNode(xmlNodePtr node);
491 
492 static xmlNodePtr
getNode(int offset)493 getNode(int offset) {
494     int idx = (vars->nodeIdx - offset - 1) & REG_MASK;
495     if (vars->nodes[idx])
496         DEBUG(" n%d", idx);
497     else
498         DEBUG(" NULL");
499     fflush(stdout);
500     return vars->nodes[idx];
501 }
502 
503 static xmlDocPtr
getDoc(int offset)504 getDoc(int offset) {
505     xmlNodePtr node = getNode(offset);
506 
507     if (node == NULL)
508         return NULL;
509     return node->doc;
510 }
511 
512 static xmlAttrPtr
getAttr(int offset)513 getAttr(int offset) {
514     xmlNodePtr node = getNode(offset);
515 
516     if (node == NULL)
517         return NULL;
518     if (node->type == XML_ATTRIBUTE_NODE)
519         return (xmlAttrPtr) node;
520     if (node->type == XML_ELEMENT_NODE)
521         return node->properties;
522 
523     return NULL;
524 }
525 
526 static xmlDtdPtr
getDtd(int offset)527 getDtd(int offset) {
528     xmlNodePtr node = getNode(offset);
529     xmlDocPtr doc;
530 
531     if (node == NULL)
532         return NULL;
533 
534     if (node->type == XML_DTD_NODE)
535         return (xmlDtdPtr) node;
536 
537     doc = node->doc;
538     if (doc == NULL)
539         return NULL;
540     if (doc->intSubset != NULL)
541         return doc->intSubset;
542     return doc->extSubset;
543 }
544 
545 static void
setNode(int offset,xmlNodePtr node)546 setNode(int offset, xmlNodePtr node) {
547     int idx = (vars->nodeIdx - offset - 1) & REG_MASK;
548     xmlNodePtr oldNode = vars->nodes[idx];
549 
550     if (node != oldNode) {
551         vars->nodes[idx] = node;
552         dropNode(oldNode);
553     }
554 
555     if (node == NULL)
556         DEBUG(" ) /* NULL */\n");
557     else
558         DEBUG(" ) -> n%d\n", idx);
559 }
560 
561 static void
incNodeIdx(void)562 incNodeIdx(void) {
563     xmlNodePtr oldNode;
564     int idx;
565 
566     idx = vars->nodeIdx & REG_MASK;
567     vars->nodeIdx = (idx + 1) & REG_MASK;
568     oldNode = vars->nodes[idx];
569 
570     if (oldNode != NULL) {
571         vars->nodes[idx] = NULL;
572         dropNode(oldNode);
573     }
574 }
575 
576 static int
isValidChildType(xmlNodePtr parent,int childType)577 isValidChildType(xmlNodePtr parent, int childType) {
578     return ((1 << childType) & childMasks[parent->type]) != 0;
579 }
580 
581 static int
isValidChild(xmlNodePtr parent,xmlNodePtr child)582 isValidChild(xmlNodePtr parent, xmlNodePtr child) {
583     xmlNodePtr cur;
584 
585     if (child == NULL || parent == NULL)
586         return 1;
587 
588     if (parent == child)
589         return 0;
590 
591     if (((1 << child->type) & childMasks[parent->type]) == 0)
592         return 0;
593 
594     if (child->children == NULL)
595         return 1;
596 
597     for (cur = parent->parent; cur != NULL; cur = cur->parent)
598         if (cur == child)
599             return 0;
600 
601     return 1;
602 }
603 
604 static int
isTextContentNode(xmlNodePtr child)605 isTextContentNode(xmlNodePtr child) {
606     if (child == NULL)
607         return 0;
608 
609     return ((1 << child->type) & NODE_MASK_TEXT_CONTENT) != 0;
610 }
611 
612 static int
isDtdChild(xmlNodePtr child)613 isDtdChild(xmlNodePtr child) {
614     if (child == NULL)
615         return 0;
616 
617     return ((1 << child->type) & CHILD_MASK_DTD) != 0;
618 }
619 
620 static xmlNodePtr
nodeGetTree(xmlNodePtr node)621 nodeGetTree(xmlNodePtr node) {
622     xmlNodePtr cur = node;
623 
624     while (cur->parent)
625         cur = cur->parent;
626     return cur;
627 }
628 
629 /*
630  * This function is called whenever a reference to a node is removed.
631  * It checks whether the node is still reachable and frees unreferenced
632  * nodes.
633  *
634  * A node is reachable if its tree, identified by the root node,
635  * is reachable. If a non-document tree is unreachable, it can be
636  * freed.
637  *
638  * Multiple trees can share the same document, so a document tree
639  * can only be freed if no other trees reference the document.
640  */
641 static void
dropNode(xmlNodePtr node)642 dropNode(xmlNodePtr node) {
643     xmlNodePtr *nodes = vars->nodes;
644     xmlNodePtr tree;
645     xmlDocPtr doc;
646     int docReferenced = 0;
647     int i;
648 
649     if (node == NULL)
650         return;
651 
652     tree = nodeGetTree(node);
653     doc = node->doc;
654 
655     for (i = 0; i < REG_MAX; i++) {
656         xmlNodePtr other;
657 
658         other = nodes[i];
659         if (other == NULL)
660             continue;
661 
662         /*
663          * Return if tree is referenced from another node
664          */
665         if (nodeGetTree(other) == tree)
666             return;
667         if (doc != NULL && other->doc == doc)
668             docReferenced = 1;
669     }
670 
671     if (tree != (xmlNodePtr) doc && !isDtdChild(tree)) {
672         if (doc == NULL || tree->type != XML_DTD_NODE ||
673             ((xmlDtdPtr) tree != doc->intSubset &&
674              (xmlDtdPtr) tree != doc->extSubset))
675             xmlFreeNode(tree);
676     }
677 
678     /*
679      * Also free document if it isn't referenced from other nodes
680      */
681     if (doc != NULL && !docReferenced)
682         xmlFreeDoc(doc);
683 }
684 
685 /*
686  * removeNode and removeChildren remove all references to a node
687  * or its children from the registers. These functions should be
688  * called if an API function destroys nodes, for example by merging
689  * text nodes.
690  */
691 
692 static void
removeNode(xmlNodePtr node)693 removeNode(xmlNodePtr node) {
694     int i;
695 
696     for (i = 0; i < REG_MAX; i++)
697         if (vars->nodes[i] == node)
698             vars->nodes[i] = NULL;
699 }
700 
701 static void
removeChildren(xmlNodePtr parent,int self)702 removeChildren(xmlNodePtr parent, int self) {
703     int i;
704 
705     if (parent == NULL || (!self && parent->children == NULL))
706         return;
707 
708     for (i = 0; i < REG_MAX; i++) {
709         xmlNodePtr node = vars->nodes[i];
710 
711         if (node == parent) {
712             if (self)
713                 vars->nodes[i] = NULL;
714             continue;
715         }
716 
717         while (node != NULL) {
718             node = node->parent;
719             if (node == parent) {
720                 vars->nodes[i] = NULL;
721                 break;
722             }
723         }
724     }
725 }
726 
727 static xmlNsPtr
nodeGetNs(xmlNodePtr node,int k)728 nodeGetNs(xmlNodePtr node, int k) {
729     int i = 0;
730     xmlNsPtr ns, next;
731 
732     if (node == NULL || node->type != XML_ELEMENT_NODE)
733         return NULL;
734 
735     ns = NULL;
736     next = node->nsDef;
737     while (1) {
738         while (next == NULL) {
739             node = node->parent;
740             if (node == NULL || node->type != XML_ELEMENT_NODE)
741                 break;
742             next = node->nsDef;
743         }
744 
745         if (next == NULL)
746             break;
747 
748         ns = next;
749         if (i == k)
750             break;
751 
752         next = ns->next;
753         i += 1;
754     }
755 
756     return ns;
757 }
758 
759 /*
760  * It's easy for programs to exhibit exponential growth patterns.
761  * For example, a tree being copied and added to the original source
762  * node doubles memory usage with two operations. Repeating these
763  * operations leads to 2^n nodes. Similar issues can arise when
764  * concatenating strings.
765  *
766  * We simply ignore tree copies or truncate text if they grow too
767  * large.
768  */
769 
770 static void
checkContent(xmlNodePtr node)771 checkContent(xmlNodePtr node) {
772     if (node != NULL &&
773         (node->type == XML_TEXT_NODE ||
774          node->type == XML_CDATA_SECTION_NODE ||
775          node->type == XML_ENTITY_NODE ||
776          node->type == XML_PI_NODE ||
777          node->type == XML_COMMENT_NODE ||
778          node->type == XML_NOTATION_NODE) &&
779         xmlStrlen(node->content) > MAX_CONTENT) {
780         xmlNodeSetContent(node, NULL);
781         node->content = uncheckedStrdup(BAD_CAST "");
782     }
783 }
784 
785 static int
countNodes(xmlNodePtr node)786 countNodes(xmlNodePtr node) {
787     xmlNodePtr cur;
788     int numNodes;
789 
790     if (node == NULL)
791         return 0;
792 
793     cur = node;
794     numNodes = 0;
795 
796     while (1) {
797         numNodes += 1;
798 
799         if (cur->children != NULL &&
800             cur->type != XML_ENTITY_REF_NODE) {
801             cur = cur->children;
802         } else {
803             while (cur->next == NULL) {
804                 if (cur == node)
805                     goto done;
806                 cur = cur->parent;
807             }
808             cur = cur->next;
809         }
810     }
811 
812 done:
813     return numNodes;
814 }
815 
816 static xmlNodePtr
checkCopy(xmlNodePtr copy)817 checkCopy(xmlNodePtr copy) {
818     vars->numCopyOps += 1;
819 
820     if (copy != NULL &&
821         (vars->numCopyOps > MAX_COPY_OPS ||
822          countNodes(copy) > MAX_COPY_NODES)) {
823         if (copy->type == XML_DOCUMENT_NODE ||
824             copy->type == XML_HTML_DOCUMENT_NODE)
825             xmlFreeDoc((xmlDocPtr) copy);
826         else
827             xmlFreeNode(copy);
828         copy = NULL;
829     }
830 
831     return copy;
832 }
833 
834 /*
835  * Fix namespaces, for example after unlinking a node. This makes
836  * sure that the node only references namespaces declared in ancestor
837  * nodes.
838  */
839 static int
fixNs(xmlNodePtr node)840 fixNs(xmlNodePtr node) {
841     if (node == NULL)
842         return 0;
843 
844     if (node->type == XML_ELEMENT_NODE) {
845         return xmlReconciliateNs(node->doc, node);
846     } else if (node->type == XML_ATTRIBUTE_NODE) {
847         xmlNodePtr parent = node->parent;
848 
849         if (parent != NULL)
850             return xmlReconciliateNs(parent->doc, parent);
851         else
852             node->ns = NULL;
853     }
854 
855     return 0;
856 }
857 
858 /* Node operations */
859 
860 static void
opNodeAccessor(int op)861 opNodeAccessor(int op) {
862     xmlNodePtr node;
863 
864     switch (op) {
865         case OP_NODE_PARENT:
866             startOp("parent"); break;
867         case OP_NODE_NEXT_SIBLING:
868             startOp("next"); break;
869         case OP_NODE_PREV_SIBLING:
870             startOp("prev"); break;
871         case OP_NODE_FIRST_CHILD:
872             startOp("children"); break;
873         case OP_XML_GET_LAST_CHILD:
874             startOp("xmlGetLastChild"); break;
875         case OP_XML_GET_INT_SUBSET:
876             startOp("xmlGetIntSubset"); break;
877         case OP_XML_DOC_GET_ROOT_ELEMENT:
878             startOp("xmlDocGetRootElement"); break;
879         default:
880             break;
881     }
882 
883     incNodeIdx();
884     node = getNode(1);
885 
886     if (node != NULL) {
887         switch (op) {
888             case OP_NODE_PARENT:
889                 node = node->parent; break;
890             case OP_NODE_NEXT_SIBLING:
891                 node = node->next; break;
892             case OP_NODE_PREV_SIBLING:
893                 node = node->prev; break;
894             case OP_NODE_FIRST_CHILD:
895                 node = node->children; break;
896             case OP_XML_GET_LAST_CHILD:
897                 node = xmlGetLastChild(node); break;
898             case OP_XML_GET_INT_SUBSET:
899                 node = (xmlNodePtr) xmlGetIntSubset(node->doc); break;
900             case OP_XML_DOC_GET_ROOT_ELEMENT:
901                 node = xmlDocGetRootElement(node->doc); break;
902             default:
903                 break;
904         }
905 
906         /*
907          * Don't descend into predefined entities
908          */
909         if (node != NULL && node->type == XML_ENTITY_DECL) {
910             xmlEntityPtr ent = (xmlEntityPtr) node;
911 
912             if (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)
913                 node = NULL;
914         }
915     }
916 
917     setNode(0, node);
918 }
919 
920 static void
opDup(int op)921 opDup(int op) {
922     int offset;
923 
924     switch (op) {
925         case OP_DUP_INTEGER:
926             incIntIdx(); break;
927         case OP_DUP_STRING:
928             incStrIdx(); break;
929         case OP_DUP_NODE:
930             incNodeIdx(); break;
931         default:
932             break;
933     }
934 
935     offset = (xmlFuzzReadInt(1) + 1) & REG_MASK;
936 
937     if (offset != 0) {
938         startOp("dup");
939         switch (op) {
940             case OP_DUP_INTEGER:
941                 setInt(0, getInt(offset));
942                 endOp();
943                 break;
944             case OP_DUP_STRING:
945                 copyStr(0, getStr(offset));
946                 endOp();
947                 break;
948             case OP_DUP_NODE:
949                 setNode(0, getNode(offset));
950                 break;
951             default:
952                 break;
953         }
954     }
955 }
956 
957 int
LLVMFuzzerInitialize(int * argc ATTRIBUTE_UNUSED,char *** argv ATTRIBUTE_UNUSED)958 LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
959                      char ***argv ATTRIBUTE_UNUSED) {
960     xmlFuzzMemSetup();
961     xmlInitParser();
962 #ifdef LIBXML_CATALOG_ENABLED
963     xmlInitializeCatalog();
964     xmlCatalogSetDefaults(XML_CATA_ALLOW_NONE);
965 #endif
966     xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc);
967 
968     return 0;
969 }
970 
971 int
LLVMFuzzerTestOneInput(const char * data,size_t size)972 LLVMFuzzerTestOneInput(const char *data, size_t size) {
973     size_t maxAlloc;
974     int i;
975 
976     if (size > 1000)
977         return 0;
978 
979     memset(vars, 0, sizeof(*vars));
980 
981     xmlFuzzDataInit(data, size);
982 
983     maxAlloc = xmlFuzzReadInt(4) % (size * 50 + 10);
984     xmlFuzzMemSetLimit(maxAlloc);
985 
986     /*
987      * Interpreter loop
988      *
989      * Processing an opcode typically involves
990      *
991      * - startOp for debugging
992      * - increase output register index if non-void
993      * - get arguments from input registers
994      * - invoke API function
995      * - set oomReport
996      * - set output register
997      * - memory management and other adjustments
998      * - endOp for void functions
999      */
1000 
1001     while (xmlFuzzBytesRemaining()) {
1002         size_t readSize;
1003         int op = xmlFuzzReadInt(1);
1004         int oomReport = -1; /* -1 means unknown */
1005 
1006         vars->opName = "[unset]";
1007 
1008         switch (op) {
1009             case OP_CREATE_INTEGER:
1010                 incIntIdx();
1011                 setInt(0, (int) xmlFuzzReadInt(4));
1012                 break;
1013 
1014             case OP_CREATE_STRING:
1015                 incStrIdx();
1016                 copyStr(0, BAD_CAST xmlFuzzReadString(&readSize));
1017                 break;
1018 
1019             case OP_DUP_INTEGER:
1020             case OP_DUP_STRING:
1021             case OP_DUP_NODE:
1022                 opDup(op);
1023                 break;
1024 
1025             case OP_PARSE_DOCUMENT:
1026                 /*
1027                  * We don't really want to test the parser but exposing
1028                  * xmlReadDoc seems like a useful way generate or
1029                  * round-trip documents.
1030                  *
1031                  * This also creates documents with a dictionary which
1032                  * is crucial to hit some code paths.
1033                  */
1034                 startOp("xmlReadDoc");
1035                 incNodeIdx();
1036                 setNode(0, (xmlNodePtr) xmlReadDoc(
1037                     getStr(0),
1038                     getCStr(1),
1039                     getCStr(2),
1040                     getInt(0)));
1041                 break;
1042 
1043             case OP_XML_NEW_DOC: {
1044                 xmlDocPtr doc;
1045 
1046                 /*
1047                  * TODO: There's no public API function to generate a
1048                  * document with a dictionary. We should add an extra
1049                  * opcode that sets doc->dict.
1050                  */
1051                 startOp("xmlNewDoc");
1052                 incNodeIdx();
1053                 doc = xmlNewDoc(getStr(0));
1054                 oomReport = (doc == NULL);
1055                 setNode(0, (xmlNodePtr) doc);
1056                 break;
1057             }
1058 
1059             case OP_XML_NEW_NODE: {
1060                 xmlNodePtr node;
1061                 const xmlChar *name;
1062 
1063                 startOp("xmlNewNode");
1064                 incNodeIdx();
1065                 node = xmlNewNode(
1066                     nodeGetNs(getNode(1), getInt(0)),
1067                     name = getStr(0));
1068                 oomReport = (name != NULL && node == NULL);
1069                 if (fixNs(node) < 0)
1070                     oomReport = 1;
1071                 setNode(0, node);
1072                 break;
1073             }
1074 
1075             case OP_XML_NEW_NODE_EAT_NAME: {
1076                 xmlNodePtr node;
1077                 xmlChar *name;
1078 
1079                 startOp("xmlNewNodeEatName");
1080                 incNodeIdx();
1081                 node = xmlNewNodeEatName(
1082                     nodeGetNs(getNode(1), getInt(0)),
1083                     name = uncheckedStrdup(getStr(0)));
1084                 oomReport = (name != NULL && node == NULL);
1085                 if (fixNs(node) < 0)
1086                     oomReport = 1;
1087                 setNode(0, node);
1088                 break;
1089             }
1090 
1091             case OP_XML_NEW_DOC_NODE: {
1092                 xmlNodePtr node;
1093                 const xmlChar *name;
1094 
1095                 startOp("xmlNewDocNode");
1096                 incNodeIdx();
1097                 node = xmlNewDocNode(
1098                     getDoc(1),
1099                     nodeGetNs(getNode(2), getInt(0)),
1100                     name = getStr(0),
1101                     getStr(1));
1102                 oomReport = (name != NULL && node == NULL);
1103                 if (fixNs(node) < 0)
1104                     oomReport = 1;
1105                 setNode(0, node);
1106                 break;
1107             }
1108 
1109             case OP_XML_NEW_DOC_NODE_EAT_NAME: {
1110                 xmlNodePtr node;
1111                 xmlChar *name;
1112 
1113                 startOp("xmlNewDocNodeEatName");
1114                 incNodeIdx();
1115                 node = xmlNewDocNodeEatName(
1116                     getDoc(1),
1117                     nodeGetNs(getNode(2), getInt(0)),
1118                     name = uncheckedStrdup(getStr(0)),
1119                     getStr(1));
1120                 oomReport = (name != NULL && node == NULL);
1121                 if (fixNs(node) < 0)
1122                     oomReport = 1;
1123                 setNode(0, node);
1124                 break;
1125             }
1126 
1127             case OP_XML_NEW_DOC_RAW_NODE: {
1128                 xmlNodePtr node;
1129                 const xmlChar *name;
1130 
1131                 startOp("xmlNewDocRawNode");
1132                 incNodeIdx();
1133                 node = xmlNewDocRawNode(
1134                     getDoc(1),
1135                     nodeGetNs(getNode(2), getInt(0)),
1136                     name = getStr(0),
1137                     getStr(1));
1138                 oomReport = (name != NULL && node == NULL);
1139                 if (fixNs(node) < 0)
1140                     oomReport = 1;
1141                 setNode(0, node);
1142                 break;
1143             }
1144 
1145             case OP_XML_NEW_CHILD: {
1146                 xmlNodePtr parent, node;
1147                 const xmlChar *name;
1148 
1149                 startOp("xmlNewChild");
1150                 incNodeIdx();
1151                 /* Use parent namespace without fixup */
1152                 node = xmlNewChild(
1153                     parent = getNode(1),
1154                     nodeGetNs(getNode(1), getInt(0)),
1155                     name = getStr(0),
1156                     getStr(1));
1157                 oomReport =
1158                     (parent != NULL &&
1159                      isValidChildType(parent, XML_ELEMENT_NODE) &&
1160                      name != NULL &&
1161                      node == NULL);
1162                 setNode(0, node);
1163                 break;
1164             }
1165 
1166             case OP_XML_NEW_TEXT_CHILD: {
1167                 xmlNodePtr parent, node;
1168                 const xmlChar *name;
1169 
1170                 startOp("xmlNewTextChild");
1171                 incNodeIdx();
1172                 /* Use parent namespace without fixup */
1173                 node = xmlNewTextChild(
1174                     parent = getNode(1),
1175                     nodeGetNs(getNode(1), getInt(0)),
1176                     name = getStr(0),
1177                     getStr(1));
1178                 oomReport =
1179                     (parent != NULL &&
1180                      isValidChildType(parent, XML_ELEMENT_NODE) &&
1181                      name != NULL &&
1182                      node == NULL);
1183                 setNode(0, node);
1184                 break;
1185             }
1186 
1187             case OP_XML_NEW_PROP: {
1188                 xmlNodePtr parent;
1189                 xmlAttrPtr attr;
1190                 const xmlChar *name;
1191 
1192                 startOp("xmlNewProp");
1193                 incNodeIdx();
1194                 attr = xmlNewProp(
1195                     parent = getNode(1),
1196                     name = getStr(0),
1197                     getStr(1));
1198                 oomReport =
1199                     ((parent == NULL || parent->type == XML_ELEMENT_NODE) &&
1200                      name != NULL &&
1201                      attr == NULL);
1202                 setNode(0, (xmlNodePtr) attr);
1203                 break;
1204             }
1205 
1206             case OP_XML_NEW_DOC_PROP: {
1207                 xmlAttrPtr attr;
1208                 const xmlChar *name;
1209 
1210                 startOp("xmlNewDocProp");
1211                 incNodeIdx();
1212                 attr = xmlNewDocProp(
1213                     getDoc(1),
1214                     name = getStr(0),
1215                     getStr(1));
1216                 oomReport = (name != NULL && attr == NULL);
1217                 setNode(0, (xmlNodePtr) attr);
1218                 break;
1219             }
1220 
1221             case OP_XML_NEW_NS_PROP: {
1222                 xmlAttrPtr attr;
1223 
1224                 startOp("xmlNewNsProp");
1225                 incNodeIdx();
1226                 attr = xmlNewNsProp(
1227                     getNode(1),
1228                     nodeGetNs(getNode(1), getInt(0)),
1229                     getStr(0),
1230                     getStr(1));
1231                 /* xmlNewNsProp returns NULL on duplicate prefixes. */
1232                 if (attr != NULL)
1233                     oomReport = 0;
1234                 setNode(0, (xmlNodePtr) attr);
1235                 break;
1236             }
1237 
1238             case OP_XML_NEW_NS_PROP_EAT_NAME: {
1239                 xmlAttrPtr attr;
1240 
1241                 startOp("xmlNewNsPropEatName");
1242                 incNodeIdx();
1243                 attr = xmlNewNsPropEatName(
1244                     getNode(1),
1245                     nodeGetNs(getNode(1), getInt(0)),
1246                     uncheckedStrdup(getStr(0)),
1247                     getStr(1));
1248                 if (attr != NULL)
1249                     oomReport = 0;
1250                 setNode(0, (xmlNodePtr) attr);
1251                 break;
1252             }
1253 
1254             case OP_XML_NEW_TEXT: {
1255                 xmlNodePtr node;
1256 
1257                 startOp("xmlNewText");
1258                 incNodeIdx();
1259                 node = xmlNewText(getStr(0));
1260                 oomReport = (node == NULL);
1261                 setNode(0, node);
1262                 break;
1263             }
1264 
1265             case OP_XML_NEW_TEXT_LEN: {
1266                 xmlNodePtr node;
1267                 const xmlChar *text;
1268 
1269                 startOp("xmlNewTextLen");
1270                 incNodeIdx();
1271                 text = getStr(0);
1272                 node = xmlNewTextLen(text, xmlStrlen(text));
1273                 oomReport = (node == NULL);
1274                 setNode(0, node);
1275                 break;
1276             }
1277 
1278             case OP_XML_NEW_DOC_TEXT: {
1279                 xmlNodePtr node;
1280 
1281                 startOp("xmlNewDocText");
1282                 incNodeIdx();
1283                 node = xmlNewDocText(getDoc(1), getStr(0));
1284                 oomReport = (node == NULL);
1285                 setNode(0, node);
1286                 break;
1287             }
1288 
1289             case OP_XML_NEW_DOC_TEXT_LEN: {
1290                 xmlDocPtr doc;
1291                 xmlNodePtr node;
1292                 const xmlChar *text;
1293 
1294                 startOp("xmlNewDocTextLen");
1295                 incNodeIdx();
1296                 doc = getDoc(1);
1297                 text = getStr(0);
1298                 node = xmlNewDocTextLen(doc, text, xmlStrlen(text));
1299                 oomReport = (node == NULL);
1300                 setNode(0, node);
1301                 break;
1302             }
1303 
1304             case OP_XML_NEW_PI: {
1305                 xmlNodePtr node;
1306                 const xmlChar *name;
1307 
1308                 startOp("xmlNewPI");
1309                 incNodeIdx();
1310                 node = xmlNewPI(
1311                     name = getStr(0),
1312                     getStr(1));
1313                 oomReport = (name != NULL && node == NULL);
1314                 setNode(0, node);
1315                 break;
1316             }
1317 
1318             case OP_XML_NEW_DOC_PI: {
1319                 xmlNodePtr node;
1320                 const xmlChar *name;
1321 
1322                 startOp("xmlNewDocPI");
1323                 incNodeIdx();
1324                 node = xmlNewDocPI(
1325                     getDoc(1),
1326                     name = getStr(0),
1327                     getStr(1));
1328                 oomReport = (name != NULL && node == NULL);
1329                 setNode(0, node);
1330                 break;
1331             }
1332 
1333             case OP_XML_NEW_COMMENT: {
1334                 xmlNodePtr node;
1335 
1336                 startOp("xmlNewComment");
1337                 incNodeIdx();
1338                 node = xmlNewComment(getStr(0));
1339                 oomReport = (node == NULL);
1340                 setNode(0, node);
1341                 break;
1342             }
1343 
1344             case OP_XML_NEW_DOC_COMMENT: {
1345                 xmlNodePtr node;
1346 
1347                 startOp("xmlNewDocComment");
1348                 incNodeIdx();
1349                 node = xmlNewDocComment(
1350                     getDoc(1),
1351                     getStr(0));
1352                 oomReport = (node == NULL);
1353                 setNode(0, node);
1354                 break;
1355             }
1356 
1357             case OP_XML_NEW_CDATA_BLOCK: {
1358                 xmlDocPtr doc;
1359                 xmlNodePtr node;
1360                 const xmlChar *text;
1361 
1362                 startOp("xmlNewCDataBlock");
1363                 incNodeIdx();
1364                 doc = getDoc(1);
1365                 text = getStr(0);
1366                 node = xmlNewDocTextLen(
1367                     doc,
1368                     text,
1369                     xmlStrlen(text));
1370                 oomReport = (node == NULL);
1371                 setNode(0, node);
1372                 break;
1373             }
1374 
1375             case OP_XML_NEW_CHAR_REF: {
1376                 xmlNodePtr node;
1377                 const xmlChar *name;
1378 
1379                 startOp("xmlNewCharRef");
1380                 incNodeIdx();
1381                 node = xmlNewCharRef(
1382                     getDoc(1),
1383                     name = getStr(0));
1384                 oomReport = (name != NULL && node == NULL);
1385                 setNode(0, node);
1386                 break;
1387             }
1388 
1389             case OP_XML_NEW_REFERENCE: {
1390                 xmlNodePtr node;
1391                 const xmlChar *name;
1392 
1393                 startOp("xmlNewReference");
1394                 incNodeIdx();
1395                 node = xmlNewReference(
1396                     getDoc(1),
1397                     name = getStr(0));
1398                 oomReport = (name != NULL && node == NULL);
1399                 setNode(0, node);
1400                 break;
1401             }
1402 
1403             case OP_XML_NEW_DOC_FRAGMENT: {
1404                 xmlNodePtr node;
1405 
1406                 startOp("xmlNewDocFragment");
1407                 incNodeIdx();
1408                 node = xmlNewDocFragment(getDoc(1));
1409                 oomReport = (node == NULL);
1410                 setNode(0, node);
1411                 break;
1412             }
1413 
1414             case OP_XML_CREATE_INT_SUBSET: {
1415                 xmlDocPtr doc;
1416                 xmlDtdPtr dtd = NULL;
1417 
1418                 startOp("xmlCreateIntSubset");
1419                 incNodeIdx();
1420                 doc = getDoc(1);
1421                 if (doc == NULL || doc->intSubset == NULL) {
1422                     dtd = xmlCreateIntSubset(
1423                         doc,
1424                         getStr(0),
1425                         getStr(1),
1426                         getStr(2));
1427                     oomReport = (dtd == NULL);
1428                 }
1429                 setNode(0, (xmlNodePtr) dtd);
1430                 break;
1431             }
1432 
1433             case OP_XML_NEW_DTD: {
1434                 xmlDocPtr doc;
1435                 xmlDtdPtr dtd = NULL;
1436 
1437                 startOp("xmlNewDtd");
1438                 incNodeIdx();
1439                 doc = getDoc(1);
1440                 if (doc == NULL || doc->extSubset == NULL) {
1441                     dtd = xmlNewDtd(
1442                         doc,
1443                         getStr(0),
1444                         getStr(1),
1445                         getStr(2));
1446                     oomReport = (dtd == NULL);
1447                 }
1448                 setNode(0, (xmlNodePtr) dtd);
1449                 break;
1450             }
1451 
1452             case OP_XML_COPY_DOC: {
1453                 xmlDocPtr copy;
1454 
1455                 startOp("xmlCopyDoc");
1456                 incNodeIdx();
1457                 copy = xmlCopyDoc(
1458                     getDoc(1),
1459                     getInt(0));
1460                 /*
1461                  * TODO: Copying DTD nodes without a document can
1462                  * result in an empty list.
1463                  */
1464                 if (copy != NULL)
1465                     oomReport = 0;
1466                 setNode(0, checkCopy((xmlNodePtr) copy));
1467                 break;
1468             }
1469 
1470             case OP_XML_COPY_NODE: {
1471                 xmlNodePtr copy;
1472 
1473                 startOp("xmlCopyNode");
1474                 incNodeIdx();
1475                 copy = xmlCopyNode(
1476                     getNode(1),
1477                     getInt(0));
1478                 if (copy != NULL)
1479                     oomReport = 0;
1480                 setNode(0, checkCopy((xmlNodePtr) copy));
1481                 break;
1482             }
1483 
1484             case OP_XML_COPY_NODE_LIST: {
1485                 xmlNodePtr copy;
1486 
1487                 startOp("xmlCopyNodeList");
1488                 copy = xmlCopyNodeList(getNode(0));
1489                 if (copy != NULL)
1490                     oomReport = 0;
1491                 xmlFreeNodeList(copy);
1492                 endOp();
1493                 break;
1494             }
1495 
1496             case OP_XML_DOC_COPY_NODE: {
1497                 xmlNodePtr node, copy;
1498                 xmlDocPtr doc;
1499 
1500                 startOp("xmlDocCopyNode");
1501                 incNodeIdx();
1502                 copy = xmlDocCopyNode(
1503                     node = getNode(1),
1504                     doc = getDoc(2),
1505                     getInt(0));
1506                 if (copy != NULL)
1507                     oomReport = 0;
1508                 setNode(0, checkCopy((xmlNodePtr) copy));
1509                 break;
1510             }
1511 
1512             case OP_XML_DOC_COPY_NODE_LIST: {
1513                 xmlNodePtr copy;
1514 
1515                 startOp("xmlDocCopyNodeList");
1516                 copy = xmlDocCopyNodeList(
1517                     getDoc(0),
1518                     getNode(1));
1519                 if (copy != NULL)
1520                     oomReport = 0;
1521                 xmlFreeNodeList(copy);
1522                 endOp();
1523                 break;
1524             }
1525 
1526             case OP_XML_COPY_PROP: {
1527                 xmlAttrPtr copy;
1528 
1529                 startOp("xmlCopyProp");
1530                 incNodeIdx();
1531                 copy = xmlCopyProp(
1532                     getNode(1),
1533                     getAttr(2));
1534                 /*
1535                  * TODO: Copying attributes can result in an empty list
1536                  * if there's a duplicate namespace prefix.
1537                  */
1538                 if (copy != NULL)
1539                     oomReport = 0;
1540                 if (copy != NULL) {
1541                     /* Quirk */
1542                     copy->parent = NULL;
1543                     /* Fix namespace */
1544                     copy->ns = NULL;
1545                 }
1546                 setNode(0, checkCopy((xmlNodePtr) copy));
1547                 break;
1548             }
1549 
1550             case OP_XML_COPY_PROP_LIST: {
1551                 xmlAttrPtr copy;
1552 
1553                 startOp("xmlCopyPropList");
1554                 copy = xmlCopyPropList(
1555                     getNode(0),
1556                     getAttr(1));
1557                 if (copy != NULL)
1558                     oomReport = 0;
1559                 xmlFreePropList(copy);
1560                 endOp();
1561                 break;
1562             }
1563 
1564             case OP_XML_COPY_DTD: {
1565                 xmlDtdPtr dtd, copy;
1566 
1567                 startOp("xmlCopyDtd");
1568                 incNodeIdx();
1569                 copy = xmlCopyDtd(
1570                     dtd = getDtd(1));
1571                 oomReport = (dtd != NULL && copy == NULL);
1572                 setNode(0, checkCopy((xmlNodePtr) copy));
1573                 break;
1574             }
1575 
1576             case OP_NODE_PARENT:
1577             case OP_NODE_NEXT_SIBLING:
1578             case OP_NODE_PREV_SIBLING:
1579             case OP_NODE_FIRST_CHILD:
1580             case OP_XML_GET_LAST_CHILD:
1581             case OP_XML_GET_INT_SUBSET:
1582             case OP_XML_DOC_GET_ROOT_ELEMENT:
1583                 opNodeAccessor(op);
1584                 oomReport = 0;
1585                 break;
1586 
1587             case OP_NODE_NAME: {
1588                 xmlNodePtr node;
1589 
1590                 startOp("name");
1591                 incStrIdx();
1592                 node = getNode(0);
1593                 copyStr(0, node ? node->name : NULL);
1594                 oomReport = 0;
1595                 endOp();
1596                 break;
1597             }
1598 
1599             case OP_XML_NODE_SET_NAME:
1600                 startOp("xmlNodeSetName");
1601                 xmlNodeSetName(
1602                     getNode(0),
1603                     getStr(0));
1604                 endOp();
1605                 break;
1606 
1607             case OP_XML_NODE_GET_CONTENT: {
1608                 xmlChar *content;
1609 
1610                 incStrIdx();
1611                 startOp("xmlNodeGetContent");
1612                 content = xmlNodeGetContent(getNode(0));
1613                 if (content != NULL)
1614                     oomReport = 0;
1615                 moveStr(0, content);
1616                 endOp();
1617                 break;
1618             }
1619 
1620             case OP_XML_NODE_SET_CONTENT: {
1621                 xmlNodePtr node;
1622                 int res;
1623 
1624                 startOp("xmlNodeSetContent");
1625                 node = getNode(0);
1626                 removeChildren(node, 0);
1627                 res = xmlNodeSetContent(
1628                     node,
1629                     getStr(0));
1630                 oomReport = (res < 0);
1631                 endOp();
1632                 break;
1633             }
1634 
1635             case OP_XML_NODE_SET_CONTENT_LEN: {
1636                 xmlNodePtr node;
1637                 const xmlChar *content;
1638                 int res;
1639 
1640                 startOp("xmlNodeSetContentLen");
1641                 node = getNode(0);
1642                 content = getStr(0);
1643                 removeChildren(node, 0);
1644                 res = xmlNodeSetContentLen(
1645                     node,
1646                     content,
1647                     xmlStrlen(content));
1648                 oomReport = (res < 0);
1649                 endOp();
1650                 break;
1651             }
1652 
1653             case OP_XML_NODE_ADD_CONTENT: {
1654                 xmlNodePtr node, text;
1655                 int res;
1656 
1657                 startOp("xmlNodeAddContent");
1658                 node = getNode(0);
1659                 res = xmlNodeAddContent(
1660                     node,
1661                     getStr(0));
1662                 oomReport = (res < 0);
1663                 if (node != NULL) {
1664                     if (node->type == XML_ELEMENT_NODE ||
1665                         node->type == XML_DOCUMENT_FRAG_NODE)
1666                         text = node->last;
1667                     else
1668                         text = node;
1669                     checkContent(text);
1670                 }
1671                 endOp();
1672                 break;
1673             }
1674 
1675             case OP_XML_NODE_ADD_CONTENT_LEN: {
1676                 xmlNodePtr node, text;
1677                 const xmlChar *content;
1678                 int res;
1679 
1680                 startOp("xmlNodeAddContentLen");
1681                 node = getNode(0);
1682                 content = getStr(0);
1683                 res = xmlNodeAddContentLen(
1684                     node,
1685                     content,
1686                     xmlStrlen(content));
1687                 oomReport = res < 0;
1688                 if (node != NULL) {
1689                     if (node->type == XML_ELEMENT_NODE ||
1690                         node->type == XML_DOCUMENT_FRAG_NODE)
1691                         text = node->last;
1692                     else
1693                         text = node;
1694                     checkContent(text);
1695                 }
1696                 endOp();
1697                 break;
1698             }
1699 
1700             case OP_XML_GET_LINE_NO:
1701                 incIntIdx();
1702                 startOp("xmlGetLineNo");
1703                 setInt(0, xmlGetLineNo(getNode(0)));
1704                 oomReport = 0;
1705                 endOp();
1706                 break;
1707 
1708             case OP_XML_GET_NODE_PATH: {
1709                 xmlChar *path;
1710 
1711                 incStrIdx();
1712                 startOp("xmlGetNodePath");
1713                 path = xmlGetNodePath(getNode(0));
1714                 if (path != NULL)
1715                     oomReport = 0;
1716                 moveStr(0, path);
1717                 endOp();
1718                 break;
1719             }
1720 
1721             case OP_XML_DOC_SET_ROOT_ELEMENT: {
1722                 xmlDocPtr oldDoc, doc;
1723                 xmlNodePtr oldRoot, oldParent, root;
1724 
1725                 startOp("xmlDocSetRootElement");
1726                 incNodeIdx();
1727                 doc = getDoc(1);
1728                 root = getNode(2);
1729                 if (doc != NULL && doc->parent != NULL)
1730                     doc = NULL;
1731                 if (!isValidChild((xmlNodePtr) doc, root))
1732                     root = NULL;
1733                 oldDoc = root ? root->doc : NULL;
1734                 oldParent = root ? root->parent : NULL;
1735 
1736                 oldRoot = xmlDocSetRootElement(doc, root);
1737                 /* We can't really know whether xmlSetTreeDoc failed */
1738                 if (oldRoot != NULL ||
1739                     root == NULL ||
1740                     root->doc == oldDoc)
1741                     oomReport = 0;
1742                 setNode(0, oldRoot);
1743 
1744                 if (root &&
1745                     (root->parent != oldParent ||
1746                      root->doc != oldDoc)) {
1747                     if (fixNs(root) < 0)
1748                         oomReport = 1;
1749                     if (oldParent != NULL)
1750                         dropNode(oldParent);
1751                     else
1752                         dropNode((xmlNodePtr) oldDoc);
1753                 }
1754                 endOp();
1755                 break;
1756             }
1757 
1758             case OP_XML_NODE_IS_TEXT:
1759                 incIntIdx();
1760                 startOp("xmlNodeIsText");
1761                 setInt(0, xmlNodeIsText(getNode(0)));
1762                 oomReport = 0;
1763                 endOp();
1764                 break;
1765 
1766             case OP_XML_NODE_GET_ATTR_VALUE: {
1767                 xmlChar *value = NULL;
1768                 int res;
1769 
1770                 incStrIdx();
1771                 startOp("xmlNodeGetAttrValue");
1772                 res = xmlNodeGetAttrValue(
1773                     getNode(0),
1774                     getStr(1),
1775                     getStr(2),
1776                     &value);
1777                 oomReport = (res < 0);
1778                 moveStr(0, value);
1779                 endOp();
1780                 break;
1781             }
1782 
1783             case OP_XML_NODE_GET_LANG: {
1784                 xmlChar *lang;
1785 
1786                 incStrIdx();
1787                 startOp("xmlNodeGetLang");
1788                 lang = xmlNodeGetLang(getNode(0));
1789                 if (lang != NULL)
1790                     oomReport = 0;
1791                 moveStr(0, lang);
1792                 endOp();
1793                 break;
1794             }
1795 
1796             case OP_XML_NODE_SET_LANG: {
1797                 xmlNodePtr node;
1798                 xmlAttrPtr attr;
1799                 int res;
1800 
1801                 startOp("xmlNodeSetLang");
1802                 node = getNode(0);
1803                 attr = xmlHasNsProp(
1804                     node,
1805                     BAD_CAST "lang",
1806                     XML_XML_NAMESPACE);
1807                 xmlFuzzResetMallocFailed();
1808                 removeChildren((xmlNodePtr) attr, 0);
1809                 res = xmlNodeSetLang(
1810                     node,
1811                     getStr(0));
1812                 oomReport = (res < 0);
1813                 endOp();
1814                 break;
1815             }
1816 
1817             case OP_XML_NODE_GET_SPACE_PRESERVE: {
1818                 int res;
1819 
1820                 incIntIdx();
1821                 startOp("xmlNodeGetSpacePreserve");
1822                 res = xmlNodeGetSpacePreserve(getNode(0));
1823                 if (res >= 0)
1824                     oomReport = 0;
1825                 setInt(0, res);
1826                 endOp();
1827                 break;
1828             }
1829 
1830             case OP_XML_NODE_SET_SPACE_PRESERVE: {
1831                 xmlNodePtr node;
1832                 xmlAttrPtr attr;
1833                 int res;
1834 
1835                 startOp("xmlNodeSetSpacePreserve");
1836                 node = getNode(0);
1837                 attr = xmlHasNsProp(
1838                     node,
1839                     BAD_CAST "space",
1840                     XML_XML_NAMESPACE);
1841                 xmlFuzzResetMallocFailed();
1842                 removeChildren((xmlNodePtr) attr, 0);
1843                 res = xmlNodeSetSpacePreserve(
1844                     node,
1845                     getInt(0));
1846                 oomReport = (res < 0);
1847                 endOp();
1848                 break;
1849             }
1850 
1851             case OP_XML_NODE_GET_BASE: {
1852                 xmlChar *base;
1853 
1854                 incStrIdx();
1855                 startOp("xmlNodeGetBase");
1856                 base = xmlNodeGetBase(
1857                     getDoc(0),
1858                     getNode(1));
1859                 if (base != NULL)
1860                     oomReport = 0;
1861                 moveStr(0, base);
1862                 endOp();
1863                 break;
1864             }
1865 
1866             case OP_XML_NODE_GET_BASE_SAFE: {
1867                 xmlChar *base;
1868                 int res;
1869 
1870                 startOp("xmlNodeGetBaseSafe");
1871                 incStrIdx();
1872                 res = xmlNodeGetBaseSafe(
1873                     getDoc(0),
1874                     getNode(1),
1875                     &base);
1876                 oomReport = (res < 0);
1877                 moveStr(0, base);
1878                 endOp();
1879                 break;
1880             }
1881 
1882             case OP_XML_NODE_SET_BASE: {
1883                 xmlNodePtr node;
1884                 xmlAttrPtr attr;
1885                 int res;
1886 
1887                 startOp("xmlNodeSetBase");
1888                 node = getNode(0);
1889                 attr = xmlHasNsProp(
1890                     node,
1891                     BAD_CAST "base",
1892                     XML_XML_NAMESPACE);
1893                 xmlFuzzResetMallocFailed();
1894                 removeChildren((xmlNodePtr) attr, 0);
1895                 res = xmlNodeSetBase(
1896                     node,
1897                     getStr(0));
1898                 if (res == 0)
1899                     oomReport = 0;
1900                 endOp();
1901                 break;
1902             }
1903 
1904             case OP_XML_IS_BLANK_NODE:
1905                 startOp("xmlIsBlankNode");
1906                 incNodeIdx();
1907                 setInt(0, xmlIsBlankNode(getNode(0)));
1908                 oomReport = 0;
1909                 break;
1910 
1911             case OP_XML_HAS_PROP: {
1912                 xmlNodePtr node;
1913                 xmlAttrPtr attr;
1914 
1915                 startOp("xmlHasProp");
1916                 incNodeIdx();
1917                 attr = xmlHasProp(
1918                     node = getNode(1),
1919                     getStr(0));
1920                 if (node != NULL &&
1921                     node->doc != NULL &&
1922                     node->doc->intSubset != NULL) {
1923                     /*
1924                      * xmlHasProp tries to look up default attributes,
1925                      * requiring a memory allocation which isn't
1926                      * checked.
1927                      */
1928                     if (attr != NULL)
1929                         oomReport = 0;
1930                 } else {
1931                     oomReport = 0;
1932                 }
1933                 setNode(0, (xmlNodePtr) attr);
1934                 break;
1935             }
1936 
1937             case OP_XML_HAS_NS_PROP: {
1938                 xmlNodePtr node;
1939                 xmlAttrPtr attr;
1940 
1941                 startOp("xmlHasNsProp");
1942                 incNodeIdx();
1943                 attr = xmlHasNsProp(
1944                     node = getNode(1),
1945                     getStr(0),
1946                     getStr(1));
1947                 if (node != NULL &&
1948                     node->doc != NULL &&
1949                     node->doc->intSubset != NULL) {
1950                     if (attr != NULL)
1951                         oomReport = 0;
1952                 } else {
1953                     oomReport = 0;
1954                 }
1955                 setNode(0, (xmlNodePtr) attr);
1956                 break;
1957             }
1958 
1959             case OP_XML_GET_PROP: {
1960                 xmlChar *content;
1961 
1962                 startOp("xmlGetProp");
1963                 incStrIdx();
1964                 content = xmlGetProp(
1965                     getNode(0),
1966                     getStr(1));
1967                 if (content != NULL)
1968                     oomReport = 0;
1969                 moveStr(0, content);
1970                 endOp();
1971                 break;
1972             }
1973 
1974             case OP_XML_GET_NS_PROP: {
1975                 xmlChar *content;
1976 
1977                 startOp("xmlGetNsProp");
1978                 incStrIdx();
1979                 content = xmlGetNsProp(
1980                     getNode(0),
1981                     getStr(1),
1982                     getStr(2));
1983                 if (content != NULL)
1984                     oomReport = 0;
1985                 moveStr(0, content);
1986                 endOp();
1987                 break;
1988             }
1989 
1990             case OP_XML_GET_NO_NS_PROP: {
1991                 xmlChar *content;
1992 
1993                 startOp("xmlGetNoNsProp");
1994                 incStrIdx();
1995                 content = xmlGetNoNsProp(
1996                     getNode(0),
1997                     getStr(1));
1998                 if (content != NULL)
1999                     oomReport = 0;
2000                 moveStr(0, content);
2001                 endOp();
2002                 break;
2003             }
2004 
2005             case OP_XML_SET_PROP: {
2006                 xmlNodePtr node;
2007                 xmlAttrPtr oldAttr, attr;
2008                 xmlNsPtr ns = NULL;
2009                 const xmlChar *name, *value, *localName;
2010                 xmlChar *prefix;
2011                 int prefixLen;
2012 
2013                 startOp("xmlSetProp");
2014                 incNodeIdx();
2015                 node = getNode(1);
2016                 name = getStr(0);
2017                 value = getStr(1);
2018 
2019                 /*
2020                  * Find the old attribute node which will be deleted.
2021                  */
2022                 localName = xmlSplitQName3(name, &prefixLen);
2023                 if (localName != NULL) {
2024                     prefix = uncheckedStrndup(name, prefixLen);
2025                     ns = xmlSearchNs(NULL, node, prefix);
2026                     xmlFree(prefix);
2027                 }
2028                 if (ns == NULL)
2029                     oldAttr = xmlHasNsProp(node, name, NULL);
2030                 else
2031                     oldAttr = xmlHasNsProp(node, localName, ns->href);
2032                 xmlFuzzResetMallocFailed();
2033                 if (oldAttr != NULL)
2034                     removeChildren((xmlNodePtr) oldAttr, 0);
2035 
2036                 attr = xmlSetProp(node, name, value);
2037 
2038                 oomReport =
2039                     (node != NULL && node->type == XML_ELEMENT_NODE &&
2040                      name != NULL &&
2041                      attr == NULL);
2042                 setNode(0, (xmlNodePtr) attr);
2043                 break;
2044             }
2045 
2046             case OP_XML_SET_NS_PROP: {
2047                 xmlNodePtr node;
2048                 xmlNsPtr ns;
2049                 xmlAttrPtr oldAttr, attr;
2050                 const xmlChar *name, *value;
2051 
2052                 startOp("xmlSetNsProp");
2053                 incNodeIdx();
2054                 node = getNode(1);
2055                 ns = nodeGetNs(getNode(2), getInt(0));
2056                 name = getStr(0);
2057                 value = getStr(1);
2058                 oldAttr = xmlHasNsProp(node, name, ns ? ns->href : NULL);
2059                 xmlFuzzResetMallocFailed();
2060                 if (oldAttr != NULL)
2061                     removeChildren((xmlNodePtr) oldAttr, 0);
2062                 attr = xmlSetNsProp(node, ns, name, value);
2063                 oomReport =
2064                     ((node == NULL || node->type == XML_ELEMENT_NODE) &&
2065                      (ns == NULL || ns->href != NULL) &&
2066                      name != NULL &&
2067                      attr == NULL);
2068                 setNode(0, (xmlNodePtr) attr);
2069                 if (ns != NULL) {
2070                     if (fixNs((xmlNodePtr) attr) < 0)
2071                         oomReport = 1;
2072                 }
2073                 break;
2074             }
2075 
2076             case OP_XML_REMOVE_PROP: {
2077                 xmlNodePtr attr, parent = NULL;
2078 
2079                 startOp("xmlRemoveProp");
2080                 incIntIdx();
2081                 attr = getNode(0);
2082                 if (attr != NULL) {
2083                     if (attr->parent != NULL &&
2084                         attr->type == XML_ATTRIBUTE_NODE)
2085                         removeChildren(attr, 1);
2086                     else
2087                         attr = NULL;
2088                 }
2089                 if (attr != NULL)
2090                     parent = attr->parent;
2091                 setInt(0, xmlRemoveProp((xmlAttrPtr) attr));
2092                 oomReport = 0;
2093                 dropNode(parent);
2094                 endOp();
2095                 break;
2096             }
2097 
2098             case OP_XML_UNSET_PROP: {
2099                 xmlNodePtr node;
2100                 xmlAttrPtr attr;
2101                 const xmlChar *name;
2102 
2103                 startOp("xmlUnsetProp");
2104                 incIntIdx();
2105                 node = getNode(0);
2106                 name = getStr(0);
2107                 attr = xmlHasNsProp(node, name, NULL);
2108                 xmlFuzzResetMallocFailed();
2109                 if (attr != NULL)
2110                     removeChildren((xmlNodePtr) attr, 1);
2111                 setInt(0, xmlUnsetProp(node, name));
2112                 oomReport = 0;
2113                 dropNode(node);
2114                 endOp();
2115                 break;
2116             }
2117 
2118             case OP_XML_UNSET_NS_PROP: {
2119                 xmlNodePtr node;
2120                 xmlNsPtr ns;
2121                 xmlAttrPtr attr;
2122                 const xmlChar *name;
2123 
2124                 startOp("xmlUnsetNsProp");
2125                 incIntIdx();
2126                 node = getNode(0);
2127                 ns = nodeGetNs(getNode(1), getInt(1));
2128                 name = getStr(0);
2129                 attr = xmlHasNsProp(node, name, ns ? ns->href : NULL);
2130                 xmlFuzzResetMallocFailed();
2131                 if (attr != NULL)
2132                     removeChildren((xmlNodePtr) attr, 1);
2133                 setInt(0, xmlUnsetNsProp(node, ns, name));
2134                 oomReport = 0;
2135                 dropNode(node);
2136                 endOp();
2137                 break;
2138             }
2139 
2140             case OP_XML_NEW_NS: {
2141                 xmlNodePtr node;
2142                 xmlNsPtr ns;
2143 
2144                 startOp("xmlNewNs");
2145                 ns = xmlNewNs(
2146                     node = getNode(0),
2147                     getStr(0),
2148                     getStr(1));
2149                 if (ns != NULL)
2150                     oomReport = 0;
2151                 if (node == NULL)
2152                     xmlFreeNs(ns);
2153                 endOp();
2154                 break;
2155             }
2156 
2157             case OP_XML_SEARCH_NS: {
2158                 xmlNsPtr ns;
2159 
2160                 startOp("xmlSearchNs");
2161                 ns = xmlSearchNs(
2162                     getDoc(0),
2163                     getNode(1),
2164                     getStr(0));
2165                 if (ns != NULL)
2166                     oomReport = 0;
2167                 endOp();
2168                 break;
2169             }
2170 
2171             case OP_XML_SEARCH_NS_BY_HREF: {
2172                 xmlNsPtr ns;
2173 
2174                 startOp("xmlSearchNsByHref");
2175                 ns = xmlSearchNsByHref(
2176                     getDoc(0),
2177                     getNode(1),
2178                     getStr(0));
2179                 if (ns != NULL)
2180                     oomReport = 0;
2181                 endOp();
2182                 break;
2183             }
2184 
2185             case OP_XML_GET_NS_LIST: {
2186                 xmlNsPtr *list;
2187 
2188                 startOp("xmlGetNsList");
2189                 list = xmlGetNsList(
2190                     getDoc(0),
2191                     getNode(1));
2192                 if (list != NULL)
2193                     oomReport = 0;
2194                 xmlFree(list);
2195                 endOp();
2196                 break;
2197             }
2198 
2199             case OP_XML_GET_NS_LIST_SAFE: {
2200                 xmlNsPtr *list;
2201                 int res;
2202 
2203                 startOp("xmlGetNsList");
2204                 res = xmlGetNsListSafe(
2205                     getDoc(0),
2206                     getNode(1),
2207                     &list);
2208                 oomReport = (res < 0);
2209                 xmlFree(list);
2210                 endOp();
2211                 break;
2212             }
2213 
2214             case OP_XML_SET_NS: {
2215                 xmlNodePtr node;
2216                 xmlNsPtr ns;
2217 
2218                 startOp("xmlSetNs");
2219                 node = getNode(0),
2220                 ns = nodeGetNs(getNode(1), getInt(0));
2221                 xmlSetNs(node, ns);
2222                 oomReport = 0;
2223                 if (ns != NULL) {
2224                     if (fixNs(node) < 0)
2225                         oomReport = 1;
2226                 }
2227                 endOp();
2228                 break;
2229             }
2230 
2231             case OP_XML_COPY_NAMESPACE: {
2232                 xmlNsPtr ns, copy;
2233 
2234                 startOp("xmlCopyNamespace");
2235                 copy = xmlCopyNamespace(
2236                     ns = nodeGetNs(getNode(0), getInt(0)));
2237                 oomReport = (ns != NULL && copy == NULL);
2238                 xmlFreeNs(copy);
2239                 endOp();
2240                 break;
2241             }
2242 
2243             case OP_XML_COPY_NAMESPACE_LIST: {
2244                 xmlNsPtr list, copy;
2245 
2246                 startOp("xmlCopyNamespaceList");
2247                 copy = xmlCopyNamespaceList(
2248                     list = nodeGetNs(getNode(0), getInt(0)));
2249                 oomReport = (list != NULL && copy == NULL);
2250                 xmlFreeNsList(copy);
2251                 endOp();
2252                 break;
2253             }
2254 
2255             case OP_XML_UNLINK_NODE: {
2256                 xmlNodePtr node, oldParent;
2257                 xmlDocPtr doc;
2258 
2259                 startOp("xmlUnlinkNode");
2260                 node = getNode(0);
2261                 doc = node ? node->doc : NULL;
2262                 /*
2263                  * Unlinking DTD children can cause invalid references
2264                  * which would be expensive to fix.
2265                  *
2266                  * Don't unlink DTD if it is the internal or external
2267                  * subset of the document.
2268                  */
2269                 if (node != NULL &&
2270                     (isDtdChild(node) ||
2271                      (node->type == XML_DTD_NODE &&
2272                       doc != NULL &&
2273                       ((xmlDtdPtr) node == doc->intSubset ||
2274                        (xmlDtdPtr) node == doc->extSubset))))
2275                     node = NULL;
2276                 oldParent = node ? node->parent : NULL;
2277                 xmlUnlinkNode(node);
2278                 oomReport = 0;
2279                 if (node != NULL && node->parent != oldParent) {
2280                     if (fixNs(node) < 0)
2281                         oomReport = 1;
2282                     dropNode(oldParent);
2283                 }
2284                 endOp();
2285                 break;
2286             }
2287 
2288             case OP_XML_REPLACE_NODE: {
2289                 xmlNodePtr old, oldParent, node, oldNodeParent, result;
2290                 xmlDocPtr oldNodeDoc;
2291 
2292                 startOp("xmlReplaceNode");
2293                 old = getNode(0);
2294                 node = getNode(1);
2295 
2296                 /*
2297                  * Unlinking DTD children can cause invalid references
2298                  * which would be expensive to fix.
2299                  */
2300                 if (isDtdChild(old))
2301                     old = NULL;
2302                 if (old != NULL && !isValidChild(old->parent, node))
2303                     node = NULL;
2304 
2305                 oldParent = old ? old->parent : NULL;
2306                 oldNodeParent = node ? node->parent : NULL;
2307                 oldNodeDoc = node ? node->doc : NULL;
2308 
2309                 result = xmlReplaceNode(old, node);
2310                 oomReport =
2311                     (old != NULL && old->parent != NULL &&
2312                      node != NULL &&
2313                      old != node &&
2314                      result == NULL);
2315 
2316                 if (old != NULL && old->parent != oldParent) {
2317                     if (fixNs(old) < 0)
2318                         oomReport = 1;
2319                 }
2320                 if (node == NULL) {
2321                     /* Old node was unlinked */
2322                     dropNode(oldParent);
2323                 } else if (node->parent != oldNodeParent ||
2324                            node->doc != oldNodeDoc) {
2325                     if (fixNs(node) < 0)
2326                         oomReport = 1;
2327                     /* Drop old parent of new node */
2328                     if (oldNodeParent != NULL)
2329                         dropNode(oldNodeParent);
2330                     else
2331                         dropNode((xmlNodePtr) oldNodeDoc);
2332                 }
2333                 endOp();
2334                 break;
2335             }
2336 
2337             case OP_XML_ADD_CHILD:
2338             case OP_XML_ADD_SIBLING:
2339             case OP_XML_ADD_PREV_SIBLING:
2340             case OP_XML_ADD_NEXT_SIBLING: {
2341                 xmlNodePtr target, parent, node, oldNodeParent, result;
2342                 xmlDocPtr oldNodeDoc;
2343                 int argsOk;
2344 
2345                 switch (op) {
2346                     case OP_XML_ADD_CHILD:
2347                         startOp("xmlAddChild"); break;
2348                     case OP_XML_ADD_SIBLING:
2349                         startOp("xmlAddSibling"); break;
2350                     case OP_XML_ADD_PREV_SIBLING:
2351                         startOp("xmlAddPrevSibling"); break;
2352                     case OP_XML_ADD_NEXT_SIBLING:
2353                         startOp("xmlAddNextSibling"); break;
2354                 }
2355 
2356                 if (op == OP_XML_ADD_CHILD) {
2357                     target = NULL;
2358                     parent = getNode(0);
2359                 } else {
2360                     target = getNode(0);
2361                     parent = target ? target->parent : NULL;
2362                 }
2363                 node = getNode(1);
2364 
2365                 /* Don't append to root node */
2366                 if (target != NULL && parent == NULL)
2367                     node = NULL;
2368 
2369                 /* Check tree structure */
2370                 if (isDtdChild(node) ||
2371                     !isValidChild(parent, node))
2372                     node = NULL;
2373 
2374                 /* Attributes */
2375                 if (node != NULL && node->type == XML_ATTRIBUTE_NODE) {
2376                     if ((op == OP_XML_ADD_CHILD) ||
2377                         ((target != NULL &&
2378                          (target->type == XML_ATTRIBUTE_NODE)))) {
2379                         xmlAttrPtr attr = xmlHasNsProp(parent, node->name,
2380                             node->ns ? node->ns->href : NULL);
2381 
2382                         xmlFuzzResetMallocFailed();
2383                         /* Attribute might be replaced */
2384                         if (attr != NULL && attr != (xmlAttrPtr) node)
2385                             removeChildren((xmlNodePtr) attr, 1);
2386                     } else {
2387                         target = NULL;
2388                     }
2389                 } else if (target != NULL &&
2390                            target->type == XML_ATTRIBUTE_NODE) {
2391                     node = NULL;
2392                 }
2393 
2394                 oldNodeParent = node ? node->parent : NULL;
2395                 oldNodeDoc = node ? node->doc : NULL;
2396                 argsOk =
2397                     (target != NULL &&
2398                      node != NULL &&
2399                      target != node);
2400 
2401                 switch (op) {
2402                     case OP_XML_ADD_CHILD:
2403                         argsOk = (parent != NULL && node != NULL);
2404                         result = xmlAddChild(parent, node);
2405                         break;
2406                     case OP_XML_ADD_SIBLING:
2407                         result = xmlAddSibling(target, node);
2408                         break;
2409                     case OP_XML_ADD_PREV_SIBLING:
2410                         result = xmlAddPrevSibling(target, node);
2411                         break;
2412                     case OP_XML_ADD_NEXT_SIBLING:
2413                         result = xmlAddNextSibling(target, node);
2414                         break;
2415                 }
2416                 oomReport = (argsOk && result == NULL);
2417 
2418                 if (result != NULL && result != node) {
2419                     /* Text node was merged */
2420                     removeNode(node);
2421                     checkContent(result);
2422                     /* Drop old parent of node */
2423                     if (oldNodeParent != NULL)
2424                         dropNode(oldNodeParent);
2425                     else
2426                         dropNode((xmlNodePtr) oldNodeDoc);
2427                 } else if (node != NULL &&
2428                            (node->parent != oldNodeParent ||
2429                             node->doc != oldNodeDoc)) {
2430                     if (fixNs(node) < 0)
2431                         oomReport = 1;
2432                     /* Drop old parent of node */
2433                     if (oldNodeParent != NULL)
2434                         dropNode(oldNodeParent);
2435                     else
2436                         dropNode((xmlNodePtr) oldNodeDoc);
2437                 }
2438 
2439                 endOp();
2440                 break;
2441             }
2442 
2443             case OP_XML_TEXT_MERGE: {
2444                 xmlNodePtr first, second, parent = NULL, res;
2445                 int argsOk;
2446 
2447                 startOp("xmlTextMerge");
2448                 first = getNode(0);
2449                 second = getNode(1);
2450                 argsOk =
2451                     (first != NULL && first->type == XML_TEXT_NODE &&
2452                      second != NULL && second->type == XML_TEXT_NODE &&
2453                      first != second &&
2454                      first->name == second->name);
2455                 if (argsOk) {
2456                     if (second->parent != NULL)
2457                         parent = second->parent;
2458                     else
2459                         parent = (xmlNodePtr) second->doc;
2460 
2461                 }
2462                 res = xmlTextMerge(first, second);
2463                 oomReport = (argsOk && res == NULL);
2464                 if (res != NULL) {
2465                     removeNode(second);
2466                     dropNode(parent);
2467                     checkContent(first);
2468                 }
2469                 endOp();
2470                 break;
2471             }
2472 
2473             case OP_XML_TEXT_CONCAT: {
2474                 xmlNodePtr node;
2475                 const xmlChar *text;
2476                 int res;
2477 
2478                 startOp("xmlTextConcat");
2479                 node = getNode(0);
2480                 text = getStr(0);
2481                 res = xmlTextConcat(
2482                     node,
2483                     text,
2484                     xmlStrlen(text));
2485                 oomReport = (isTextContentNode(node) && res < 0);
2486                 checkContent(node);
2487                 endOp();
2488                 break;
2489             }
2490 
2491             case OP_XML_STRING_GET_NODE_LIST: {
2492                 xmlNodePtr list;
2493                 const xmlChar *value;
2494 
2495                 startOp("xmlStringGetNodeList");
2496                 list = xmlStringGetNodeList(
2497                     getDoc(0),
2498                     value = getStr(0));
2499                 oomReport = (value != NULL && list == NULL);
2500                 xmlFreeNodeList(list);
2501                 endOp();
2502                 break;
2503             }
2504 
2505             case OP_XML_STRING_LEN_GET_NODE_LIST: {
2506                 xmlDocPtr doc;
2507                 xmlNodePtr list;
2508                 const xmlChar *value;
2509 
2510                 startOp("xmlStringLenGetNodeList");
2511                 doc = getDoc(0);
2512                 value = getStr(0);
2513                 list = xmlStringLenGetNodeList(
2514                     doc,
2515                     value,
2516                     xmlStrlen(value));
2517                 oomReport = (value != NULL && list == NULL);
2518                 xmlFreeNodeList(list);
2519                 endOp();
2520                 break;
2521             }
2522 
2523             case OP_XML_NODE_LIST_GET_STRING: {
2524                 xmlChar *string;
2525 
2526                 startOp("xmlNodeListGetString");
2527                 incStrIdx();
2528                 string = xmlNodeListGetString(
2529                     getDoc(0),
2530                     getNode(1),
2531                     getInt(0));
2532                 oomReport = (string == NULL);
2533                 moveStr(0, string);
2534                 endOp();
2535                 break;
2536             }
2537 
2538             case OP_XML_NODE_LIST_GET_RAW_STRING: {
2539                 xmlChar *string;
2540 
2541                 startOp("xmlNodeListGetRawString");
2542                 incStrIdx();
2543                 string = xmlNodeListGetRawString(
2544                     getDoc(0),
2545                     getNode(1),
2546                     getInt(0));
2547                 oomReport = (string == NULL);
2548                 moveStr(0, string);
2549                 endOp();
2550                 break;
2551             }
2552 
2553             case OP_XML_IS_XHTML:
2554                 startOp("xmlIsXHTML");
2555                 incIntIdx();
2556                 setInt(0, xmlIsXHTML(
2557                     getStr(0),
2558                     getStr(1)));
2559                 oomReport = 0;
2560                 break;
2561 
2562             case OP_XML_ADD_ELEMENT_DECL: {
2563                 xmlElementPtr decl;
2564 
2565                 startOp("xmlAddElementDecl");
2566                 incNodeIdx();
2567                 decl = xmlAddElementDecl(
2568                     NULL,
2569                     getDtd(1),
2570                     getStr(0),
2571                     (xmlElementTypeVal) getInt(0),
2572                     NULL);
2573                 if (decl != NULL)
2574                     oomReport = 0;
2575                 setNode(0, (xmlNodePtr) decl);
2576                 break;
2577             }
2578 
2579             case OP_XML_ADD_ATTRIBUTE_DECL: {
2580                 xmlAttributePtr decl;
2581 
2582                 startOp("xmlAddAttributeDecl");
2583                 incNodeIdx();
2584                 decl = xmlAddAttributeDecl(
2585                     NULL,
2586                     getDtd(1),
2587                     getStr(0),
2588                     getStr(1),
2589                     getStr(2),
2590                     (xmlAttributeType) getInt(0),
2591                     (xmlAttributeDefault) getInt(1),
2592                     getStr(3),
2593                     NULL);
2594                 if (decl != NULL)
2595                     oomReport = 0;
2596                 setNode(0, (xmlNodePtr) decl);
2597                 break;
2598             }
2599 
2600             case OP_XML_ADD_NOTATION_DECL: {
2601                 xmlNotationPtr decl;
2602 
2603                 startOp("xmlAddNotationDecl");
2604                 decl = xmlAddNotationDecl(
2605                     NULL,
2606                     getDtd(1),
2607                     getStr(0),
2608                     getStr(1),
2609                     getStr(2));
2610                 if (decl != NULL)
2611                     oomReport = 0;
2612                 endOp();
2613                 break;
2614             }
2615 
2616             case OP_XML_GET_DTD_ELEMENT_DESC: {
2617                 xmlElementPtr elem;
2618 
2619                 startOp("xmlGetDtdElementDesc");
2620                 incNodeIdx();
2621                 elem = xmlGetDtdElementDesc(
2622                     getDtd(1),
2623                     getStr(0));
2624                 if (elem != NULL)
2625                     oomReport = 0;
2626                 /*
2627                  * Don't reference XML_ELEMENT_TYPE_UNDEFINED dummy
2628                  * declarations.
2629                  */
2630                 if (elem != NULL && elem->parent == NULL)
2631                     elem = NULL;
2632                 setNode(0, (xmlNodePtr) elem);
2633                 break;
2634             }
2635 
2636             case OP_XML_GET_DTD_QELEMENT_DESC: {
2637                 xmlElementPtr elem;
2638 
2639                 startOp("xmlGetDtdQElementDesc");
2640                 incNodeIdx();
2641                 elem = xmlGetDtdQElementDesc(
2642                     getDtd(1),
2643                     getStr(0),
2644                     getStr(1));
2645                 oomReport = 0;
2646                 if (elem != NULL && elem->parent == NULL)
2647                     elem = NULL;
2648                 setNode(0, (xmlNodePtr) elem);
2649                 break;
2650             }
2651 
2652             case OP_XML_GET_DTD_ATTR_DESC: {
2653                 xmlAttributePtr decl;
2654 
2655                 startOp("xmlGetDtdAttrDesc");
2656                 incNodeIdx();
2657                 decl = xmlGetDtdAttrDesc(
2658                     getDtd(1),
2659                     getStr(0),
2660                     getStr(1));
2661                 if (decl != NULL)
2662                     oomReport = 0;
2663                 setNode(0, (xmlNodePtr) decl);
2664                 break;
2665             }
2666 
2667             case OP_XML_GET_DTD_QATTR_DESC: {
2668                 xmlAttributePtr decl;
2669 
2670                 startOp("xmlGetDtdQAttrDesc");
2671                 incNodeIdx();
2672                 decl = xmlGetDtdQAttrDesc(
2673                     getDtd(1),
2674                     getStr(0),
2675                     getStr(1),
2676                     getStr(2));
2677                 oomReport = 0;
2678                 setNode(0, (xmlNodePtr) decl);
2679                 break;
2680             }
2681 
2682             case OP_XML_GET_DTD_NOTATION_DESC:
2683                 startOp("xmlGetDtdNotationDesc");
2684                 xmlGetDtdNotationDesc(
2685                     getDtd(1),
2686                     getStr(0));
2687                 oomReport = 0;
2688                 endOp();
2689                 break;
2690 
2691             case OP_XML_ADD_ID:
2692                 startOp("xmlAddID");
2693                 xmlAddID(
2694                     NULL,
2695                     getDoc(0),
2696                     getStr(0),
2697                     getAttr(1));
2698                 endOp();
2699                 break;
2700 
2701             case OP_XML_ADD_ID_SAFE: {
2702                 int res;
2703 
2704                 startOp("xmlAddIDSafe");
2705                 res = xmlAddIDSafe(
2706                     getAttr(0),
2707                     getStr(0));
2708                 oomReport = (res < 0);
2709                 endOp();
2710                 break;
2711             }
2712 
2713             case OP_XML_GET_ID:
2714                 startOp("xmlGetID");
2715                 incNodeIdx();
2716                 setNode(0, (xmlNodePtr) xmlGetID(
2717                     getDoc(1),
2718                     getStr(0)));
2719                 oomReport = 0;
2720                 break;
2721 
2722             case OP_XML_IS_ID: {
2723                 int res;
2724 
2725                 startOp("xmlIsID");
2726                 res = xmlIsID(
2727                     getDoc(2),
2728                     getNode(1),
2729                     getAttr(0));
2730                 oomReport = (res < 0);
2731                 endOp();
2732                 break;
2733             }
2734 
2735             case OP_XML_REMOVE_ID:
2736                 startOp("xmlRemoveID");
2737                 xmlRemoveID(
2738                     getDoc(1),
2739                     getAttr(0));
2740                 oomReport = 0;
2741                 endOp();
2742                 break;
2743 
2744             case OP_XML_ADD_REF: {
2745                 xmlDocPtr doc;
2746                 xmlAttrPtr attr;
2747                 xmlRefPtr ref;
2748                 const xmlChar *value;
2749 
2750                 startOp("xmlAddRef");
2751                 ref = xmlAddRef(
2752                     NULL,
2753                     doc = getDoc(0),
2754                     value = getStr(0),
2755                     attr = getAttr(1));
2756                 oomReport =
2757                     (doc != NULL &&
2758                      value != NULL &&
2759                      attr != NULL &&
2760                      ref == NULL);
2761                 endOp();
2762                 break;
2763             }
2764 
2765             case OP_XML_GET_REFS:
2766                 startOp("xmlGetRefs");
2767                 xmlGetRefs(
2768                     getDoc(1),
2769                     getStr(0));
2770                 oomReport = 0;
2771                 endOp();
2772                 break;
2773 
2774             case OP_XML_IS_REF:
2775                 startOp("xmlIsRef");
2776                 xmlIsRef(
2777                     getDoc(2),
2778                     getNode(1),
2779                     getAttr(0));
2780                 oomReport = 0;
2781                 endOp();
2782                 break;
2783 
2784             case OP_XML_REMOVE_REF: {
2785                 int res;
2786 
2787                 startOp("xmlRemoveRef");
2788                 res = xmlRemoveRef(
2789                     getDoc(1),
2790                     getAttr(0));
2791                 if (res == 0)
2792                     oomReport = 0;
2793                 endOp();
2794                 break;
2795             }
2796 
2797             case OP_XML_NEW_ENTITY: {
2798                 xmlDocPtr doc;
2799                 xmlEntityPtr ent;
2800 
2801                 startOp("xmlNewEntity");
2802                 incNodeIdx();
2803                 ent = xmlNewEntity(
2804                     doc = getDoc(1),
2805                     getStr(0),
2806                     getInt(0),
2807                     getStr(1),
2808                     getStr(2),
2809                     getStr(3));
2810                 if (ent != NULL)
2811                     oomReport = 0;
2812                 if (doc == NULL || doc->intSubset == NULL) {
2813                     xmlFreeEntity(ent);
2814                     ent = NULL;
2815                 }
2816                 setNode(0, (xmlNodePtr) ent);
2817                 break;
2818             }
2819 
2820             case OP_XML_ADD_ENTITY: {
2821                 xmlEntityPtr ent;
2822                 int res;
2823 
2824                 startOp("xmlAddEntity");
2825                 incNodeIdx();
2826                 res = xmlAddEntity(
2827                     getDoc(1),
2828                     getInt(0),
2829                     getStr(0),
2830                     getInt(1),
2831                     getStr(1),
2832                     getStr(2),
2833                     getStr(3),
2834                     &ent);
2835                 oomReport = (res == XML_ERR_NO_MEMORY);
2836                 setNode(0, (xmlNodePtr) ent);
2837                 break;
2838             }
2839 
2840             case OP_XML_ADD_DOC_ENTITY: {
2841                 xmlEntityPtr ent;
2842 
2843                 startOp("xmlAddDocEntity");
2844                 incNodeIdx();
2845                 ent = xmlAddDocEntity(
2846                     getDoc(1),
2847                     getStr(0),
2848                     getInt(1),
2849                     getStr(1),
2850                     getStr(2),
2851                     getStr(3));
2852                 if (ent != NULL)
2853                     oomReport = 0;
2854                 setNode(0, (xmlNodePtr) ent);
2855                 break;
2856             }
2857 
2858             case OP_XML_ADD_DTD_ENTITY: {
2859                 xmlEntityPtr ent;
2860 
2861                 startOp("xmlAddDtdEntity");
2862                 incNodeIdx();
2863                 ent = xmlAddDtdEntity(
2864                     getDoc(1),
2865                     getStr(0),
2866                     getInt(1),
2867                     getStr(1),
2868                     getStr(2),
2869                     getStr(3));
2870                 setNode(0, (xmlNodePtr) ent);
2871                 break;
2872             }
2873 
2874             case OP_XML_GET_PREDEFINED_ENTITY:
2875                 startOp("xmlGetPredefinedEntity");
2876                 incNodeIdx();
2877                 setNode(0, (xmlNodePtr) xmlGetPredefinedEntity(
2878                     getStr(0)));
2879                 oomReport = 0;
2880                 break;
2881 
2882             case OP_XML_GET_DOC_ENTITY:
2883                 startOp("xmlGetDocEntity");
2884                 incNodeIdx();
2885                 setNode(0, (xmlNodePtr) xmlGetDocEntity(
2886                     getDoc(1),
2887                     getStr(0)));
2888                 oomReport = 0;
2889                 break;
2890 
2891             case OP_XML_GET_DTD_ENTITY:
2892                 startOp("xmlGetDtdEntity");
2893                 incNodeIdx();
2894                 setNode(0, (xmlNodePtr) xmlGetDtdEntity(
2895                     getDoc(1),
2896                     getStr(0)));
2897                 oomReport = 0;
2898                 break;
2899 
2900             case OP_XML_GET_PARAMETER_ENTITY:
2901                 startOp("xmlGetParameterEntity");
2902                 incNodeIdx();
2903                 setNode(0, (xmlNodePtr) xmlGetParameterEntity(
2904                     getDoc(1),
2905                     getStr(0)));
2906                 oomReport = 0;
2907                 break;
2908 
2909             case OP_XML_ENCODE_ENTITIES_REENTRANT: {
2910                 const xmlChar *string;
2911                 xmlChar *encoded;
2912 
2913                 startOp("xmlEncodeEntitiesReentrant");
2914                 incStrIdx();
2915                 encoded = xmlEncodeEntitiesReentrant(
2916                     getDoc(0),
2917                     string = getStr(1));
2918                 oomReport = (string != NULL && encoded == NULL);
2919                 moveStr(0, encoded);
2920                 endOp();
2921                 break;
2922             }
2923 
2924             case OP_XML_ENCODE_SPECIAL_CHARS: {
2925                 const xmlChar *string;
2926                 xmlChar *encoded;
2927 
2928                 startOp("xmlEncodespecialChars");
2929                 incStrIdx();
2930                 encoded = xmlEncodeSpecialChars(
2931                     getDoc(0),
2932                     string = getStr(1));
2933                 oomReport = (string != NULL && encoded == NULL);
2934                 moveStr(0, encoded);
2935                 endOp();
2936                 break;
2937             }
2938 
2939 #ifdef LIBXML_HTML_ENABLED
2940             case OP_HTML_NEW_DOC: {
2941                 htmlDocPtr doc;
2942 
2943                 startOp("htmlNewDoc");
2944                 incNodeIdx();
2945                 doc = htmlNewDoc(
2946                     getStr(0),
2947                     getStr(1));
2948                 oomReport = (doc == NULL);
2949                 setNode(0, (xmlNodePtr) doc);
2950                 break;
2951             }
2952 
2953             case OP_HTML_NEW_DOC_NO_DTD: {
2954                 htmlDocPtr doc;
2955 
2956                 startOp("htmlNewDocNoDtD");
2957                 incNodeIdx();
2958                 doc = htmlNewDocNoDtD(
2959                     getStr(0),
2960                     getStr(1));
2961                 oomReport = (doc == NULL);
2962                 setNode(0, (xmlNodePtr) doc);
2963                 break;
2964             }
2965 
2966             case OP_HTML_GET_META_ENCODING: {
2967                 const xmlChar *encoding;
2968 
2969                 startOp("htmlGetMetaEncoding");
2970                 incStrIdx();
2971                 encoding = htmlGetMetaEncoding(getDoc(0));
2972                 if (encoding != NULL)
2973                     oomReport = 0;
2974                 copyStr(0, encoding);
2975                 break;
2976             }
2977 
2978             case OP_HTML_SET_META_ENCODING:
2979                 /* TODO (can destroy inner text) */
2980                 break;
2981 
2982             case OP_HTML_IS_BOOLEAN_ATTR:
2983                 startOp("htmlIsBooleanAttr");
2984                 htmlIsBooleanAttr(getStr(0));
2985                 oomReport = 0;
2986                 endOp();
2987                 break;
2988 #endif
2989 
2990 #ifdef LIBXML_VALID_ENABLED
2991             case OP_VALIDATE: {
2992                 xmlNodePtr node;
2993                 int type;
2994                 int res = 1;
2995 
2996                 startOp("validate");
2997                 incIntIdx();
2998                 node = getNode(0);
2999                 type = node ? node->type : 0;
3000                 xmlValidCtxtPtr vctxt = xmlNewValidCtxt();
3001                 xmlFuzzResetMallocFailed();
3002 
3003                 switch (type) {
3004                     case XML_DOCUMENT_NODE:
3005                     case XML_HTML_DOCUMENT_NODE:
3006                         res = xmlValidateDocument(vctxt, (xmlDocPtr) node);
3007                         break;
3008                     case XML_ELEMENT_DECL:
3009                         res = xmlValidateElementDecl(vctxt, node->doc,
3010                             (xmlElementPtr) node);
3011                         break;
3012                     case XML_ATTRIBUTE_DECL:
3013                         res = xmlValidateAttributeDecl(vctxt, node->doc,
3014                             (xmlAttributePtr) node);
3015                         break;
3016                     case XML_ELEMENT_NODE:
3017                         res = xmlValidateElement(vctxt, node->doc, node);
3018                         break;
3019                     default:
3020                         break;
3021                 }
3022 
3023                 if (res != 0)
3024                     oomReport = 0;
3025                 xmlFreeValidCtxt(vctxt);
3026                 setInt(0, res);
3027                 endOp();
3028                 break;
3029             }
3030 
3031             case OP_XML_VALIDATE_DTD: {
3032                 xmlValidCtxtPtr vctxt;
3033                 int res;
3034 
3035                 startOp("xmlValidateDtd");
3036                 incIntIdx();
3037                 vctxt = xmlNewValidCtxt();
3038                 res = xmlValidateDtd(
3039                     vctxt,
3040                     getDoc(0),
3041                     getDtd(1));
3042                 if (res != 0)
3043                     oomReport = 0;
3044                 xmlFreeValidCtxt(vctxt);
3045                 setInt(0, res);
3046                 endOp();
3047                 break;
3048             }
3049 #endif /* LIBXML_VALID_ENABLED */
3050 
3051 #ifdef LIBXML_OUTPUT_ENABLED
3052             case OP_XML_DOC_DUMP_MEMORY:
3053             case OP_XML_DOC_DUMP_MEMORY_ENC:
3054             case OP_XML_DOC_DUMP_FORMAT_MEMORY:
3055             case OP_XML_DOC_DUMP_FORMAT_MEMORY_ENC:
3056             case OP_HTML_DOC_DUMP_MEMORY:
3057             case OP_HTML_DOC_DUMP_MEMORY_FORMAT: {
3058                 xmlDocPtr doc;
3059                 xmlChar *out = NULL;
3060                 int outSize = 0;
3061 
3062                 switch (op) {
3063                     case OP_XML_DOC_DUMP_MEMORY:
3064                         startOp("xmlDocDumpMemory"); break;
3065                     case OP_XML_DOC_DUMP_MEMORY_ENC:
3066                         startOp("xmlDocDumpMemoryEnc"); break;
3067                     case OP_XML_DOC_DUMP_FORMAT_MEMORY:
3068                         startOp("xmlDocDumpFormatMemory"); break;
3069                     case OP_XML_DOC_DUMP_FORMAT_MEMORY_ENC:
3070                         startOp("xmlDocDumpFormatMemoryEnc"); break;
3071                     case OP_HTML_DOC_DUMP_MEMORY:
3072                         startOp("htmlDocDumpMemory"); break;
3073                     case OP_HTML_DOC_DUMP_MEMORY_FORMAT:
3074                         startOp("htmlDocDumpMemoryFormat"); break;
3075                 }
3076 
3077                 incStrIdx();
3078                 doc = getDoc(0);
3079 
3080                 switch (op) {
3081                     case OP_XML_DOC_DUMP_MEMORY:
3082                         xmlDocDumpMemory(doc, &out, &outSize);
3083                         break;
3084                     case OP_XML_DOC_DUMP_MEMORY_ENC:
3085                         xmlDocDumpMemoryEnc(doc, &out, &outSize,
3086                             (const char *) getStr(1));
3087                         break;
3088                     case OP_XML_DOC_DUMP_FORMAT_MEMORY:
3089                         xmlDocDumpFormatMemory(doc, &out, &outSize,
3090                             getInt(0));
3091                         break;
3092                     case OP_XML_DOC_DUMP_FORMAT_MEMORY_ENC:
3093                         xmlDocDumpFormatMemoryEnc(doc, &out, &outSize,
3094                             (const char *) getStr(1),
3095                             getInt(0));
3096                         break;
3097 #ifdef LIBXML_HTML_ENABLED
3098                     case OP_HTML_DOC_DUMP_MEMORY:
3099                         htmlDocDumpMemory(doc, &out, &outSize);
3100                         break;
3101                     case OP_HTML_DOC_DUMP_MEMORY_FORMAT:
3102                         htmlDocDumpMemoryFormat(doc, &out, &outSize,
3103                             getInt(0));
3104                         break;
3105 #endif /* LIBXML_HTML_ENABLED */
3106                 }
3107 
3108                 /* Could be an unknown encoding */
3109                 if (out != NULL)
3110                     oomReport = 0;
3111                 moveStr(0, out);
3112                 endOp();
3113                 break;
3114             }
3115 
3116             case OP_XML_NODE_DUMP:
3117             case OP_XML_NODE_BUF_GET_CONTENT:
3118             case OP_XML_ATTR_SERIALIZE_TXT_CONTENT:
3119             case OP_XML_DUMP_ELEMENT_DECL:
3120             case OP_XML_DUMP_ELEMENT_TABLE:
3121             case OP_XML_DUMP_ATTRIBUTE_DECL:
3122             case OP_XML_DUMP_ATTRIBUTE_TABLE:
3123             case OP_XML_DUMP_ENTITY_DECL:
3124             case OP_XML_DUMP_ENTITIES_TABLE:
3125             case OP_XML_DUMP_NOTATION_DECL:
3126             case OP_XML_DUMP_NOTATION_TABLE:
3127             case OP_HTML_NODE_DUMP: {
3128                 xmlNodePtr node;
3129                 xmlDocPtr doc;
3130                 xmlBufferPtr buffer;
3131                 xmlChar *dump;
3132                 int level, format, res;
3133 
3134                 switch (op) {
3135                     case OP_XML_NODE_DUMP:
3136                         startOp("xmlNodeDump"); break;
3137                     case OP_XML_NODE_BUF_GET_CONTENT:
3138                         startOp("xmlNodeBufGetContent"); break;
3139                     case OP_XML_ATTR_SERIALIZE_TXT_CONTENT:
3140                         startOp("xmlAttrSerializeTxtContent"); break;
3141                     case OP_XML_DUMP_ELEMENT_DECL:
3142                         startOp("xmlDumpElementDecl"); break;
3143                     case OP_XML_DUMP_ELEMENT_TABLE:
3144                         startOp("xmlDumpElementTable"); break;
3145                     case OP_XML_DUMP_ATTRIBUTE_DECL:
3146                         startOp("xmlDumpAttributeDecl"); break;
3147                     case OP_XML_DUMP_ATTRIBUTE_TABLE:
3148                         startOp("xmlDumpAttributeTable"); break;
3149                     case OP_XML_DUMP_ENTITY_DECL:
3150                         startOp("xmlDumpEntityDecl"); break;
3151                     case OP_XML_DUMP_ENTITIES_TABLE:
3152                         startOp("xmlDumpEntitiesTable"); break;
3153                     case OP_XML_DUMP_NOTATION_DECL:
3154                         startOp("xmlDumpNotationDecl"); break;
3155                     case OP_XML_DUMP_NOTATION_TABLE:
3156                         startOp("xmlDumpNotationTable"); break;
3157                     case OP_HTML_NODE_DUMP:
3158                         startOp("htmlNodeDump"); break;
3159                 }
3160 
3161                 incStrIdx();
3162                 buffer = xmlBufferCreate();
3163                 xmlFuzzResetMallocFailed();
3164                 node = getNode(0);
3165                 doc = node ? node->doc : NULL;
3166                 level = getInt(0);
3167                 format = getInt(0);
3168                 res = 0;
3169 
3170                 switch (op) {
3171                     case OP_XML_NODE_DUMP:
3172                         res = xmlNodeDump(buffer, doc, node, level, format);
3173                         break;
3174                     case OP_XML_NODE_BUF_GET_CONTENT:
3175                         res = xmlNodeBufGetContent(buffer, node);
3176                         break;
3177                     case OP_XML_ATTR_SERIALIZE_TXT_CONTENT:
3178                         if (node != NULL && node->type != XML_ATTRIBUTE_NODE)
3179                             node = NULL;
3180                         xmlAttrSerializeTxtContent(
3181                             buffer, doc,
3182                             (xmlAttrPtr) node,
3183                             getStr(1));
3184                         break;
3185                     case OP_XML_DUMP_ELEMENT_DECL:
3186                         if (node != NULL && node->type != XML_ELEMENT_DECL)
3187                             node = NULL;
3188                         xmlDumpElementDecl(buffer, (xmlElementPtr) node);
3189                         break;
3190                     case OP_XML_DUMP_ATTRIBUTE_DECL:
3191                         if (node != NULL && node->type != XML_ATTRIBUTE_DECL)
3192                             node = NULL;
3193                         xmlDumpAttributeDecl(buffer, (xmlAttributePtr) node);
3194                         break;
3195                     case OP_XML_DUMP_NOTATION_DECL:
3196                         /* TODO */
3197                         break;
3198                     case OP_XML_DUMP_ENTITY_DECL:
3199                         if (node != NULL && node->type != XML_ENTITY_DECL)
3200                             node = NULL;
3201                         xmlDumpEntityDecl(buffer, (xmlEntityPtr) node);
3202                         break;
3203                     case OP_XML_DUMP_ELEMENT_TABLE: {
3204                         xmlElementTablePtr table;
3205 
3206                         table = node != NULL && node->type == XML_DTD_NODE ?
3207                                 ((xmlDtdPtr) node)->elements :
3208                                 NULL;
3209                         xmlDumpElementTable(buffer, table);
3210                         break;
3211                     }
3212                     case OP_XML_DUMP_ATTRIBUTE_TABLE: {
3213                         xmlAttributeTablePtr table;
3214 
3215                         table = node != NULL && node->type == XML_DTD_NODE ?
3216                                 ((xmlDtdPtr) node)->attributes :
3217                                 NULL;
3218                         xmlDumpAttributeTable(buffer, table);
3219                         break;
3220                     }
3221                     case OP_XML_DUMP_NOTATION_TABLE: {
3222                         xmlNotationTablePtr table;
3223 
3224                         table = node != NULL && node->type == XML_DTD_NODE ?
3225                                 ((xmlDtdPtr) node)->notations :
3226                                 NULL;
3227                         xmlDumpNotationTable(buffer, table);
3228                         break;
3229                     }
3230                     case OP_XML_DUMP_ENTITIES_TABLE: {
3231                         xmlEntitiesTablePtr table;
3232 
3233                         table = node != NULL && node->type == XML_DTD_NODE ?
3234                                 ((xmlDtdPtr) node)->entities :
3235                                 NULL;
3236                         xmlDumpEntitiesTable(buffer, table);
3237                         break;
3238                     }
3239 #ifdef LIBXML_HTML_ENABLED
3240                     case OP_HTML_NODE_DUMP:
3241                         res = htmlNodeDump(buffer, doc, node);
3242                         break;
3243 #endif /* LIBXML_HTML_ENABLED */
3244                 }
3245 
3246                 dump = xmlBufferDetach(buffer);
3247                 if (res == 0 && dump != NULL)
3248                     oomReport = 0;
3249                 moveStr(0, dump);
3250                 xmlBufferFree(buffer);
3251                 endOp();
3252                 break;
3253             }
3254 
3255             case OP_XML_SAVE_FILE_TO:
3256             case OP_XML_SAVE_FORMAT_FILE_TO:
3257             case OP_XML_NODE_DUMP_OUTPUT:
3258             case OP_HTML_DOC_CONTENT_DUMP_OUTPUT:
3259             case OP_HTML_DOC_CONTENT_DUMP_FORMAT_OUTPUT:
3260             case OP_HTML_NODE_DUMP_OUTPUT:
3261             case OP_HTML_NODE_DUMP_FORMAT_OUTPUT: {
3262                 xmlNodePtr node;
3263                 xmlDocPtr doc;
3264                 xmlOutputBufferPtr output;
3265                 const char *encoding;
3266                 int level, format, argsOk, res, closed;
3267 
3268                 switch (op) {
3269                     case OP_XML_SAVE_FILE_TO:
3270                         startOp("xmlSaveFileTo"); break;
3271                     case OP_XML_SAVE_FORMAT_FILE_TO:
3272                         startOp("xmlSaveFormatFileTo"); break;
3273                     case OP_XML_NODE_DUMP_OUTPUT:
3274                         startOp("xmlNodeDumpOutput"); break;
3275                     case OP_HTML_DOC_CONTENT_DUMP_OUTPUT:
3276                         startOp("htmlDocContentDumpOutput"); break;
3277                     case OP_HTML_DOC_CONTENT_DUMP_FORMAT_OUTPUT:
3278                         startOp("htmlDocContentDumpFormatOutput"); break;
3279                     case OP_HTML_NODE_DUMP_OUTPUT:
3280                         startOp("htmlNodeDumpOutput"); break;
3281                     case OP_HTML_NODE_DUMP_FORMAT_OUTPUT:
3282                         startOp("htmlNodeDumpFormatOutput"); break;
3283                 }
3284 
3285                 incStrIdx();
3286                 output = xmlAllocOutputBuffer(NULL);
3287                 xmlFuzzResetMallocFailed();
3288                 node = getNode(0);
3289                 doc = node ? node->doc : NULL;
3290                 encoding = (const char *) getStr(1);
3291                 level = getInt(0);
3292                 format = getInt(0);
3293                 argsOk = (output != NULL);
3294                 res = 0;
3295                 closed = 0;
3296 
3297                 switch (op) {
3298                     case OP_XML_SAVE_FILE_TO:
3299                         argsOk &= (doc != NULL);
3300                         res = xmlSaveFileTo(output, doc, encoding);
3301                         closed = 1;
3302                         break;
3303                     case OP_XML_SAVE_FORMAT_FILE_TO:
3304                         argsOk &= (doc != NULL);
3305                         res = xmlSaveFormatFileTo(output, doc, encoding, format);
3306                         closed = 1;
3307                         break;
3308                     case OP_XML_NODE_DUMP_OUTPUT:
3309                         argsOk &= (node != NULL);
3310                         xmlNodeDumpOutput(output, doc, node, level, format,
3311                                           encoding);
3312                         break;
3313 #ifdef LIBXML_HTML_ENABLED
3314                     case OP_HTML_DOC_CONTENT_DUMP_OUTPUT:
3315                         argsOk &= (doc != NULL);
3316                         htmlDocContentDumpOutput(output, doc, encoding);
3317                         break;
3318                     case OP_HTML_DOC_CONTENT_DUMP_FORMAT_OUTPUT:
3319                         argsOk &= (doc != NULL);
3320                         htmlDocContentDumpFormatOutput(output, doc, encoding,
3321                                                        format);
3322                         break;
3323                     case OP_HTML_NODE_DUMP_OUTPUT:
3324                         argsOk &= (node != NULL);
3325                         htmlNodeDumpOutput(output, doc, node, encoding);
3326                         break;
3327                     case OP_HTML_NODE_DUMP_FORMAT_OUTPUT:
3328                         argsOk &= (node != NULL);
3329                         htmlNodeDumpFormatOutput(output, doc, node, encoding,
3330                                                  format);
3331                         break;
3332 #endif /* LIBXML_HTML_ENABLED */
3333                 }
3334 
3335                 if (closed) {
3336                     if (res >= 0)
3337                         oomReport = 0;
3338                     moveStr(0, NULL);
3339                 } else {
3340                     oomReport =
3341                         (output != NULL &&
3342                          output->error == XML_ERR_NO_MEMORY);
3343                     if (argsOk && !output->error)
3344                         copyStr(0, xmlBufContent(output->buffer));
3345                     else
3346                         moveStr(0, NULL);
3347                     xmlOutputBufferClose(output);
3348                 }
3349                 endOp();
3350                 break;
3351             }
3352 #endif /* LIBXML_OUTPUT_ENABLED */
3353 
3354             case OP_XML_DOM_WRAP_RECONCILE_NAMESPACES: {
3355                 xmlNodePtr node;
3356                 int res;
3357 
3358                 startOp("xmlDOMWrapReconcileNamespaces");
3359                 res = xmlDOMWrapReconcileNamespaces(
3360                     NULL,
3361                     node = getNode(0),
3362                     getInt(0));
3363                 oomReport =
3364                     (node != NULL &&
3365                      node->doc != NULL &&
3366                      node->type == XML_ELEMENT_NODE &&
3367                      res < 0);
3368                 endOp();
3369                 break;
3370             }
3371 
3372             case OP_XML_DOM_WRAP_ADOPT_NODE: {
3373                 xmlDOMWrapCtxtPtr ctxt;
3374                 xmlDocPtr doc, destDoc, oldDoc;
3375                 xmlNodePtr node, destParent, oldParent;
3376                 int res;
3377 
3378                 startOp("xmlDOMWrapAdoptNode");
3379                 ctxt = xmlDOMWrapNewCtxt();
3380                 doc = getDoc(0);
3381                 node = getNode(1);
3382                 destDoc = getDoc(2);
3383                 destParent = getNode(3);
3384 
3385                 if (!isValidChild(destParent, node))
3386                     destParent = NULL;
3387 
3388                 oldParent = node ? node->parent : NULL;
3389                 oldDoc = node ? node->doc : NULL;
3390 
3391                 res = xmlDOMWrapAdoptNode(
3392                     ctxt,
3393                     doc,
3394                     node,
3395                     destDoc,
3396                     destParent,
3397                     getInt(0));
3398                 if (ctxt == NULL)
3399                     oomReport = 1;
3400                 else if (res == 0)
3401                     oomReport = 0;
3402 
3403                 if (node != NULL) {
3404                     /* Node can reference destParent's namespaces */
3405                     if (destParent != NULL &&
3406                         node->parent == NULL &&
3407                         node->doc == destParent->doc) {
3408                         if (node->type == XML_ATTRIBUTE_NODE) {
3409                             xmlNodePtr prop;
3410 
3411                             /* Insert without removing duplicates */
3412                             node->parent = destParent;
3413                             prop = (xmlNodePtr) destParent->properties;
3414                             node->next = prop;
3415                             if (prop != NULL)
3416                                 prop->prev = node;
3417                             destParent->properties = (xmlAttrPtr) node;
3418                         } else if (node->type != XML_TEXT_NODE) {
3419                             xmlAddChild(destParent, node);
3420                         }
3421                     }
3422 
3423                     /* Node can be unlinked and moved to a new document. */
3424                     if (oldParent != NULL && node->parent != oldParent)
3425                         dropNode(oldParent);
3426                     else if (node->doc != oldDoc)
3427                         dropNode((xmlNodePtr) oldDoc);
3428                 }
3429 
3430                 xmlDOMWrapFreeCtxt(ctxt);
3431                 endOp();
3432                 break;
3433             }
3434 
3435             case OP_XML_DOM_WRAP_REMOVE_NODE: {
3436                 xmlDocPtr doc;
3437                 xmlNodePtr node, oldParent;
3438                 int res;
3439 
3440                 startOp("xmlDOMWrapRemoveNode");
3441                 doc = getDoc(0);
3442                 node = getNode(1);
3443                 oldParent = node ? node->parent : NULL;
3444                 res = xmlDOMWrapRemoveNode(NULL, doc, node, 0);
3445                 oomReport =
3446                     (node != NULL &&
3447                      doc != NULL &&
3448                      node->doc == doc &&
3449                      res < 0);
3450                 if (node != NULL && node->parent != oldParent) {
3451                     if (fixNs(node) < 0)
3452                         oomReport = 1;
3453                     dropNode(oldParent);
3454                 }
3455                 endOp();
3456                 break;
3457             }
3458 
3459             case OP_XML_DOM_WRAP_CLONE_NODE: {
3460                 xmlDOMWrapCtxtPtr ctxt;
3461                 xmlDocPtr doc, destDoc;
3462                 xmlNodePtr node, destParent, copy = NULL;
3463                 int res;
3464 
3465                 startOp("xmlDOMWrapCloneNode");
3466                 incNodeIdx();
3467                 ctxt = xmlDOMWrapNewCtxt();
3468                 doc = getDoc(1);
3469                 node = getNode(2);
3470                 destDoc = getDoc(3);
3471                 destParent = getNode(4);
3472 
3473                 if (destParent != NULL &&
3474                     node != NULL &&
3475                     !isValidChildType(destParent, node->type))
3476                     destParent = NULL;
3477 
3478                 /* xmlDOMWrapCloneNode returns a garbage node on error. */
3479                 res = xmlDOMWrapCloneNode(
3480                     ctxt,
3481                     doc,
3482                     node,
3483                     &copy,
3484                     destDoc,
3485                     destParent,
3486                     getInt(0),
3487                     0);
3488                 if (ctxt == NULL)
3489                     oomReport = 1;
3490                 else if (res == 0)
3491                     oomReport = 0;
3492                 copy = checkCopy(copy);
3493 
3494                 /* Copy can reference destParent's namespaces */
3495                 if (destParent != NULL && copy != NULL) {
3496                     if (copy->type == XML_ATTRIBUTE_NODE) {
3497                         xmlNodePtr prop;
3498 
3499                         /* Insert without removing duplicates */
3500                         copy->parent = destParent;
3501                         prop = (xmlNodePtr) destParent->properties;
3502                         copy->next = prop;
3503                         if (prop != NULL)
3504                             prop->prev = copy;
3505                         destParent->properties = (xmlAttrPtr) copy;
3506                     } else if (copy->type != XML_TEXT_NODE) {
3507                         xmlAddChild(destParent, copy);
3508                     }
3509                 }
3510 
3511                 xmlDOMWrapFreeCtxt(ctxt);
3512                 setNode(0, copy);
3513                 break;
3514             }
3515 
3516             case OP_XML_CHILD_ELEMENT_COUNT:
3517                 startOp("xmlChildElementCount");
3518                 incIntIdx();
3519                 setInt(0, xmlChildElementCount(getNode(0)));
3520                 oomReport = 0;
3521                 break;
3522 
3523             case OP_XML_FIRST_ELEMENT_CHILD:
3524                 startOp("xmlFirstElementChild");
3525                 incNodeIdx();
3526                 setNode(0, xmlFirstElementChild(getNode(1)));
3527                 oomReport = 0;
3528                 break;
3529 
3530             case OP_XML_LAST_ELEMENT_CHILD:
3531                 startOp("xmlLastElementChild");
3532                 incNodeIdx();
3533                 setNode(0, xmlLastElementChild(getNode(1)));
3534                 oomReport = 0;
3535                 break;
3536 
3537             case OP_XML_NEXT_ELEMENT_SIBLING:
3538                 startOp("xmlNextElementSibling");
3539                 incNodeIdx();
3540                 setNode(0, xmlNextElementSibling(getNode(1)));
3541                 oomReport = 0;
3542                 break;
3543 
3544             case OP_XML_PREVIOUS_ELEMENT_SIBLING:
3545                 startOp("xmlPreviousElementSibling");
3546                 incNodeIdx();
3547                 setNode(0, xmlPreviousElementSibling(getNode(1)));
3548                 oomReport = 0;
3549                 break;
3550 
3551             default:
3552                 break;
3553         }
3554 
3555         xmlFuzzCheckMallocFailure(vars->opName, oomReport);
3556     }
3557 
3558     for (i = 0; i < REG_MAX; i++)
3559         xmlFree(vars->strings[i]);
3560 
3561     for (i = 0; i < REG_MAX; i++) {
3562         xmlNodePtr node = vars->nodes[i];
3563 
3564         vars->nodes[i] = NULL;
3565         dropNode(node);
3566     }
3567 
3568     xmlFuzzMemSetLimit(0);
3569     xmlFuzzDataCleanup();
3570     xmlResetLastError();
3571     return(0);
3572 }
3573 
3574