Coverage Report

Created: 2026-09-14 06:09

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