Coverage Report

Created: 2025-10-10 06:44

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
93.4k
#define MAX_CONTENT     100
59
20.6k
#define MAX_COPY_NODES   50
60
50.4k
#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
2.49k
#define NODE_MASK_TEXT_CONTENT ( \
305
2.49k
    (1 << XML_TEXT_NODE) | \
306
2.49k
    (1 << XML_CDATA_SECTION_NODE) | \
307
2.49k
    (1 << XML_COMMENT_NODE) | \
308
2.49k
    (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
123k
#define CHILD_MASK_DTD ( \
332
123k
    (1 << XML_ELEMENT_DECL) | \
333
123k
    (1 << XML_ATTRIBUTE_DECL) | \
334
123k
    (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
8.84M
#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.04M
startOp(const char *name) {
387
1.04M
    vars->opName = name;
388
1.04M
    DEBUG("%s(", name);
389
1.04M
}
390
391
static void
392
505k
endOp(void) {
393
505k
    DEBUG(" )\n");
394
505k
}
395
396
/* Integers */
397
398
static int
399
631k
getInt(int offset) {
400
631k
    int idx = (vars->intIdx - offset - 1) & REG_MASK;
401
631k
    DEBUG(" %d", vars->integers[idx]);
402
631k
    return vars->integers[idx];
403
631k
}
404
405
static void
406
95.1k
setInt(int offset, int n) {
407
95.1k
    int idx = (vars->intIdx - offset - 1) & REG_MASK;
408
95.1k
    vars->integers[idx] = n;
409
95.1k
}
410
411
static void
412
94.5k
incIntIdx(void) {
413
94.5k
    vars->intIdx = (vars->intIdx + 1) & REG_MASK;
414
94.5k
}
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
373k
        DEBUG(" NULL");
425
924k
    else
426
924k
        DEBUG(" \"%.20s\"", str);
427
428
1.29M
    return str;
429
1.29M
}
430
431
static const char *
432
331k
getCStr(int offset) {
433
331k
    return (const char *) getStr(offset);
434
331k
}
435
436
static void
437
222k
setStr(int offset, xmlChar *str) {
438
222k
    xmlChar **strings = vars->strings;
439
222k
    int idx = (vars->stringIdx - offset - 1) & REG_MASK;
440
222k
    xmlChar *oldString = strings[idx];
441
442
222k
    strings[idx] = str;
443
222k
    if (oldString)
444
72.6k
        xmlFree(oldString);
445
222k
}
446
447
static void
448
157k
moveStr(int offset, xmlChar *str) {
449
157k
    if (xmlStrlen(str) > 1000) {
450
7.55k
        setStr(offset, NULL);
451
7.55k
        xmlFree(str);
452
149k
    } else {
453
149k
        setStr(offset, str);
454
149k
    }
455
157k
}
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
7.07k
        return NULL;
467
468
77.7k
    copy = BAD_CAST strndup((const char *) str, size);
469
77.7k
    if (copy == NULL) {
470
0
        fprintf(stderr, "out of memory\n");
471
0
        abort();
472
0
    }
473
474
77.7k
    return copy;
475
77.7k
}
476
477
static xmlChar *
478
83.3k
uncheckedStrdup(const xmlChar *str) {
479
83.3k
    return uncheckedStrndup(str, MAX_CONTENT);
480
83.3k
}
481
482
static void
483
65.0k
copyStr(int offset, const xmlChar *str) {
484
65.0k
    setStr(offset, uncheckedStrdup(str));
485
65.0k
}
486
487
static void
488
222k
incStrIdx(void) {
489
222k
    vars->stringIdx = (vars->stringIdx + 1) & REG_MASK;
490
222k
}
491
492
/* Nodes */
493
494
static void
495
dropNode(xmlNodePtr node);
496
497
static xmlNodePtr
498
1.15M
getNode(int offset) {
499
1.15M
    int idx = (vars->nodeIdx - offset - 1) & REG_MASK;
500
1.15M
    if (vars->nodes[idx])
501
976k
        DEBUG(" n%d", idx);
502
176k
    else
503
176k
        DEBUG(" NULL");
504
1.15M
    fflush(stdout);
505
1.15M
    return vars->nodes[idx];
506
1.15M
}
507
508
static xmlDocPtr
509
264k
getDoc(int offset) {
510
264k
    xmlNodePtr node = getNode(offset);
511
512
264k
    if (node == NULL)
513
54.4k
        return NULL;
514
209k
    return node->doc;
515
264k
}
516
517
static xmlAttrPtr
518
22.0k
getAttr(int offset) {
519
22.0k
    xmlNodePtr node = getNode(offset);
520
521
22.0k
    if (node == NULL)
522
5.69k
        return NULL;
523
16.3k
    if (node->type == XML_ATTRIBUTE_NODE)
524
6.55k
        return (xmlAttrPtr) node;
525
9.75k
    if (node->type == XML_ELEMENT_NODE)
526
5.92k
        return node->properties;
527
528
3.83k
    return NULL;
529
9.75k
}
530
531
static xmlDtdPtr
532
48.9k
getDtd(int offset) {
533
48.9k
    xmlNodePtr node = getNode(offset);
534
48.9k
    xmlDocPtr doc;
535
536
48.9k
    if (node == NULL)
537
5.89k
        return NULL;
538
539
43.0k
    if (node->type == XML_DTD_NODE)
540
5.88k
        return (xmlDtdPtr) node;
541
542
37.1k
    doc = node->doc;
543
37.1k
    if (doc == NULL)
544
2.59k
        return NULL;
545
34.5k
    if (doc->intSubset != NULL)
546
31.0k
        return doc->intSubset;
547
3.48k
    return doc->extSubset;
548
34.5k
}
549
550
static void
551
537k
setNode(int offset, xmlNodePtr node) {
552
537k
    int idx = (vars->nodeIdx - offset - 1) & REG_MASK;
553
537k
    xmlNodePtr oldNode = vars->nodes[idx];
554
555
537k
    if (node != oldNode) {
556
390k
        vars->nodes[idx] = node;
557
390k
        dropNode(oldNode);
558
390k
    }
559
560
537k
    if (node == NULL)
561
146k
        DEBUG(" ) /* NULL */\n");
562
390k
    else
563
390k
        DEBUG(" ) -> n%d\n", idx);
564
537k
}
565
566
static void
567
538k
incNodeIdx(void) {
568
538k
    xmlNodePtr oldNode;
569
538k
    int idx;
570
571
538k
    idx = vars->nodeIdx & REG_MASK;
572
538k
    vars->nodeIdx = (idx + 1) & REG_MASK;
573
538k
    oldNode = vars->nodes[idx];
574
575
538k
    if (oldNode != NULL) {
576
245k
        vars->nodes[idx] = NULL;
577
245k
        dropNode(oldNode);
578
245k
    }
579
538k
}
580
581
static int
582
83.7k
isValidChildType(xmlNodePtr parent, int childType) {
583
83.7k
    return ((1 << childType) & childMasks[parent->type]) != 0;
584
83.7k
}
585
586
static int
587
52.4k
isValidChild(xmlNodePtr parent, xmlNodePtr child) {
588
52.4k
    xmlNodePtr cur;
589
590
52.4k
    if (child == NULL || parent == NULL)
591
7.68k
        return 1;
592
593
44.7k
    if (parent == child)
594
1.14k
        return 0;
595
596
43.6k
    if (((1 << child->type) & childMasks[parent->type]) == 0)
597
3.46k
        return 0;
598
599
40.1k
    if (child->children == NULL)
600
20.1k
        return 1;
601
602
47.1k
    for (cur = parent->parent; cur != NULL; cur = cur->parent)
603
28.0k
        if (cur == child)
604
927
            return 0;
605
606
19.1k
    return 1;
607
20.0k
}
608
609
static int
610
2.83k
isTextContentNode(xmlNodePtr child) {
611
2.83k
    if (child == NULL)
612
336
        return 0;
613
614
2.49k
    return ((1 << child->type) & NODE_MASK_TEXT_CONTENT) != 0;
615
2.83k
}
616
617
static int
618
126k
isDtdChild(xmlNodePtr child) {
619
126k
    if (child == NULL)
620
3.04k
        return 0;
621
622
123k
    return ((1 << child->type) & CHILD_MASK_DTD) != 0;
623
126k
}
624
625
static xmlNodePtr
626
1.78M
nodeGetTree(xmlNodePtr node) {
627
1.78M
    xmlNodePtr cur = node;
628
629
13.5M
    while (cur->parent)
630
11.7M
        cur = cur->parent;
631
1.78M
    return cur;
632
1.78M
}
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
985k
dropNode(xmlNodePtr node) {
648
985k
    xmlNodePtr *nodes = vars->nodes;
649
985k
    xmlNodePtr tree;
650
985k
    xmlDocPtr doc;
651
985k
    int docReferenced = 0;
652
985k
    int i;
653
654
985k
    if (node == NULL)
655
561k
        return;
656
657
423k
    tree = nodeGetTree(node);
658
423k
    doc = node->doc;
659
660
2.67M
    for (i = 0; i < REG_MAX; i++) {
661
2.44M
        xmlNodePtr other;
662
663
2.44M
        other = nodes[i];
664
2.44M
        if (other == NULL)
665
1.08M
            continue;
666
667
        /*
668
         * Return if tree is referenced from another node
669
         */
670
1.35M
        if (nodeGetTree(other) == tree)
671
187k
            return;
672
1.17M
        if (doc != NULL && other->doc == doc)
673
136k
            docReferenced = 1;
674
1.17M
    }
675
676
236k
    if (tree != (xmlNodePtr) doc && !isDtdChild(tree)) {
677
87.6k
        if (doc == NULL || tree->type != XML_DTD_NODE ||
678
3.32k
            ((xmlDtdPtr) tree != doc->intSubset &&
679
3.14k
             (xmlDtdPtr) tree != doc->extSubset))
680
84.2k
            xmlFreeNode(tree);
681
87.6k
    }
682
683
    /*
684
     * Also free document if it isn't referenced from other nodes
685
     */
686
236k
    if (doc != NULL && !docReferenced)
687
145k
        xmlFreeDoc(doc);
688
236k
}
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
3.30k
removeNode(xmlNodePtr node) {
699
3.30k
    int i;
700
701
29.7k
    for (i = 0; i < REG_MAX; i++)
702
26.4k
        if (vars->nodes[i] == node)
703
9.52k
            vars->nodes[i] = NULL;
704
3.30k
}
705
706
static void
707
38.0k
removeChildren(xmlNodePtr parent, int self) {
708
38.0k
    int i;
709
710
38.0k
    if (parent == NULL || (!self && parent->children == NULL))
711
23.6k
        return;
712
713
130k
    for (i = 0; i < REG_MAX; i++) {
714
115k
        xmlNodePtr node = vars->nodes[i];
715
716
115k
        if (node == parent) {
717
13.9k
            if (self)
718
2.88k
                vars->nodes[i] = NULL;
719
13.9k
            continue;
720
13.9k
        }
721
722
305k
        while (node != NULL) {
723
205k
            node = node->parent;
724
205k
            if (node == parent) {
725
1.94k
                vars->nodes[i] = NULL;
726
1.94k
                break;
727
1.94k
            }
728
205k
        }
729
101k
    }
730
14.4k
}
731
732
static xmlNsPtr
733
149k
nodeGetNs(xmlNodePtr node, int k) {
734
149k
    int i = 0;
735
149k
    xmlNsPtr ns, next;
736
737
149k
    if (node == NULL || node->type != XML_ELEMENT_NODE)
738
53.9k
        return NULL;
739
740
95.8k
    ns = NULL;
741
95.8k
    next = node->nsDef;
742
312k
    while (1) {
743
4.64M
        while (next == NULL) {
744
4.41M
            node = node->parent;
745
4.41M
            if (node == NULL || node->type != XML_ELEMENT_NODE)
746
76.0k
                break;
747
4.33M
            next = node->nsDef;
748
4.33M
        }
749
750
312k
        if (next == NULL)
751
76.0k
            break;
752
753
236k
        ns = next;
754
236k
        if (i == k)
755
19.8k
            break;
756
757
216k
        next = ns->next;
758
216k
        i += 1;
759
216k
    }
760
761
95.8k
    return ns;
762
149k
}
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
43.6k
checkContent(xmlNodePtr node) {
777
43.6k
    if (node != NULL &&
778
42.3k
        (node->type == XML_TEXT_NODE ||
779
35.1k
         node->type == XML_CDATA_SECTION_NODE ||
780
34.7k
         node->type == XML_ENTITY_NODE ||
781
34.7k
         node->type == XML_PI_NODE ||
782
33.3k
         node->type == XML_COMMENT_NODE ||
783
32.2k
         node->type == XML_NOTATION_NODE) &&
784
10.0k
        xmlStrlen(node->content) > MAX_CONTENT) {
785
2.76k
        xmlNodeSetContent(node, NULL);
786
2.76k
        node->content = uncheckedStrdup(BAD_CAST "");
787
2.76k
    }
788
43.6k
}
789
790
static int
791
20.6k
countNodes(xmlNodePtr node) {
792
20.6k
    xmlNodePtr cur;
793
20.6k
    int numNodes;
794
795
20.6k
    if (node == NULL)
796
0
        return 0;
797
798
20.6k
    cur = node;
799
20.6k
    numNodes = 0;
800
801
125k
    while (1) {
802
125k
        numNodes += 1;
803
804
125k
        if (cur->children != NULL &&
805
54.7k
            cur->type != XML_ENTITY_REF_NODE) {
806
53.3k
            cur = cur->children;
807
72.5k
        } else {
808
125k
            while (cur->next == NULL) {
809
74.0k
                if (cur == node)
810
20.6k
                    goto done;
811
53.3k
                cur = cur->parent;
812
53.3k
            }
813
51.8k
            cur = cur->next;
814
51.8k
        }
815
125k
    }
816
817
20.6k
done:
818
20.6k
    return numNodes;
819
20.6k
}
820
821
static xmlNodePtr
822
38.0k
checkCopy(xmlNodePtr copy) {
823
38.0k
    vars->numCopyOps += 1;
824
825
38.0k
    if (copy != NULL &&
826
25.2k
        (vars->numCopyOps > MAX_COPY_OPS ||
827
20.6k
         countNodes(copy) > MAX_COPY_NODES)) {
828
4.84k
        if (copy->type == XML_DOCUMENT_NODE ||
829
4.11k
            copy->type == XML_HTML_DOCUMENT_NODE)
830
1.95k
            xmlFreeDoc((xmlDocPtr) copy);
831
2.89k
        else
832
2.89k
            xmlFreeNode(copy);
833
4.84k
        copy = NULL;
834
4.84k
    }
835
836
38.0k
    return copy;
837
38.0k
}
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
71.2k
fixNs(xmlNodePtr node) {
846
71.2k
    if (node == NULL)
847
3.33k
        return 0;
848
849
67.8k
    if (node->type == XML_ELEMENT_NODE) {
850
54.3k
        return xmlReconciliateNs(node->doc, node);
851
54.3k
    } else if (node->type == XML_ATTRIBUTE_NODE) {
852
8.34k
        xmlNodePtr parent = node->parent;
853
854
8.34k
        if (parent != NULL)
855
6.55k
            return xmlReconciliateNs(parent->doc, parent);
856
1.79k
        else
857
1.79k
            node->ns = NULL;
858
8.34k
    }
859
860
6.98k
    return 0;
861
67.8k
}
862
863
/* Node operations */
864
865
static void
866
24.0k
opNodeAccessor(int op) {
867
24.0k
    xmlNodePtr node;
868
869
24.0k
    switch (op) {
870
7.58k
        case OP_NODE_PARENT:
871
7.58k
            startOp("parent"); break;
872
999
        case OP_NODE_NEXT_SIBLING:
873
999
            startOp("next"); break;
874
1.73k
        case OP_NODE_PREV_SIBLING:
875
1.73k
            startOp("prev"); break;
876
3.83k
        case OP_NODE_FIRST_CHILD:
877
3.83k
            startOp("children"); break;
878
2.36k
        case OP_XML_GET_LAST_CHILD:
879
2.36k
            startOp("xmlGetLastChild"); break;
880
1.88k
        case OP_XML_GET_INT_SUBSET:
881
1.88k
            startOp("xmlGetIntSubset"); break;
882
5.60k
        case OP_XML_DOC_GET_ROOT_ELEMENT:
883
5.60k
            startOp("xmlDocGetRootElement"); break;
884
0
        default:
885
0
            break;
886
24.0k
    }
887
888
24.0k
    incNodeIdx();
889
24.0k
    node = getNode(1);
890
891
24.0k
    if (node != NULL) {
892
20.6k
        switch (op) {
893
7.11k
            case OP_NODE_PARENT:
894
7.11k
                node = node->parent; break;
895
623
            case OP_NODE_NEXT_SIBLING:
896
623
                node = node->next; break;
897
1.37k
            case OP_NODE_PREV_SIBLING:
898
1.37k
                node = node->prev; break;
899
3.31k
            case OP_NODE_FIRST_CHILD:
900
3.31k
                node = node->children; break;
901
1.91k
            case OP_XML_GET_LAST_CHILD:
902
1.91k
                node = xmlGetLastChild(node); break;
903
1.32k
            case OP_XML_GET_INT_SUBSET:
904
1.32k
                node = (xmlNodePtr) xmlGetIntSubset(node->doc); break;
905
5.01k
            case OP_XML_DOC_GET_ROOT_ELEMENT:
906
5.01k
                node = xmlDocGetRootElement(node->doc); break;
907
0
            default:
908
0
                break;
909
20.6k
        }
910
911
        /*
912
         * Don't descend into predefined entities
913
         */
914
20.6k
        if (node != NULL && node->type == XML_ENTITY_DECL) {
915
412
            xmlEntityPtr ent = (xmlEntityPtr) node;
916
917
412
            if (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)
918
194
                node = NULL;
919
412
        }
920
20.6k
    }
921
922
24.0k
    setNode(0, node);
923
24.0k
}
924
925
static void
926
8.71k
opDup(int op) {
927
8.71k
    int offset;
928
929
8.71k
    switch (op) {
930
1.57k
        case OP_DUP_INTEGER:
931
1.57k
            incIntIdx(); break;
932
3.44k
        case OP_DUP_STRING:
933
3.44k
            incStrIdx(); break;
934
3.70k
        case OP_DUP_NODE:
935
3.70k
            incNodeIdx(); break;
936
0
        default:
937
0
            break;
938
8.71k
    }
939
940
8.71k
    offset = (xmlFuzzReadInt(1) + 1) & REG_MASK;
941
942
8.71k
    if (offset != 0) {
943
8.18k
        startOp("dup");
944
8.18k
        switch (op) {
945
1.26k
            case OP_DUP_INTEGER:
946
1.26k
                setInt(0, getInt(offset));
947
1.26k
                endOp();
948
1.26k
                break;
949
3.25k
            case OP_DUP_STRING:
950
3.25k
                copyStr(0, getStr(offset));
951
3.25k
                endOp();
952
3.25k
                break;
953
3.66k
            case OP_DUP_NODE:
954
3.66k
                setNode(0, getNode(offset));
955
3.66k
                break;
956
0
            default:
957
0
                break;
958
8.18k
        }
959
8.18k
    }
960
8.71k
}
961
962
int
963
LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
964
2
                     char ***argv ATTRIBUTE_UNUSED) {
965
2
    xmlFuzzMemSetup();
966
2
    xmlInitParser();
967
2
#ifdef LIBXML_CATALOG_ENABLED
968
2
    xmlInitializeCatalog();
969
2
    xmlCatalogSetDefaults(XML_CATA_ALLOW_NONE);
970
2
#endif
971
2
    xmlSetGenericErrorFunc(NULL, xmlFuzzErrorFunc);
972
973
2
    return 0;
974
2
}
975
976
int
977
37.1k
LLVMFuzzerTestOneInput(const char *data, size_t size) {
978
37.1k
    size_t failurePos;
979
37.1k
    int i;
980
981
37.1k
    if (size > 1000)
982
12
        return 0;
983
984
37.1k
    memset(vars, 0, sizeof(*vars));
985
986
37.1k
    xmlFuzzDataInit(data, size);
987
988
37.1k
    failurePos = xmlFuzzReadInt(4) % (size * 50 + 10);
989
37.1k
    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.18M
    while (xmlFuzzBytesRemaining()) {
1007
1.14M
        size_t readSize;
1008
1.14M
        int op = xmlFuzzReadInt(1);
1009
1.14M
        int oomReport = -1; /* -1 means unknown */
1010
1.14M
        int ioReport = 0;
1011
1012
1.14M
        vars->opName = "[unset]";
1013
1014
1.14M
        switch (op) {
1015
19.1k
            case OP_CREATE_INTEGER:
1016
19.1k
                incIntIdx();
1017
19.1k
                setInt(0, (int) xmlFuzzReadInt(4));
1018
19.1k
                break;
1019
1020
19.7k
            case OP_CREATE_STRING:
1021
19.7k
                incStrIdx();
1022
19.7k
                copyStr(0, BAD_CAST xmlFuzzReadString(&readSize));
1023
19.7k
                break;
1024
1025
1.57k
            case OP_DUP_INTEGER:
1026
5.01k
            case OP_DUP_STRING:
1027
8.71k
            case OP_DUP_NODE:
1028
8.71k
                opDup(op);
1029
8.71k
                break;
1030
1031
165k
            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
165k
                startOp("xmlReadDoc");
1041
165k
                incNodeIdx();
1042
165k
                setNode(0, (xmlNodePtr) xmlReadDoc(
1043
165k
                    getStr(0),
1044
165k
                    getCStr(1),
1045
165k
                    getCStr(2),
1046
165k
                    getInt(0)));
1047
165k
                break;
1048
1049
7.78k
            case OP_XML_NEW_DOC: {
1050
7.78k
                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.78k
                startOp("xmlNewDoc");
1058
7.78k
                incNodeIdx();
1059
7.78k
                doc = xmlNewDoc(getStr(0));
1060
7.78k
                oomReport = (doc == NULL);
1061
7.78k
                setNode(0, (xmlNodePtr) doc);
1062
7.78k
                break;
1063
5.01k
            }
1064
1065
5.17k
            case OP_XML_NEW_NODE: {
1066
5.17k
                xmlNodePtr node;
1067
5.17k
                const xmlChar *name;
1068
1069
5.17k
                startOp("xmlNewNode");
1070
5.17k
                incNodeIdx();
1071
5.17k
                node = xmlNewNode(
1072
5.17k
                    nodeGetNs(getNode(1), getInt(0)),
1073
5.17k
                    name = getStr(0));
1074
5.17k
                oomReport = (name != NULL && node == NULL);
1075
5.17k
                if (fixNs(node) < 0)
1076
2
                    oomReport = 1;
1077
5.17k
                setNode(0, node);
1078
5.17k
                break;
1079
5.01k
            }
1080
1081
4.85k
            case OP_XML_NEW_NODE_EAT_NAME: {
1082
4.85k
                xmlNodePtr node;
1083
4.85k
                xmlChar *name;
1084
1085
4.85k
                startOp("xmlNewNodeEatName");
1086
4.85k
                incNodeIdx();
1087
4.85k
                node = xmlNewNodeEatName(
1088
4.85k
                    nodeGetNs(getNode(1), getInt(0)),
1089
4.85k
                    name = uncheckedStrdup(getStr(0)));
1090
4.85k
                oomReport = (name != NULL && node == NULL);
1091
4.85k
                if (fixNs(node) < 0)
1092
1
                    oomReport = 1;
1093
4.85k
                setNode(0, node);
1094
4.85k
                break;
1095
5.01k
            }
1096
1097
8.74k
            case OP_XML_NEW_DOC_NODE: {
1098
8.74k
                xmlNodePtr node;
1099
8.74k
                const xmlChar *name;
1100
1101
8.74k
                startOp("xmlNewDocNode");
1102
8.74k
                incNodeIdx();
1103
8.74k
                node = xmlNewDocNode(
1104
8.74k
                    getDoc(1),
1105
8.74k
                    nodeGetNs(getNode(2), getInt(0)),
1106
8.74k
                    name = getStr(0),
1107
8.74k
                    getStr(1));
1108
8.74k
                oomReport = (name != NULL && node == NULL);
1109
8.74k
                if (fixNs(node) < 0)
1110
2
                    oomReport = 1;
1111
8.74k
                setNode(0, node);
1112
8.74k
                break;
1113
5.01k
            }
1114
1115
5.01k
            case OP_XML_NEW_DOC_NODE_EAT_NAME: {
1116
5.01k
                xmlNodePtr node;
1117
5.01k
                xmlChar *name;
1118
1119
5.01k
                startOp("xmlNewDocNodeEatName");
1120
5.01k
                incNodeIdx();
1121
5.01k
                node = xmlNewDocNodeEatName(
1122
5.01k
                    getDoc(1),
1123
5.01k
                    nodeGetNs(getNode(2), getInt(0)),
1124
5.01k
                    name = uncheckedStrdup(getStr(0)),
1125
5.01k
                    getStr(1));
1126
5.01k
                oomReport = (name != NULL && node == NULL);
1127
5.01k
                if (fixNs(node) < 0)
1128
1
                    oomReport = 1;
1129
5.01k
                setNode(0, node);
1130
5.01k
                break;
1131
5.01k
            }
1132
1133
17.1k
            case OP_XML_NEW_DOC_RAW_NODE: {
1134
17.1k
                xmlNodePtr node;
1135
17.1k
                const xmlChar *name;
1136
1137
17.1k
                startOp("xmlNewDocRawNode");
1138
17.1k
                incNodeIdx();
1139
17.1k
                node = xmlNewDocRawNode(
1140
17.1k
                    getDoc(1),
1141
17.1k
                    nodeGetNs(getNode(2), getInt(0)),
1142
17.1k
                    name = getStr(0),
1143
17.1k
                    getStr(1));
1144
17.1k
                oomReport = (name != NULL && node == NULL);
1145
17.1k
                if (fixNs(node) < 0)
1146
5
                    oomReport = 1;
1147
17.1k
                setNode(0, node);
1148
17.1k
                break;
1149
5.01k
            }
1150
1151
21.5k
            case OP_XML_NEW_CHILD: {
1152
21.5k
                xmlNodePtr parent, node;
1153
21.5k
                const xmlChar *name;
1154
1155
21.5k
                startOp("xmlNewChild");
1156
21.5k
                incNodeIdx();
1157
                /* Use parent namespace without fixup */
1158
21.5k
                node = xmlNewChild(
1159
21.5k
                    parent = getNode(1),
1160
21.5k
                    nodeGetNs(getNode(1), getInt(0)),
1161
21.5k
                    name = getStr(0),
1162
21.5k
                    getStr(1));
1163
21.5k
                oomReport =
1164
21.5k
                    (parent != NULL &&
1165
20.8k
                     isValidChildType(parent, XML_ELEMENT_NODE) &&
1166
20.2k
                     name != NULL &&
1167
19.9k
                     node == NULL);
1168
21.5k
                setNode(0, node);
1169
21.5k
                break;
1170
5.01k
            }
1171
1172
52.8k
            case OP_XML_NEW_TEXT_CHILD: {
1173
52.8k
                xmlNodePtr parent, node;
1174
52.8k
                const xmlChar *name;
1175
1176
52.8k
                startOp("xmlNewTextChild");
1177
52.8k
                incNodeIdx();
1178
                /* Use parent namespace without fixup */
1179
52.8k
                node = xmlNewTextChild(
1180
52.8k
                    parent = getNode(1),
1181
52.8k
                    nodeGetNs(getNode(1), getInt(0)),
1182
52.8k
                    name = getStr(0),
1183
52.8k
                    getStr(1));
1184
52.8k
                oomReport =
1185
52.8k
                    (parent != NULL &&
1186
51.9k
                     isValidChildType(parent, XML_ELEMENT_NODE) &&
1187
51.5k
                     name != NULL &&
1188
51.2k
                     node == NULL);
1189
52.8k
                setNode(0, node);
1190
52.8k
                break;
1191
5.01k
            }
1192
1193
3.66k
            case OP_XML_NEW_PROP: {
1194
3.66k
                xmlNodePtr parent;
1195
3.66k
                xmlAttrPtr attr;
1196
3.66k
                const xmlChar *name;
1197
1198
3.66k
                startOp("xmlNewProp");
1199
3.66k
                incNodeIdx();
1200
3.66k
                attr = xmlNewProp(
1201
3.66k
                    parent = getNode(1),
1202
3.66k
                    name = getStr(0),
1203
3.66k
                    getStr(1));
1204
3.66k
                oomReport =
1205
3.66k
                    ((parent == NULL || parent->type == XML_ELEMENT_NODE) &&
1206
3.23k
                     name != NULL &&
1207
2.97k
                     attr == NULL);
1208
3.66k
                setNode(0, (xmlNodePtr) attr);
1209
3.66k
                break;
1210
5.01k
            }
1211
1212
2.98k
            case OP_XML_NEW_DOC_PROP: {
1213
2.98k
                xmlAttrPtr attr;
1214
2.98k
                const xmlChar *name;
1215
1216
2.98k
                startOp("xmlNewDocProp");
1217
2.98k
                incNodeIdx();
1218
2.98k
                attr = xmlNewDocProp(
1219
2.98k
                    getDoc(1),
1220
2.98k
                    name = getStr(0),
1221
2.98k
                    getStr(1));
1222
2.98k
                oomReport = (name != NULL && attr == NULL);
1223
2.98k
                setNode(0, (xmlNodePtr) attr);
1224
2.98k
                break;
1225
5.01k
            }
1226
1227
6.68k
            case OP_XML_NEW_NS_PROP: {
1228
6.68k
                xmlAttrPtr attr;
1229
1230
6.68k
                startOp("xmlNewNsProp");
1231
6.68k
                incNodeIdx();
1232
6.68k
                attr = xmlNewNsProp(
1233
6.68k
                    getNode(1),
1234
6.68k
                    nodeGetNs(getNode(1), getInt(0)),
1235
6.68k
                    getStr(0),
1236
6.68k
                    getStr(1));
1237
                /* xmlNewNsProp returns NULL on duplicate prefixes. */
1238
6.68k
                if (attr != NULL)
1239
6.05k
                    oomReport = 0;
1240
6.68k
                setNode(0, (xmlNodePtr) attr);
1241
6.68k
                break;
1242
5.01k
            }
1243
1244
5.72k
            case OP_XML_NEW_NS_PROP_EAT_NAME: {
1245
5.72k
                xmlAttrPtr attr;
1246
1247
5.72k
                startOp("xmlNewNsPropEatName");
1248
5.72k
                incNodeIdx();
1249
5.72k
                attr = xmlNewNsPropEatName(
1250
5.72k
                    getNode(1),
1251
5.72k
                    nodeGetNs(getNode(1), getInt(0)),
1252
5.72k
                    uncheckedStrdup(getStr(0)),
1253
5.72k
                    getStr(1));
1254
5.72k
                if (attr != NULL)
1255
4.45k
                    oomReport = 0;
1256
5.72k
                setNode(0, (xmlNodePtr) attr);
1257
5.72k
                break;
1258
5.01k
            }
1259
1260
2.17k
            case OP_XML_NEW_TEXT: {
1261
2.17k
                xmlNodePtr node;
1262
1263
2.17k
                startOp("xmlNewText");
1264
2.17k
                incNodeIdx();
1265
2.17k
                node = xmlNewText(getStr(0));
1266
2.17k
                oomReport = (node == NULL);
1267
2.17k
                setNode(0, node);
1268
2.17k
                break;
1269
5.01k
            }
1270
1271
4.01k
            case OP_XML_NEW_TEXT_LEN: {
1272
4.01k
                xmlNodePtr node;
1273
4.01k
                const xmlChar *text;
1274
1275
4.01k
                startOp("xmlNewTextLen");
1276
4.01k
                incNodeIdx();
1277
4.01k
                text = getStr(0);
1278
4.01k
                node = xmlNewTextLen(text, xmlStrlen(text));
1279
4.01k
                oomReport = (node == NULL);
1280
4.01k
                setNode(0, node);
1281
4.01k
                break;
1282
5.01k
            }
1283
1284
2.39k
            case OP_XML_NEW_DOC_TEXT: {
1285
2.39k
                xmlNodePtr node;
1286
1287
2.39k
                startOp("xmlNewDocText");
1288
2.39k
                incNodeIdx();
1289
2.39k
                node = xmlNewDocText(getDoc(1), getStr(0));
1290
2.39k
                oomReport = (node == NULL);
1291
2.39k
                setNode(0, node);
1292
2.39k
                break;
1293
5.01k
            }
1294
1295
3.36k
            case OP_XML_NEW_DOC_TEXT_LEN: {
1296
3.36k
                xmlDocPtr doc;
1297
3.36k
                xmlNodePtr node;
1298
3.36k
                const xmlChar *text;
1299
1300
3.36k
                startOp("xmlNewDocTextLen");
1301
3.36k
                incNodeIdx();
1302
3.36k
                doc = getDoc(1);
1303
3.36k
                text = getStr(0);
1304
3.36k
                node = xmlNewDocTextLen(doc, text, xmlStrlen(text));
1305
3.36k
                oomReport = (node == NULL);
1306
3.36k
                setNode(0, node);
1307
3.36k
                break;
1308
5.01k
            }
1309
1310
2.95k
            case OP_XML_NEW_PI: {
1311
2.95k
                xmlNodePtr node;
1312
2.95k
                const xmlChar *name;
1313
1314
2.95k
                startOp("xmlNewPI");
1315
2.95k
                incNodeIdx();
1316
2.95k
                node = xmlNewPI(
1317
2.95k
                    name = getStr(0),
1318
2.95k
                    getStr(1));
1319
2.95k
                oomReport = (name != NULL && node == NULL);
1320
2.95k
                setNode(0, node);
1321
2.95k
                break;
1322
5.01k
            }
1323
1324
1.93k
            case OP_XML_NEW_DOC_PI: {
1325
1.93k
                xmlNodePtr node;
1326
1.93k
                const xmlChar *name;
1327
1328
1.93k
                startOp("xmlNewDocPI");
1329
1.93k
                incNodeIdx();
1330
1.93k
                node = xmlNewDocPI(
1331
1.93k
                    getDoc(1),
1332
1.93k
                    name = getStr(0),
1333
1.93k
                    getStr(1));
1334
1.93k
                oomReport = (name != NULL && node == NULL);
1335
1.93k
                setNode(0, node);
1336
1.93k
                break;
1337
5.01k
            }
1338
1339
2.03k
            case OP_XML_NEW_COMMENT: {
1340
2.03k
                xmlNodePtr node;
1341
1342
2.03k
                startOp("xmlNewComment");
1343
2.03k
                incNodeIdx();
1344
2.03k
                node = xmlNewComment(getStr(0));
1345
2.03k
                oomReport = (node == NULL);
1346
2.03k
                setNode(0, node);
1347
2.03k
                break;
1348
5.01k
            }
1349
1350
3.85k
            case OP_XML_NEW_DOC_COMMENT: {
1351
3.85k
                xmlNodePtr node;
1352
1353
3.85k
                startOp("xmlNewDocComment");
1354
3.85k
                incNodeIdx();
1355
3.85k
                node = xmlNewDocComment(
1356
3.85k
                    getDoc(1),
1357
3.85k
                    getStr(0));
1358
3.85k
                oomReport = (node == NULL);
1359
3.85k
                setNode(0, node);
1360
3.85k
                break;
1361
5.01k
            }
1362
1363
2.39k
            case OP_XML_NEW_CDATA_BLOCK: {
1364
2.39k
                xmlDocPtr doc;
1365
2.39k
                xmlNodePtr node;
1366
2.39k
                const xmlChar *text;
1367
1368
2.39k
                startOp("xmlNewCDataBlock");
1369
2.39k
                incNodeIdx();
1370
2.39k
                doc = getDoc(1);
1371
2.39k
                text = getStr(0);
1372
2.39k
                node = xmlNewDocTextLen(
1373
2.39k
                    doc,
1374
2.39k
                    text,
1375
2.39k
                    xmlStrlen(text));
1376
2.39k
                oomReport = (node == NULL);
1377
2.39k
                setNode(0, node);
1378
2.39k
                break;
1379
5.01k
            }
1380
1381
2.40k
            case OP_XML_NEW_CHAR_REF: {
1382
2.40k
                xmlNodePtr node;
1383
2.40k
                const xmlChar *name;
1384
1385
2.40k
                startOp("xmlNewCharRef");
1386
2.40k
                incNodeIdx();
1387
2.40k
                node = xmlNewCharRef(
1388
2.40k
                    getDoc(1),
1389
2.40k
                    name = getStr(0));
1390
2.40k
                oomReport = (name != NULL && node == NULL);
1391
2.40k
                setNode(0, node);
1392
2.40k
                break;
1393
5.01k
            }
1394
1395
4.11k
            case OP_XML_NEW_REFERENCE: {
1396
4.11k
                xmlNodePtr node;
1397
4.11k
                const xmlChar *name;
1398
1399
4.11k
                startOp("xmlNewReference");
1400
4.11k
                incNodeIdx();
1401
4.11k
                node = xmlNewReference(
1402
4.11k
                    getDoc(1),
1403
4.11k
                    name = getStr(0));
1404
4.11k
                oomReport = (name != NULL && node == NULL);
1405
4.11k
                setNode(0, node);
1406
4.11k
                break;
1407
5.01k
            }
1408
1409
3.44k
            case OP_XML_NEW_DOC_FRAGMENT: {
1410
3.44k
                xmlNodePtr node;
1411
1412
3.44k
                startOp("xmlNewDocFragment");
1413
3.44k
                incNodeIdx();
1414
3.44k
                node = xmlNewDocFragment(getDoc(1));
1415
3.44k
                oomReport = (node == NULL);
1416
3.44k
                setNode(0, node);
1417
3.44k
                break;
1418
5.01k
            }
1419
1420
3.34k
            case OP_XML_CREATE_INT_SUBSET: {
1421
3.34k
                xmlDocPtr doc;
1422
3.34k
                xmlDtdPtr dtd = NULL;
1423
1424
3.34k
                startOp("xmlCreateIntSubset");
1425
3.34k
                incNodeIdx();
1426
3.34k
                doc = getDoc(1);
1427
3.34k
                if (doc == NULL || doc->intSubset == NULL) {
1428
3.10k
                    dtd = xmlCreateIntSubset(
1429
3.10k
                        doc,
1430
3.10k
                        getStr(0),
1431
3.10k
                        getStr(1),
1432
3.10k
                        getStr(2));
1433
3.10k
                    oomReport = (dtd == NULL);
1434
3.10k
                }
1435
3.34k
                setNode(0, (xmlNodePtr) dtd);
1436
3.34k
                break;
1437
5.01k
            }
1438
1439
6.94k
            case OP_XML_NEW_DTD: {
1440
6.94k
                xmlDocPtr doc;
1441
6.94k
                xmlDtdPtr dtd = NULL;
1442
1443
6.94k
                startOp("xmlNewDtd");
1444
6.94k
                incNodeIdx();
1445
6.94k
                doc = getDoc(1);
1446
6.94k
                if (doc == NULL || doc->extSubset == NULL) {
1447
6.69k
                    dtd = xmlNewDtd(
1448
6.69k
                        doc,
1449
6.69k
                        getStr(0),
1450
6.69k
                        getStr(1),
1451
6.69k
                        getStr(2));
1452
6.69k
                    oomReport = (dtd == NULL);
1453
6.69k
                }
1454
6.94k
                setNode(0, (xmlNodePtr) dtd);
1455
6.94k
                break;
1456
5.01k
            }
1457
1458
3.56k
            case OP_XML_COPY_DOC: {
1459
3.56k
                xmlDocPtr copy;
1460
1461
3.56k
                startOp("xmlCopyDoc");
1462
3.56k
                incNodeIdx();
1463
3.56k
                copy = xmlCopyDoc(
1464
3.56k
                    getDoc(1),
1465
3.56k
                    getInt(0));
1466
                /*
1467
                 * TODO: Copying DTD nodes without a document can
1468
                 * result in an empty list.
1469
                 */
1470
3.56k
                if (copy != NULL)
1471
2.94k
                    oomReport = 0;
1472
3.56k
                setNode(0, checkCopy((xmlNodePtr) copy));
1473
3.56k
                break;
1474
5.01k
            }
1475
1476
4.47k
            case OP_XML_COPY_NODE: {
1477
4.47k
                xmlNodePtr copy;
1478
1479
4.47k
                startOp("xmlCopyNode");
1480
4.47k
                incNodeIdx();
1481
4.47k
                copy = xmlCopyNode(
1482
4.47k
                    getNode(1),
1483
4.47k
                    getInt(0));
1484
4.47k
                if (copy != NULL)
1485
3.29k
                    oomReport = 0;
1486
4.47k
                setNode(0, checkCopy((xmlNodePtr) copy));
1487
4.47k
                break;
1488
5.01k
            }
1489
1490
9.11k
            case OP_XML_COPY_NODE_LIST: {
1491
9.11k
                xmlNodePtr copy;
1492
1493
9.11k
                startOp("xmlCopyNodeList");
1494
9.11k
                copy = xmlCopyNodeList(getNode(0));
1495
9.11k
                if (copy != NULL)
1496
7.21k
                    oomReport = 0;
1497
9.11k
                xmlFreeNodeList(copy);
1498
9.11k
                endOp();
1499
9.11k
                break;
1500
5.01k
            }
1501
1502
4.65k
            case OP_XML_DOC_COPY_NODE: {
1503
4.65k
                xmlNodePtr node, copy;
1504
4.65k
                xmlDocPtr doc;
1505
1506
4.65k
                startOp("xmlDocCopyNode");
1507
4.65k
                incNodeIdx();
1508
4.65k
                copy = xmlDocCopyNode(
1509
4.65k
                    node = getNode(1),
1510
4.65k
                    doc = getDoc(2),
1511
4.65k
                    getInt(0));
1512
4.65k
                if (copy != NULL)
1513
2.74k
                    oomReport = 0;
1514
4.65k
                setNode(0, checkCopy((xmlNodePtr) copy));
1515
4.65k
                break;
1516
5.01k
            }
1517
1518
8.23k
            case OP_XML_DOC_COPY_NODE_LIST: {
1519
8.23k
                xmlNodePtr copy;
1520
1521
8.23k
                startOp("xmlDocCopyNodeList");
1522
8.23k
                copy = xmlDocCopyNodeList(
1523
8.23k
                    getDoc(0),
1524
8.23k
                    getNode(1));
1525
8.23k
                if (copy != NULL)
1526
6.50k
                    oomReport = 0;
1527
8.23k
                xmlFreeNodeList(copy);
1528
8.23k
                endOp();
1529
8.23k
                break;
1530
5.01k
            }
1531
1532
3.28k
            case OP_XML_COPY_PROP: {
1533
3.28k
                xmlAttrPtr copy;
1534
1535
3.28k
                startOp("xmlCopyProp");
1536
3.28k
                incNodeIdx();
1537
3.28k
                copy = xmlCopyProp(
1538
3.28k
                    getNode(1),
1539
3.28k
                    getAttr(2));
1540
                /*
1541
                 * TODO: Copying attributes can result in an empty list
1542
                 * if there's a duplicate namespace prefix.
1543
                 */
1544
3.28k
                if (copy != NULL)
1545
478
                    oomReport = 0;
1546
3.28k
                if (copy != NULL) {
1547
                    /* Quirk */
1548
478
                    copy->parent = NULL;
1549
                    /* Fix namespace */
1550
478
                    copy->ns = NULL;
1551
478
                }
1552
3.28k
                setNode(0, checkCopy((xmlNodePtr) copy));
1553
3.28k
                break;
1554
5.01k
            }
1555
1556
3.74k
            case OP_XML_COPY_PROP_LIST: {
1557
3.74k
                xmlAttrPtr copy;
1558
1559
3.74k
                startOp("xmlCopyPropList");
1560
3.74k
                copy = xmlCopyPropList(
1561
3.74k
                    getNode(0),
1562
3.74k
                    getAttr(1));
1563
3.74k
                if (copy != NULL)
1564
971
                    oomReport = 0;
1565
3.74k
                xmlFreePropList(copy);
1566
3.74k
                endOp();
1567
3.74k
                break;
1568
5.01k
            }
1569
1570
5.39k
            case OP_XML_COPY_DTD: {
1571
5.39k
                xmlDtdPtr dtd, copy;
1572
1573
5.39k
                startOp("xmlCopyDtd");
1574
5.39k
                incNodeIdx();
1575
5.39k
                copy = xmlCopyDtd(
1576
5.39k
                    dtd = getDtd(1));
1577
5.39k
                oomReport = (dtd != NULL && copy == NULL);
1578
5.39k
                setNode(0, checkCopy((xmlNodePtr) copy));
1579
5.39k
                break;
1580
5.01k
            }
1581
1582
7.58k
            case OP_NODE_PARENT:
1583
8.58k
            case OP_NODE_NEXT_SIBLING:
1584
10.3k
            case OP_NODE_PREV_SIBLING:
1585
14.1k
            case OP_NODE_FIRST_CHILD:
1586
16.5k
            case OP_XML_GET_LAST_CHILD:
1587
18.4k
            case OP_XML_GET_INT_SUBSET:
1588
24.0k
            case OP_XML_DOC_GET_ROOT_ELEMENT:
1589
24.0k
                opNodeAccessor(op);
1590
24.0k
                oomReport = 0;
1591
24.0k
                break;
1592
1593
11.5k
            case OP_NODE_NAME: {
1594
11.5k
                xmlNodePtr node;
1595
1596
11.5k
                startOp("name");
1597
11.5k
                incStrIdx();
1598
11.5k
                node = getNode(0);
1599
11.5k
                copyStr(0, node ? node->name : NULL);
1600
11.5k
                oomReport = 0;
1601
11.5k
                endOp();
1602
11.5k
                break;
1603
18.4k
            }
1604
1605
4.11k
            case OP_XML_NODE_SET_NAME:
1606
4.11k
                startOp("xmlNodeSetName");
1607
4.11k
                xmlNodeSetName(
1608
4.11k
                    getNode(0),
1609
4.11k
                    getStr(0));
1610
4.11k
                endOp();
1611
4.11k
                break;
1612
1613
6.52k
            case OP_XML_NODE_GET_CONTENT: {
1614
6.52k
                xmlChar *content;
1615
1616
6.52k
                incStrIdx();
1617
6.52k
                startOp("xmlNodeGetContent");
1618
6.52k
                content = xmlNodeGetContent(getNode(0));
1619
6.52k
                if (content != NULL)
1620
5.68k
                    oomReport = 0;
1621
6.52k
                moveStr(0, content);
1622
6.52k
                endOp();
1623
6.52k
                break;
1624
18.4k
            }
1625
1626
4.62k
            case OP_XML_NODE_SET_CONTENT: {
1627
4.62k
                xmlNodePtr node;
1628
4.62k
                int res;
1629
1630
4.62k
                startOp("xmlNodeSetContent");
1631
4.62k
                node = getNode(0);
1632
4.62k
                removeChildren(node, 0);
1633
4.62k
                res = xmlNodeSetContent(
1634
4.62k
                    node,
1635
4.62k
                    getStr(0));
1636
4.62k
                oomReport = (res < 0);
1637
4.62k
                endOp();
1638
4.62k
                break;
1639
18.4k
            }
1640
1641
4.97k
            case OP_XML_NODE_SET_CONTENT_LEN: {
1642
4.97k
                xmlNodePtr node;
1643
4.97k
                const xmlChar *content;
1644
4.97k
                int res;
1645
1646
4.97k
                startOp("xmlNodeSetContentLen");
1647
4.97k
                node = getNode(0);
1648
4.97k
                content = getStr(0);
1649
4.97k
                removeChildren(node, 0);
1650
4.97k
                res = xmlNodeSetContentLen(
1651
4.97k
                    node,
1652
4.97k
                    content,
1653
4.97k
                    xmlStrlen(content));
1654
4.97k
                oomReport = (res < 0);
1655
4.97k
                endOp();
1656
4.97k
                break;
1657
18.4k
            }
1658
1659
33.3k
            case OP_XML_NODE_ADD_CONTENT: {
1660
33.3k
                xmlNodePtr node, text;
1661
33.3k
                int res;
1662
1663
33.3k
                startOp("xmlNodeAddContent");
1664
33.3k
                node = getNode(0);
1665
33.3k
                res = xmlNodeAddContent(
1666
33.3k
                    node,
1667
33.3k
                    getStr(0));
1668
33.3k
                oomReport = (res < 0);
1669
33.3k
                if (node != NULL) {
1670
32.1k
                    if (node->type == XML_ELEMENT_NODE ||
1671
30.2k
                        node->type == XML_DOCUMENT_FRAG_NODE)
1672
2.17k
                        text = node->last;
1673
29.9k
                    else
1674
29.9k
                        text = node;
1675
32.1k
                    checkContent(text);
1676
32.1k
                }
1677
33.3k
                endOp();
1678
33.3k
                break;
1679
18.4k
            }
1680
1681
5.84k
            case OP_XML_NODE_ADD_CONTENT_LEN: {
1682
5.84k
                xmlNodePtr node, text;
1683
5.84k
                const xmlChar *content;
1684
5.84k
                int res;
1685
1686
5.84k
                startOp("xmlNodeAddContentLen");
1687
5.84k
                node = getNode(0);
1688
5.84k
                content = getStr(0);
1689
5.84k
                res = xmlNodeAddContentLen(
1690
5.84k
                    node,
1691
5.84k
                    content,
1692
5.84k
                    xmlStrlen(content));
1693
5.84k
                oomReport = res < 0;
1694
5.84k
                if (node != NULL) {
1695
5.39k
                    if (node->type == XML_ELEMENT_NODE ||
1696
3.83k
                        node->type == XML_DOCUMENT_FRAG_NODE)
1697
2.02k
                        text = node->last;
1698
3.36k
                    else
1699
3.36k
                        text = node;
1700
5.39k
                    checkContent(text);
1701
5.39k
                }
1702
5.84k
                endOp();
1703
5.84k
                break;
1704
18.4k
            }
1705
1706
2.99k
            case OP_XML_GET_LINE_NO:
1707
2.99k
                incIntIdx();
1708
2.99k
                startOp("xmlGetLineNo");
1709
2.99k
                setInt(0, xmlGetLineNo(getNode(0)));
1710
2.99k
                oomReport = 0;
1711
2.99k
                endOp();
1712
2.99k
                break;
1713
1714
8.51k
            case OP_XML_GET_NODE_PATH: {
1715
8.51k
                xmlChar *path;
1716
1717
8.51k
                incStrIdx();
1718
8.51k
                startOp("xmlGetNodePath");
1719
8.51k
                path = xmlGetNodePath(getNode(0));
1720
8.51k
                if (path != NULL)
1721
7.65k
                    oomReport = 0;
1722
8.51k
                moveStr(0, path);
1723
8.51k
                endOp();
1724
8.51k
                break;
1725
18.4k
            }
1726
1727
4.48k
            case OP_XML_DOC_SET_ROOT_ELEMENT: {
1728
4.48k
                xmlDocPtr oldDoc, doc;
1729
4.48k
                xmlNodePtr oldRoot, oldParent, root;
1730
1731
4.48k
                startOp("xmlDocSetRootElement");
1732
4.48k
                incNodeIdx();
1733
4.48k
                doc = getDoc(1);
1734
4.48k
                root = getNode(2);
1735
4.48k
                if (doc != NULL && doc->parent != NULL)
1736
0
                    doc = NULL;
1737
4.48k
                if (!isValidChild((xmlNodePtr) doc, root))
1738
453
                    root = NULL;
1739
4.48k
                oldDoc = root ? root->doc : NULL;
1740
4.48k
                oldParent = root ? root->parent : NULL;
1741
1742
4.48k
                oldRoot = xmlDocSetRootElement(doc, root);
1743
                /* We can't really know whether xmlSetTreeDoc failed */
1744
4.48k
                if (oldRoot != NULL ||
1745
1.79k
                    root == NULL ||
1746
745
                    root->doc == oldDoc)
1747
4.08k
                    oomReport = 0;
1748
4.48k
                setNode(0, oldRoot);
1749
1750
4.48k
                if (root &&
1751
3.43k
                    (root->parent != oldParent ||
1752
2.48k
                     root->doc != oldDoc)) {
1753
2.48k
                    if (fixNs(root) < 0)
1754
2
                        oomReport = 1;
1755
2.48k
                    if (oldParent != NULL)
1756
588
                        dropNode(oldParent);
1757
1.89k
                    else
1758
1.89k
                        dropNode((xmlNodePtr) oldDoc);
1759
2.48k
                }
1760
4.48k
                endOp();
1761
4.48k
                break;
1762
18.4k
            }
1763
1764
771
            case OP_XML_NODE_IS_TEXT:
1765
771
                incIntIdx();
1766
771
                startOp("xmlNodeIsText");
1767
771
                setInt(0, xmlNodeIsText(getNode(0)));
1768
771
                oomReport = 0;
1769
771
                endOp();
1770
771
                break;
1771
1772
1.28k
            case OP_XML_NODE_GET_ATTR_VALUE: {
1773
1.28k
                xmlChar *value = NULL;
1774
1.28k
                int res;
1775
1776
1.28k
                incStrIdx();
1777
1.28k
                startOp("xmlNodeGetAttrValue");
1778
1.28k
                res = xmlNodeGetAttrValue(
1779
1.28k
                    getNode(0),
1780
1.28k
                    getStr(1),
1781
1.28k
                    getStr(2),
1782
1.28k
                    &value);
1783
1.28k
                oomReport = (res < 0);
1784
1.28k
                moveStr(0, value);
1785
1.28k
                endOp();
1786
1.28k
                break;
1787
18.4k
            }
1788
1789
2.91k
            case OP_XML_NODE_GET_LANG: {
1790
2.91k
                xmlChar *lang;
1791
1792
2.91k
                incStrIdx();
1793
2.91k
                startOp("xmlNodeGetLang");
1794
2.91k
                lang = xmlNodeGetLang(getNode(0));
1795
2.91k
                if (lang != NULL)
1796
869
                    oomReport = 0;
1797
2.91k
                moveStr(0, lang);
1798
2.91k
                endOp();
1799
2.91k
                break;
1800
18.4k
            }
1801
1802
6.98k
            case OP_XML_NODE_SET_LANG: {
1803
6.98k
                xmlNodePtr node;
1804
6.98k
                xmlAttrPtr attr;
1805
6.98k
                int res;
1806
1807
6.98k
                startOp("xmlNodeSetLang");
1808
6.98k
                node = getNode(0);
1809
6.98k
                attr = xmlHasNsProp(
1810
6.98k
                    node,
1811
6.98k
                    BAD_CAST "lang",
1812
6.98k
                    XML_XML_NAMESPACE);
1813
6.98k
                xmlFuzzResetFailure();
1814
6.98k
                removeChildren((xmlNodePtr) attr, 0);
1815
6.98k
                res = xmlNodeSetLang(
1816
6.98k
                    node,
1817
6.98k
                    getStr(0));
1818
6.98k
                oomReport = (res < 0);
1819
6.98k
                endOp();
1820
6.98k
                break;
1821
18.4k
            }
1822
1823
3.28k
            case OP_XML_NODE_GET_SPACE_PRESERVE: {
1824
3.28k
                int res;
1825
1826
3.28k
                incIntIdx();
1827
3.28k
                startOp("xmlNodeGetSpacePreserve");
1828
3.28k
                res = xmlNodeGetSpacePreserve(getNode(0));
1829
3.28k
                if (res >= 0)
1830
638
                    oomReport = 0;
1831
3.28k
                setInt(0, res);
1832
3.28k
                endOp();
1833
3.28k
                break;
1834
18.4k
            }
1835
1836
4.10k
            case OP_XML_NODE_SET_SPACE_PRESERVE: {
1837
4.10k
                xmlNodePtr node;
1838
4.10k
                xmlAttrPtr attr;
1839
4.10k
                int res;
1840
1841
4.10k
                startOp("xmlNodeSetSpacePreserve");
1842
4.10k
                node = getNode(0);
1843
4.10k
                attr = xmlHasNsProp(
1844
4.10k
                    node,
1845
4.10k
                    BAD_CAST "space",
1846
4.10k
                    XML_XML_NAMESPACE);
1847
4.10k
                xmlFuzzResetFailure();
1848
4.10k
                removeChildren((xmlNodePtr) attr, 0);
1849
4.10k
                res = xmlNodeSetSpacePreserve(
1850
4.10k
                    node,
1851
4.10k
                    getInt(0));
1852
4.10k
                oomReport = (res < 0);
1853
4.10k
                endOp();
1854
4.10k
                break;
1855
18.4k
            }
1856
1857
4.18k
            case OP_XML_NODE_GET_BASE: {
1858
4.18k
                xmlChar *base;
1859
1860
4.18k
                incStrIdx();
1861
4.18k
                startOp("xmlNodeGetBase");
1862
4.18k
                base = xmlNodeGetBase(
1863
4.18k
                    getDoc(0),
1864
4.18k
                    getNode(1));
1865
4.18k
                if (base != NULL)
1866
2.27k
                    oomReport = 0;
1867
4.18k
                moveStr(0, base);
1868
4.18k
                endOp();
1869
4.18k
                break;
1870
18.4k
            }
1871
1872
5.50k
            case OP_XML_NODE_GET_BASE_SAFE: {
1873
5.50k
                xmlChar *base;
1874
5.50k
                int res;
1875
1876
5.50k
                startOp("xmlNodeGetBaseSafe");
1877
5.50k
                incStrIdx();
1878
5.50k
                res = xmlNodeGetBaseSafe(
1879
5.50k
                    getDoc(0),
1880
5.50k
                    getNode(1),
1881
5.50k
                    &base);
1882
5.50k
                oomReport = (res < 0);
1883
5.50k
                moveStr(0, base);
1884
5.50k
                endOp();
1885
5.50k
                break;
1886
18.4k
            }
1887
1888
10.4k
            case OP_XML_NODE_SET_BASE: {
1889
10.4k
                xmlNodePtr node;
1890
10.4k
                xmlAttrPtr attr;
1891
10.4k
                int res;
1892
1893
10.4k
                startOp("xmlNodeSetBase");
1894
10.4k
                node = getNode(0);
1895
10.4k
                attr = xmlHasNsProp(
1896
10.4k
                    node,
1897
10.4k
                    BAD_CAST "base",
1898
10.4k
                    XML_XML_NAMESPACE);
1899
10.4k
                xmlFuzzResetFailure();
1900
10.4k
                removeChildren((xmlNodePtr) attr, 0);
1901
10.4k
                res = xmlNodeSetBase(
1902
10.4k
                    node,
1903
10.4k
                    getStr(0));
1904
10.4k
                if (res == 0)
1905
7.32k
                    oomReport = 0;
1906
10.4k
                endOp();
1907
10.4k
                break;
1908
18.4k
            }
1909
1910
983
            case OP_XML_IS_BLANK_NODE:
1911
983
                startOp("xmlIsBlankNode");
1912
983
                incNodeIdx();
1913
983
                setInt(0, xmlIsBlankNode(getNode(0)));
1914
983
                oomReport = 0;
1915
983
                break;
1916
1917
1.55k
            case OP_XML_HAS_PROP: {
1918
1.55k
                xmlNodePtr node;
1919
1.55k
                xmlAttrPtr attr;
1920
1921
1.55k
                startOp("xmlHasProp");
1922
1.55k
                incNodeIdx();
1923
1.55k
                attr = xmlHasProp(
1924
1.55k
                    node = getNode(1),
1925
1.55k
                    getStr(0));
1926
1.55k
                if (node != NULL &&
1927
1.05k
                    node->doc != NULL &&
1928
771
                    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
569
                    if (attr != NULL)
1935
332
                        oomReport = 0;
1936
984
                } else {
1937
984
                    oomReport = 0;
1938
984
                }
1939
1.55k
                setNode(0, (xmlNodePtr) attr);
1940
1.55k
                break;
1941
18.4k
            }
1942
1943
1.58k
            case OP_XML_HAS_NS_PROP: {
1944
1.58k
                xmlNodePtr node;
1945
1.58k
                xmlAttrPtr attr;
1946
1947
1.58k
                startOp("xmlHasNsProp");
1948
1.58k
                incNodeIdx();
1949
1.58k
                attr = xmlHasNsProp(
1950
1.58k
                    node = getNode(1),
1951
1.58k
                    getStr(0),
1952
1.58k
                    getStr(1));
1953
1.58k
                if (node != NULL &&
1954
904
                    node->doc != NULL &&
1955
649
                    node->doc->intSubset != NULL) {
1956
437
                    if (attr != NULL)
1957
194
                        oomReport = 0;
1958
1.15k
                } else {
1959
1.15k
                    oomReport = 0;
1960
1.15k
                }
1961
1.58k
                setNode(0, (xmlNodePtr) attr);
1962
1.58k
                break;
1963
18.4k
            }
1964
1965
3.58k
            case OP_XML_GET_PROP: {
1966
3.58k
                xmlChar *content;
1967
1968
3.58k
                startOp("xmlGetProp");
1969
3.58k
                incStrIdx();
1970
3.58k
                content = xmlGetProp(
1971
3.58k
                    getNode(0),
1972
3.58k
                    getStr(1));
1973
3.58k
                if (content != NULL)
1974
1.14k
                    oomReport = 0;
1975
3.58k
                moveStr(0, content);
1976
3.58k
                endOp();
1977
3.58k
                break;
1978
18.4k
            }
1979
1980
1.67k
            case OP_XML_GET_NS_PROP: {
1981
1.67k
                xmlChar *content;
1982
1983
1.67k
                startOp("xmlGetNsProp");
1984
1.67k
                incStrIdx();
1985
1.67k
                content = xmlGetNsProp(
1986
1.67k
                    getNode(0),
1987
1.67k
                    getStr(1),
1988
1.67k
                    getStr(2));
1989
1.67k
                if (content != NULL)
1990
527
                    oomReport = 0;
1991
1.67k
                moveStr(0, content);
1992
1.67k
                endOp();
1993
1.67k
                break;
1994
18.4k
            }
1995
1996
1.99k
            case OP_XML_GET_NO_NS_PROP: {
1997
1.99k
                xmlChar *content;
1998
1999
1.99k
                startOp("xmlGetNoNsProp");
2000
1.99k
                incStrIdx();
2001
1.99k
                content = xmlGetNoNsProp(
2002
1.99k
                    getNode(0),
2003
1.99k
                    getStr(1));
2004
1.99k
                if (content != NULL)
2005
847
                    oomReport = 0;
2006
1.99k
                moveStr(0, content);
2007
1.99k
                endOp();
2008
1.99k
                break;
2009
18.4k
            }
2010
2011
5.86k
            case OP_XML_SET_PROP: {
2012
5.86k
                xmlNodePtr node;
2013
5.86k
                xmlAttrPtr oldAttr, attr;
2014
5.86k
                xmlNsPtr ns = NULL;
2015
5.86k
                const xmlChar *name, *value, *localName;
2016
5.86k
                xmlChar *prefix;
2017
5.86k
                int prefixLen;
2018
2019
5.86k
                startOp("xmlSetProp");
2020
5.86k
                incNodeIdx();
2021
5.86k
                node = getNode(1);
2022
5.86k
                name = getStr(0);
2023
5.86k
                value = getStr(1);
2024
2025
                /*
2026
                 * Find the old attribute node which will be deleted.
2027
                 */
2028
5.86k
                localName = xmlSplitQName3(name, &prefixLen);
2029
5.86k
                if (localName != NULL) {
2030
1.48k
                    prefix = uncheckedStrndup(name, prefixLen);
2031
1.48k
                    ns = xmlSearchNs(NULL, node, prefix);
2032
1.48k
                    xmlFree(prefix);
2033
1.48k
                }
2034
5.86k
                if (ns == NULL)
2035
4.90k
                    oldAttr = xmlHasNsProp(node, name, NULL);
2036
962
                else
2037
962
                    oldAttr = xmlHasNsProp(node, localName, ns->href);
2038
5.86k
                xmlFuzzResetFailure();
2039
5.86k
                if (oldAttr != NULL)
2040
1.14k
                    removeChildren((xmlNodePtr) oldAttr, 0);
2041
2042
5.86k
                attr = xmlSetProp(node, name, value);
2043
2044
5.86k
                oomReport =
2045
5.86k
                    (node != NULL && node->type == XML_ELEMENT_NODE &&
2046
3.87k
                     name != NULL &&
2047
3.80k
                     attr == NULL);
2048
5.86k
                setNode(0, (xmlNodePtr) attr);
2049
5.86k
                break;
2050
18.4k
            }
2051
2052
5.97k
            case OP_XML_SET_NS_PROP: {
2053
5.97k
                xmlNodePtr node;
2054
5.97k
                xmlNsPtr ns;
2055
5.97k
                xmlAttrPtr oldAttr, attr;
2056
5.97k
                const xmlChar *name, *value;
2057
2058
5.97k
                startOp("xmlSetNsProp");
2059
5.97k
                incNodeIdx();
2060
5.97k
                node = getNode(1);
2061
5.97k
                ns = nodeGetNs(getNode(2), getInt(0));
2062
5.97k
                name = getStr(0);
2063
5.97k
                value = getStr(1);
2064
5.97k
                oldAttr = xmlHasNsProp(node, name, ns ? ns->href : NULL);
2065
5.97k
                xmlFuzzResetFailure();
2066
5.97k
                if (oldAttr != NULL)
2067
1.11k
                    removeChildren((xmlNodePtr) oldAttr, 0);
2068
5.97k
                attr = xmlSetNsProp(node, ns, name, value);
2069
5.97k
                oomReport =
2070
5.97k
                    ((node == NULL || node->type == XML_ELEMENT_NODE) &&
2071
4.81k
                     (ns == NULL || ns->href != NULL) &&
2072
4.71k
                     name != NULL &&
2073
4.21k
                     attr == NULL);
2074
5.97k
                setNode(0, (xmlNodePtr) attr);
2075
5.97k
                if (ns != NULL) {
2076
939
                    if (fixNs((xmlNodePtr) attr) < 0)
2077
2
                        oomReport = 1;
2078
939
                }
2079
5.97k
                break;
2080
18.4k
            }
2081
2082
3.31k
            case OP_XML_REMOVE_PROP: {
2083
3.31k
                xmlNodePtr attr, parent = NULL;
2084
2085
3.31k
                startOp("xmlRemoveProp");
2086
3.31k
                incIntIdx();
2087
3.31k
                attr = getNode(0);
2088
3.31k
                if (attr != NULL) {
2089
2.76k
                    if (attr->parent != NULL &&
2090
1.61k
                        attr->type == XML_ATTRIBUTE_NODE)
2091
1.07k
                        removeChildren(attr, 1);
2092
1.68k
                    else
2093
1.68k
                        attr = NULL;
2094
2.76k
                }
2095
3.31k
                if (attr != NULL)
2096
1.07k
                    parent = attr->parent;
2097
3.31k
                setInt(0, xmlRemoveProp((xmlAttrPtr) attr));
2098
3.31k
                oomReport = 0;
2099
3.31k
                dropNode(parent);
2100
3.31k
                endOp();
2101
3.31k
                break;
2102
18.4k
            }
2103
2104
4.14k
            case OP_XML_UNSET_PROP: {
2105
4.14k
                xmlNodePtr node;
2106
4.14k
                xmlAttrPtr attr;
2107
4.14k
                const xmlChar *name;
2108
2109
4.14k
                startOp("xmlUnsetProp");
2110
4.14k
                incIntIdx();
2111
4.14k
                node = getNode(0);
2112
4.14k
                name = getStr(0);
2113
4.14k
                attr = xmlHasNsProp(node, name, NULL);
2114
4.14k
                xmlFuzzResetFailure();
2115
4.14k
                if (attr != NULL)
2116
1.22k
                    removeChildren((xmlNodePtr) attr, 1);
2117
4.14k
                setInt(0, xmlUnsetProp(node, name));
2118
4.14k
                oomReport = 0;
2119
4.14k
                dropNode(node);
2120
4.14k
                endOp();
2121
4.14k
                break;
2122
18.4k
            }
2123
2124
7.03k
            case OP_XML_UNSET_NS_PROP: {
2125
7.03k
                xmlNodePtr node;
2126
7.03k
                xmlNsPtr ns;
2127
7.03k
                xmlAttrPtr attr;
2128
7.03k
                const xmlChar *name;
2129
2130
7.03k
                startOp("xmlUnsetNsProp");
2131
7.03k
                incIntIdx();
2132
7.03k
                node = getNode(0);
2133
7.03k
                ns = nodeGetNs(getNode(1), getInt(1));
2134
7.03k
                name = getStr(0);
2135
7.03k
                attr = xmlHasNsProp(node, name, ns ? ns->href : NULL);
2136
7.03k
                xmlFuzzResetFailure();
2137
7.03k
                if (attr != NULL)
2138
1.37k
                    removeChildren((xmlNodePtr) attr, 1);
2139
7.03k
                setInt(0, xmlUnsetNsProp(node, ns, name));
2140
7.03k
                oomReport = 0;
2141
7.03k
                dropNode(node);
2142
7.03k
                endOp();
2143
7.03k
                break;
2144
18.4k
            }
2145
2146
21.9k
            case OP_XML_NEW_NS: {
2147
21.9k
                xmlNodePtr node;
2148
21.9k
                xmlNsPtr ns;
2149
2150
21.9k
                startOp("xmlNewNs");
2151
21.9k
                ns = xmlNewNs(
2152
21.9k
                    node = getNode(0),
2153
21.9k
                    getStr(0),
2154
21.9k
                    getStr(1));
2155
21.9k
                if (ns != NULL)
2156
18.0k
                    oomReport = 0;
2157
21.9k
                if (node == NULL)
2158
972
                    xmlFreeNs(ns);
2159
21.9k
                endOp();
2160
21.9k
                break;
2161
18.4k
            }
2162
2163
1.43k
            case OP_XML_SEARCH_NS: {
2164
1.43k
                xmlNsPtr ns;
2165
2166
1.43k
                startOp("xmlSearchNs");
2167
1.43k
                ns = xmlSearchNs(
2168
1.43k
                    getDoc(0),
2169
1.43k
                    getNode(1),
2170
1.43k
                    getStr(0));
2171
1.43k
                if (ns != NULL)
2172
210
                    oomReport = 0;
2173
1.43k
                endOp();
2174
1.43k
                break;
2175
18.4k
            }
2176
2177
1.80k
            case OP_XML_SEARCH_NS_BY_HREF: {
2178
1.80k
                xmlNsPtr ns;
2179
2180
1.80k
                startOp("xmlSearchNsByHref");
2181
1.80k
                ns = xmlSearchNsByHref(
2182
1.80k
                    getDoc(0),
2183
1.80k
                    getNode(1),
2184
1.80k
                    getStr(0));
2185
1.80k
                if (ns != NULL)
2186
245
                    oomReport = 0;
2187
1.80k
                endOp();
2188
1.80k
                break;
2189
18.4k
            }
2190
2191
1.05k
            case OP_XML_GET_NS_LIST: {
2192
1.05k
                xmlNsPtr *list;
2193
2194
1.05k
                startOp("xmlGetNsList");
2195
1.05k
                list = xmlGetNsList(
2196
1.05k
                    getDoc(0),
2197
1.05k
                    getNode(1));
2198
1.05k
                if (list != NULL)
2199
351
                    oomReport = 0;
2200
1.05k
                xmlFree(list);
2201
1.05k
                endOp();
2202
1.05k
                break;
2203
18.4k
            }
2204
2205
1.34k
            case OP_XML_GET_NS_LIST_SAFE: {
2206
1.34k
                xmlNsPtr *list;
2207
1.34k
                int res;
2208
2209
1.34k
                startOp("xmlGetNsList");
2210
1.34k
                res = xmlGetNsListSafe(
2211
1.34k
                    getDoc(0),
2212
1.34k
                    getNode(1),
2213
1.34k
                    &list);
2214
1.34k
                oomReport = (res < 0);
2215
1.34k
                xmlFree(list);
2216
1.34k
                endOp();
2217
1.34k
                break;
2218
18.4k
            }
2219
2220
3.92k
            case OP_XML_SET_NS: {
2221
3.92k
                xmlNodePtr node;
2222
3.92k
                xmlNsPtr ns;
2223
2224
3.92k
                startOp("xmlSetNs");
2225
3.92k
                node = getNode(0),
2226
3.92k
                ns = nodeGetNs(getNode(1), getInt(0));
2227
3.92k
                xmlSetNs(node, ns);
2228
3.92k
                oomReport = 0;
2229
3.92k
                if (ns != NULL) {
2230
2.24k
                    if (fixNs(node) < 0)
2231
4
                        oomReport = 1;
2232
2.24k
                }
2233
3.92k
                endOp();
2234
3.92k
                break;
2235
18.4k
            }
2236
2237
2.56k
            case OP_XML_COPY_NAMESPACE: {
2238
2.56k
                xmlNsPtr ns, copy;
2239
2240
2.56k
                startOp("xmlCopyNamespace");
2241
2.56k
                copy = xmlCopyNamespace(
2242
2.56k
                    ns = nodeGetNs(getNode(0), getInt(0)));
2243
2.56k
                oomReport = (ns != NULL && copy == NULL);
2244
2.56k
                xmlFreeNs(copy);
2245
2.56k
                endOp();
2246
2.56k
                break;
2247
18.4k
            }
2248
2249
2.60k
            case OP_XML_COPY_NAMESPACE_LIST: {
2250
2.60k
                xmlNsPtr list, copy;
2251
2252
2.60k
                startOp("xmlCopyNamespaceList");
2253
2.60k
                copy = xmlCopyNamespaceList(
2254
2.60k
                    list = nodeGetNs(getNode(0), getInt(0)));
2255
2.60k
                oomReport = (list != NULL && copy == NULL);
2256
2.60k
                xmlFreeNsList(copy);
2257
2.60k
                endOp();
2258
2.60k
                break;
2259
18.4k
            }
2260
2261
3.33k
            case OP_XML_UNLINK_NODE: {
2262
3.33k
                xmlNodePtr node, oldParent;
2263
3.33k
                xmlDocPtr doc;
2264
2265
3.33k
                startOp("xmlUnlinkNode");
2266
3.33k
                node = getNode(0);
2267
3.33k
                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.33k
                if (node != NULL &&
2276
2.95k
                    (isDtdChild(node) ||
2277
2.74k
                     (node->type == XML_DTD_NODE &&
2278
596
                      doc != NULL &&
2279
400
                      ((xmlDtdPtr) node == doc->intSubset ||
2280
194
                       (xmlDtdPtr) node == doc->extSubset))))
2281
610
                    node = NULL;
2282
3.33k
                oldParent = node ? node->parent : NULL;
2283
3.33k
                xmlUnlinkNode(node);
2284
3.33k
                oomReport = 0;
2285
3.33k
                if (node != NULL && node->parent != oldParent) {
2286
1.24k
                    if (fixNs(node) < 0)
2287
1
                        oomReport = 1;
2288
1.24k
                    dropNode(oldParent);
2289
1.24k
                }
2290
3.33k
                endOp();
2291
3.33k
                break;
2292
18.4k
            }
2293
2294
3.72k
            case OP_XML_REPLACE_NODE: {
2295
3.72k
                xmlNodePtr old, oldParent, node, oldNodeParent, result;
2296
3.72k
                xmlDocPtr oldDoc, oldNodeDoc;
2297
2298
3.72k
                startOp("xmlReplaceNode");
2299
3.72k
                old = getNode(0);
2300
3.72k
                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
3.72k
                old = old ? old->parent : NULL;
2310
3.72k
                oldDoc = old ? old->doc : NULL;
2311
3.72k
                if (old != NULL &&
2312
3.06k
                    (isDtdChild(old) ||
2313
2.86k
                     (old->type == XML_DTD_NODE &&
2314
619
                      oldDoc != NULL &&
2315
424
                      ((xmlDtdPtr) old == oldDoc->intSubset ||
2316
218
                       (xmlDtdPtr) old == oldDoc->extSubset))))
2317
619
                    old = NULL;
2318
3.72k
                if (old != NULL && !isValidChild(old->parent, node))
2319
130
                    node = NULL;
2320
2321
3.72k
                oldParent = old ? old->parent : NULL;
2322
3.72k
                oldNodeParent = node ? node->parent : NULL;
2323
3.72k
                oldNodeDoc = node ? node->doc : NULL;
2324
2325
3.72k
                result = xmlReplaceNode(old, node);
2326
3.72k
                oomReport =
2327
3.72k
                    (old != NULL && old->parent != NULL &&
2328
724
                     node != NULL &&
2329
724
                     old != node &&
2330
404
                     result == NULL);
2331
2332
3.72k
                if (old != NULL && old->parent != oldParent) {
2333
988
                    if (fixNs(old) < 0)
2334
1
                        oomReport = 1;
2335
988
                }
2336
3.72k
                if (node == NULL) {
2337
                    /* Old node was unlinked */
2338
681
                    dropNode(oldParent);
2339
3.04k
                } else if (node->parent != oldNodeParent ||
2340
2.30k
                           node->doc != oldNodeDoc) {
2341
744
                    if (fixNs(node) < 0)
2342
1
                        oomReport = 1;
2343
                    /* Drop old parent of new node */
2344
744
                    if (oldNodeParent != NULL)
2345
692
                        dropNode(oldNodeParent);
2346
52
                    else
2347
52
                        dropNode((xmlNodePtr) oldNodeDoc);
2348
744
                }
2349
3.72k
                endOp();
2350
3.72k
                break;
2351
18.4k
            }
2352
2353
24.4k
            case OP_XML_ADD_CHILD:
2354
27.3k
            case OP_XML_ADD_SIBLING:
2355
31.0k
            case OP_XML_ADD_PREV_SIBLING:
2356
33.0k
            case OP_XML_ADD_NEXT_SIBLING: {
2357
33.0k
                xmlNodePtr target, parent, node, oldNodeParent, result;
2358
33.0k
                xmlDocPtr oldNodeDoc;
2359
33.0k
                int argsOk;
2360
2361
33.0k
                switch (op) {
2362
24.4k
                    case OP_XML_ADD_CHILD:
2363
24.4k
                        startOp("xmlAddChild"); break;
2364
2.88k
                    case OP_XML_ADD_SIBLING:
2365
2.88k
                        startOp("xmlAddSibling"); break;
2366
3.74k
                    case OP_XML_ADD_PREV_SIBLING:
2367
3.74k
                        startOp("xmlAddPrevSibling"); break;
2368
1.98k
                    case OP_XML_ADD_NEXT_SIBLING:
2369
1.98k
                        startOp("xmlAddNextSibling"); break;
2370
33.0k
                }
2371
2372
33.0k
                if (op == OP_XML_ADD_CHILD) {
2373
24.4k
                    target = NULL;
2374
24.4k
                    parent = getNode(0);
2375
24.4k
                } else {
2376
8.61k
                    target = getNode(0);
2377
8.61k
                    parent = target ? target->parent : NULL;
2378
8.61k
                }
2379
33.0k
                node = getNode(1);
2380
2381
                /* Don't append to root node */
2382
33.0k
                if (target != NULL && parent == NULL)
2383
1.29k
                    node = NULL;
2384
2385
                /* Check tree structure */
2386
33.0k
                if (isDtdChild(node) ||
2387
32.8k
                    !isValidChild(parent, node))
2388
2.26k
                    node = NULL;
2389
2390
                /* Attributes */
2391
33.0k
                if (node != NULL && node->type == XML_ATTRIBUTE_NODE) {
2392
9.64k
                    if ((op == OP_XML_ADD_CHILD) ||
2393
2.07k
                        ((target != NULL &&
2394
9.23k
                         (target->type == XML_ATTRIBUTE_NODE)))) {
2395
9.23k
                        xmlAttrPtr attr = xmlHasNsProp(parent, node->name,
2396
9.23k
                            node->ns ? node->ns->href : NULL);
2397
2398
9.23k
                        xmlFuzzResetFailure();
2399
                        /* Attribute might be replaced */
2400
9.23k
                        if (attr != NULL && attr != (xmlAttrPtr) node)
2401
1.00k
                            removeChildren((xmlNodePtr) attr, 1);
2402
9.23k
                    } else {
2403
412
                        target = NULL;
2404
412
                    }
2405
23.4k
                } else if (target != NULL &&
2406
5.41k
                           target->type == XML_ATTRIBUTE_NODE) {
2407
325
                    node = NULL;
2408
325
                }
2409
2410
33.0k
                oldNodeParent = node ? node->parent : NULL;
2411
33.0k
                oldNodeDoc = node ? node->doc : NULL;
2412
33.0k
                argsOk =
2413
33.0k
                    (target != NULL &&
2414
7.08k
                     node != NULL &&
2415
5.01k
                     target != node);
2416
2417
33.0k
                switch (op) {
2418
24.4k
                    case OP_XML_ADD_CHILD:
2419
24.4k
                        argsOk = (parent != NULL && node != NULL);
2420
24.4k
                        result = xmlAddChild(parent, node);
2421
24.4k
                        break;
2422
2.88k
                    case OP_XML_ADD_SIBLING:
2423
2.88k
                        result = xmlAddSibling(target, node);
2424
2.88k
                        break;
2425
3.74k
                    case OP_XML_ADD_PREV_SIBLING:
2426
3.74k
                        result = xmlAddPrevSibling(target, node);
2427
3.74k
                        break;
2428
1.98k
                    case OP_XML_ADD_NEXT_SIBLING:
2429
1.98k
                        result = xmlAddNextSibling(target, node);
2430
1.98k
                        break;
2431
33.0k
                }
2432
33.0k
                oomReport = (argsOk && result == NULL);
2433
2434
33.0k
                if (result != NULL && result != node) {
2435
                    /* Text node was merged */
2436
870
                    removeNode(node);
2437
870
                    checkContent(result);
2438
                    /* Drop old parent of node */
2439
870
                    if (oldNodeParent != NULL)
2440
532
                        dropNode(oldNodeParent);
2441
338
                    else
2442
338
                        dropNode((xmlNodePtr) oldNodeDoc);
2443
32.2k
                } else if (node != NULL &&
2444
26.9k
                           (node->parent != oldNodeParent ||
2445
18.2k
                            node->doc != oldNodeDoc)) {
2446
18.2k
                    if (fixNs(node) < 0)
2447
17
                        oomReport = 1;
2448
                    /* Drop old parent of node */
2449
18.2k
                    if (oldNodeParent != NULL)
2450
5.74k
                        dropNode(oldNodeParent);
2451
12.4k
                    else
2452
12.4k
                        dropNode((xmlNodePtr) oldNodeDoc);
2453
18.2k
                }
2454
2455
33.0k
                endOp();
2456
33.0k
                break;
2457
33.0k
            }
2458
2459
4.22k
            case OP_XML_TEXT_MERGE: {
2460
4.22k
                xmlNodePtr first, second, parent = NULL, res;
2461
4.22k
                int argsOk;
2462
2463
4.22k
                startOp("xmlTextMerge");
2464
4.22k
                first = getNode(0);
2465
4.22k
                second = getNode(1);
2466
4.22k
                argsOk =
2467
4.22k
                    first == NULL ?
2468
715
                        second != NULL :
2469
4.22k
                        second == NULL ||
2470
2.36k
                        (first->type == XML_TEXT_NODE &&
2471
1.72k
                         second->type == XML_TEXT_NODE &&
2472
1.48k
                         first != second &&
2473
1.28k
                         first->name == second->name);
2474
4.22k
                if (argsOk && second != NULL) {
2475
1.69k
                    if (second->parent != NULL)
2476
225
                        parent = second->parent;
2477
1.47k
                    else
2478
1.47k
                        parent = (xmlNodePtr) second->doc;
2479
2480
1.69k
                }
2481
4.22k
                res = xmlTextMerge(first, second);
2482
4.22k
                oomReport = (argsOk && res == NULL);
2483
4.22k
                if (res != NULL && first != NULL) {
2484
2.43k
                    removeNode(second);
2485
2.43k
                    dropNode(parent);
2486
2.43k
                    checkContent(first);
2487
2.43k
                }
2488
4.22k
                endOp();
2489
4.22k
                break;
2490
33.0k
            }
2491
2492
2.83k
            case OP_XML_TEXT_CONCAT: {
2493
2.83k
                xmlNodePtr node;
2494
2.83k
                const xmlChar *text;
2495
2.83k
                int res;
2496
2497
2.83k
                startOp("xmlTextConcat");
2498
2.83k
                node = getNode(0);
2499
2.83k
                text = getStr(0);
2500
2.83k
                res = xmlTextConcat(
2501
2.83k
                    node,
2502
2.83k
                    text,
2503
2.83k
                    xmlStrlen(text));
2504
2.83k
                oomReport = (isTextContentNode(node) && res < 0);
2505
2.83k
                checkContent(node);
2506
2.83k
                endOp();
2507
2.83k
                break;
2508
33.0k
            }
2509
2510
2.92k
            case OP_XML_STRING_GET_NODE_LIST: {
2511
2.92k
                xmlNodePtr list;
2512
2.92k
                const xmlChar *value;
2513
2514
2.92k
                startOp("xmlStringGetNodeList");
2515
2.92k
                list = xmlStringGetNodeList(
2516
2.92k
                    getDoc(0),
2517
2.92k
                    value = getStr(0));
2518
2.92k
                oomReport = (value != NULL && value[0] != 0 && list == NULL);
2519
2.92k
                xmlFreeNodeList(list);
2520
2.92k
                endOp();
2521
2.92k
                break;
2522
33.0k
            }
2523
2524
2.83k
            case OP_XML_STRING_LEN_GET_NODE_LIST: {
2525
2.83k
                xmlDocPtr doc;
2526
2.83k
                xmlNodePtr list;
2527
2.83k
                const xmlChar *value;
2528
2529
2.83k
                startOp("xmlStringLenGetNodeList");
2530
2.83k
                doc = getDoc(0);
2531
2.83k
                value = getStr(0);
2532
2.83k
                list = xmlStringLenGetNodeList(
2533
2.83k
                    doc,
2534
2.83k
                    value,
2535
2.83k
                    xmlStrlen(value));
2536
2.83k
                oomReport = (value != NULL && value[0] != 0 && list == NULL);
2537
2.83k
                xmlFreeNodeList(list);
2538
2.83k
                endOp();
2539
2.83k
                break;
2540
33.0k
            }
2541
2542
2.26k
            case OP_XML_NODE_LIST_GET_STRING: {
2543
2.26k
                xmlDocPtr doc;
2544
2.26k
                xmlNodePtr list;
2545
2.26k
                xmlChar *string;
2546
2547
2.26k
                startOp("xmlNodeListGetString");
2548
2.26k
                incStrIdx();
2549
2.26k
                doc = getDoc(0);
2550
2.26k
                list = getNode(1);
2551
2.26k
                string = xmlNodeListGetString(
2552
2.26k
                    doc,
2553
2.26k
                    list,
2554
2.26k
                    getInt(0));
2555
2.26k
                oomReport = (list != NULL && string == NULL);
2556
2.26k
                moveStr(0, string);
2557
2.26k
                endOp();
2558
2.26k
                break;
2559
33.0k
            }
2560
2561
2.49k
            case OP_XML_NODE_LIST_GET_RAW_STRING: {
2562
2.49k
                xmlDocPtr doc;
2563
2.49k
                xmlNodePtr list;
2564
2.49k
                xmlChar *string;
2565
2566
2.49k
                startOp("xmlNodeListGetRawString");
2567
2.49k
                incStrIdx();
2568
2.49k
                doc = getDoc(0);
2569
2.49k
                list = getNode(1);
2570
2.49k
                string = xmlNodeListGetRawString(
2571
2.49k
                    doc,
2572
2.49k
                    list,
2573
2.49k
                    getInt(0));
2574
2.49k
                oomReport = (list != NULL && string == NULL);
2575
2.49k
                moveStr(0, string);
2576
2.49k
                endOp();
2577
2.49k
                break;
2578
33.0k
            }
2579
2580
1.73k
            case OP_XML_IS_XHTML:
2581
1.73k
                startOp("xmlIsXHTML");
2582
1.73k
                incIntIdx();
2583
1.73k
                setInt(0, xmlIsXHTML(
2584
1.73k
                    getStr(0),
2585
1.73k
                    getStr(1)));
2586
1.73k
                oomReport = 0;
2587
1.73k
                break;
2588
2589
6.50k
            case OP_XML_ADD_ELEMENT_DECL: {
2590
6.50k
                xmlElementPtr decl;
2591
2592
6.50k
                startOp("xmlAddElementDecl");
2593
6.50k
                incNodeIdx();
2594
6.50k
                decl = xmlAddElementDecl(
2595
6.50k
                    NULL,
2596
6.50k
                    getDtd(1),
2597
6.50k
                    getStr(0),
2598
6.50k
                    (xmlElementTypeVal) getInt(0),
2599
6.50k
                    NULL);
2600
6.50k
                if (decl != NULL)
2601
4.00k
                    oomReport = 0;
2602
6.50k
                setNode(0, (xmlNodePtr) decl);
2603
6.50k
                break;
2604
33.0k
            }
2605
2606
12.3k
            case OP_XML_ADD_ATTRIBUTE_DECL: {
2607
12.3k
                xmlAttributePtr decl;
2608
2609
12.3k
                startOp("xmlAddAttributeDecl");
2610
12.3k
                incNodeIdx();
2611
12.3k
                decl = xmlAddAttributeDecl(
2612
12.3k
                    NULL,
2613
12.3k
                    getDtd(1),
2614
12.3k
                    getStr(0),
2615
12.3k
                    getStr(1),
2616
12.3k
                    getStr(2),
2617
12.3k
                    (xmlAttributeType) getInt(0),
2618
12.3k
                    (xmlAttributeDefault) getInt(1),
2619
12.3k
                    getStr(3),
2620
12.3k
                    NULL);
2621
12.3k
                if (decl != NULL)
2622
10.0k
                    oomReport = 0;
2623
12.3k
                setNode(0, (xmlNodePtr) decl);
2624
12.3k
                break;
2625
33.0k
            }
2626
2627
4.93k
            case OP_XML_ADD_NOTATION_DECL: {
2628
4.93k
                xmlNotationPtr decl;
2629
2630
4.93k
                startOp("xmlAddNotationDecl");
2631
4.93k
                decl = xmlAddNotationDecl(
2632
4.93k
                    NULL,
2633
4.93k
                    getDtd(1),
2634
4.93k
                    getStr(0),
2635
4.93k
                    getStr(1),
2636
4.93k
                    getStr(2));
2637
4.93k
                if (decl != NULL)
2638
1.99k
                    oomReport = 0;
2639
4.93k
                endOp();
2640
4.93k
                break;
2641
33.0k
            }
2642
2643
2.50k
            case OP_XML_GET_DTD_ELEMENT_DESC: {
2644
2.50k
                xmlElementPtr elem;
2645
2646
2.50k
                startOp("xmlGetDtdElementDesc");
2647
2.50k
                incNodeIdx();
2648
2.50k
                elem = xmlGetDtdElementDesc(
2649
2.50k
                    getDtd(1),
2650
2.50k
                    getStr(0));
2651
2.50k
                if (elem != NULL)
2652
1.04k
                    oomReport = 0;
2653
                /*
2654
                 * Don't reference XML_ELEMENT_TYPE_UNDEFINED dummy
2655
                 * declarations which can be freed by xmlAddElementDecl.
2656
                 */
2657
2.50k
                if (elem != NULL && elem->parent == NULL)
2658
211
                    elem = NULL;
2659
2.50k
                setNode(0, (xmlNodePtr) elem);
2660
2.50k
                break;
2661
33.0k
            }
2662
2663
1.68k
            case OP_XML_GET_DTD_QELEMENT_DESC: {
2664
1.68k
                xmlElementPtr elem;
2665
2666
1.68k
                startOp("xmlGetDtdQElementDesc");
2667
1.68k
                incNodeIdx();
2668
1.68k
                elem = xmlGetDtdQElementDesc(
2669
1.68k
                    getDtd(1),
2670
1.68k
                    getStr(0),
2671
1.68k
                    getStr(1));
2672
1.68k
                oomReport = 0;
2673
1.68k
                if (elem != NULL && elem->parent == NULL)
2674
66
                    elem = NULL;
2675
1.68k
                setNode(0, (xmlNodePtr) elem);
2676
1.68k
                break;
2677
33.0k
            }
2678
2679
1.86k
            case OP_XML_GET_DTD_ATTR_DESC: {
2680
1.86k
                xmlAttributePtr decl;
2681
2682
1.86k
                startOp("xmlGetDtdAttrDesc");
2683
1.86k
                incNodeIdx();
2684
1.86k
                decl = xmlGetDtdAttrDesc(
2685
1.86k
                    getDtd(1),
2686
1.86k
                    getStr(0),
2687
1.86k
                    getStr(1));
2688
1.86k
                if (decl != NULL)
2689
805
                    oomReport = 0;
2690
1.86k
                setNode(0, (xmlNodePtr) decl);
2691
1.86k
                break;
2692
33.0k
            }
2693
2694
1.75k
            case OP_XML_GET_DTD_QATTR_DESC: {
2695
1.75k
                xmlAttributePtr decl;
2696
2697
1.75k
                startOp("xmlGetDtdQAttrDesc");
2698
1.75k
                incNodeIdx();
2699
1.75k
                decl = xmlGetDtdQAttrDesc(
2700
1.75k
                    getDtd(1),
2701
1.75k
                    getStr(0),
2702
1.75k
                    getStr(1),
2703
1.75k
                    getStr(2));
2704
1.75k
                oomReport = 0;
2705
1.75k
                setNode(0, (xmlNodePtr) decl);
2706
1.75k
                break;
2707
33.0k
            }
2708
2709
2.12k
            case OP_XML_GET_DTD_NOTATION_DESC:
2710
2.12k
                startOp("xmlGetDtdNotationDesc");
2711
2.12k
                xmlGetDtdNotationDesc(
2712
2.12k
                    getDtd(1),
2713
2.12k
                    getStr(0));
2714
2.12k
                oomReport = 0;
2715
2.12k
                endOp();
2716
2.12k
                break;
2717
2718
1.59k
            case OP_XML_ADD_ID:
2719
1.59k
                startOp("xmlAddID");
2720
1.59k
                xmlAddID(
2721
1.59k
                    NULL,
2722
1.59k
                    getDoc(0),
2723
1.59k
                    getStr(0),
2724
1.59k
                    getAttr(1));
2725
1.59k
                endOp();
2726
1.59k
                break;
2727
2728
2.72k
            case OP_XML_ADD_ID_SAFE: {
2729
2.72k
                int res;
2730
2731
2.72k
                startOp("xmlAddIDSafe");
2732
2.72k
                res = xmlAddIDSafe(
2733
2.72k
                    getAttr(0),
2734
2.72k
                    getStr(0));
2735
2.72k
                oomReport = (res < 0);
2736
2.72k
                endOp();
2737
2.72k
                break;
2738
33.0k
            }
2739
2740
2.04k
            case OP_XML_GET_ID:
2741
2.04k
                startOp("xmlGetID");
2742
2.04k
                incNodeIdx();
2743
2.04k
                setNode(0, (xmlNodePtr) xmlGetID(
2744
2.04k
                    getDoc(1),
2745
2.04k
                    getStr(0)));
2746
2.04k
                oomReport = 0;
2747
2.04k
                break;
2748
2749
2.28k
            case OP_XML_IS_ID: {
2750
2.28k
                int res;
2751
2752
2.28k
                startOp("xmlIsID");
2753
2.28k
                res = xmlIsID(
2754
2.28k
                    getDoc(2),
2755
2.28k
                    getNode(1),
2756
2.28k
                    getAttr(0));
2757
2.28k
                oomReport = (res < 0);
2758
2.28k
                endOp();
2759
2.28k
                break;
2760
33.0k
            }
2761
2762
2.04k
            case OP_XML_REMOVE_ID:
2763
2.04k
                startOp("xmlRemoveID");
2764
2.04k
                xmlRemoveID(
2765
2.04k
                    getDoc(1),
2766
2.04k
                    getAttr(0));
2767
2.04k
                oomReport = 0;
2768
2.04k
                endOp();
2769
2.04k
                break;
2770
2771
1.89k
            case OP_XML_ADD_REF: {
2772
1.89k
                xmlDocPtr doc;
2773
1.89k
                xmlAttrPtr attr;
2774
1.89k
                xmlRefPtr ref;
2775
1.89k
                const xmlChar *value;
2776
2777
1.89k
                startOp("xmlAddRef");
2778
1.89k
                ref = xmlAddRef(
2779
1.89k
                    NULL,
2780
1.89k
                    doc = getDoc(0),
2781
1.89k
                    value = getStr(0),
2782
1.89k
                    attr = getAttr(1));
2783
1.89k
                oomReport =
2784
1.89k
                    (doc != NULL &&
2785
1.46k
                     value != NULL &&
2786
1.23k
                     attr != NULL &&
2787
852
                     ref == NULL);
2788
1.89k
                endOp();
2789
1.89k
                break;
2790
33.0k
            }
2791
2792
1.36k
            case OP_XML_GET_REFS:
2793
1.36k
                startOp("xmlGetRefs");
2794
1.36k
                xmlGetRefs(
2795
1.36k
                    getDoc(1),
2796
1.36k
                    getStr(0));
2797
1.36k
                oomReport = 0;
2798
1.36k
                endOp();
2799
1.36k
                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.25k
            case OP_XML_REMOVE_REF: {
2812
2.25k
                int res;
2813
2814
2.25k
                startOp("xmlRemoveRef");
2815
2.25k
                res = xmlRemoveRef(
2816
2.25k
                    getDoc(1),
2817
2.25k
                    getAttr(0));
2818
2.25k
                if (res == 0)
2819
466
                    oomReport = 0;
2820
2.25k
                endOp();
2821
2.25k
                break;
2822
33.0k
            }
2823
2824
5.13k
            case OP_XML_NEW_ENTITY: {
2825
5.13k
                xmlDocPtr doc;
2826
5.13k
                xmlEntityPtr ent;
2827
2828
5.13k
                startOp("xmlNewEntity");
2829
5.13k
                incNodeIdx();
2830
5.13k
                ent = xmlNewEntity(
2831
5.13k
                    doc = getDoc(1),
2832
5.13k
                    getStr(0),
2833
5.13k
                    getInt(0),
2834
5.13k
                    getStr(1),
2835
5.13k
                    getStr(2),
2836
5.13k
                    getStr(3));
2837
5.13k
                if (ent != NULL)
2838
4.02k
                    oomReport = 0;
2839
5.13k
                if (doc == NULL || doc->intSubset == NULL) {
2840
1.06k
                    xmlFreeEntity(ent);
2841
1.06k
                    ent = NULL;
2842
1.06k
                }
2843
5.13k
                setNode(0, (xmlNodePtr) ent);
2844
5.13k
                break;
2845
33.0k
            }
2846
2847
1.15k
            case OP_XML_ADD_ENTITY: {
2848
1.15k
                xmlEntityPtr ent;
2849
1.15k
                int res;
2850
2851
1.15k
                startOp("xmlAddEntity");
2852
1.15k
                incNodeIdx();
2853
1.15k
                res = xmlAddEntity(
2854
1.15k
                    getDoc(1),
2855
1.15k
                    getInt(0),
2856
1.15k
                    getStr(0),
2857
1.15k
                    getInt(1),
2858
1.15k
                    getStr(1),
2859
1.15k
                    getStr(2),
2860
1.15k
                    getStr(3),
2861
1.15k
                    &ent);
2862
1.15k
                oomReport = (res == XML_ERR_NO_MEMORY);
2863
1.15k
                setNode(0, (xmlNodePtr) ent);
2864
1.15k
                break;
2865
33.0k
            }
2866
2867
1.70k
            case OP_XML_ADD_DOC_ENTITY: {
2868
1.70k
                xmlEntityPtr ent;
2869
2870
1.70k
                startOp("xmlAddDocEntity");
2871
1.70k
                incNodeIdx();
2872
1.70k
                ent = xmlAddDocEntity(
2873
1.70k
                    getDoc(1),
2874
1.70k
                    getStr(0),
2875
1.70k
                    getInt(1),
2876
1.70k
                    getStr(1),
2877
1.70k
                    getStr(2),
2878
1.70k
                    getStr(3));
2879
1.70k
                if (ent != NULL)
2880
629
                    oomReport = 0;
2881
1.70k
                setNode(0, (xmlNodePtr) ent);
2882
1.70k
                break;
2883
33.0k
            }
2884
2885
1.38k
            case OP_XML_ADD_DTD_ENTITY: {
2886
1.38k
                xmlEntityPtr ent;
2887
2888
1.38k
                startOp("xmlAddDtdEntity");
2889
1.38k
                incNodeIdx();
2890
1.38k
                ent = xmlAddDtdEntity(
2891
1.38k
                    getDoc(1),
2892
1.38k
                    getStr(0),
2893
1.38k
                    getInt(1),
2894
1.38k
                    getStr(1),
2895
1.38k
                    getStr(2),
2896
1.38k
                    getStr(3));
2897
1.38k
                setNode(0, (xmlNodePtr) ent);
2898
1.38k
                break;
2899
33.0k
            }
2900
2901
917
            case OP_XML_GET_PREDEFINED_ENTITY:
2902
917
                startOp("xmlGetPredefinedEntity");
2903
917
                incNodeIdx();
2904
917
                setNode(0, (xmlNodePtr) xmlGetPredefinedEntity(
2905
917
                    getStr(0)));
2906
917
                oomReport = 0;
2907
917
                break;
2908
2909
946
            case OP_XML_GET_DOC_ENTITY:
2910
946
                startOp("xmlGetDocEntity");
2911
946
                incNodeIdx();
2912
946
                setNode(0, (xmlNodePtr) xmlGetDocEntity(
2913
946
                    getDoc(1),
2914
946
                    getStr(0)));
2915
946
                oomReport = 0;
2916
946
                break;
2917
2918
1.10k
            case OP_XML_GET_DTD_ENTITY:
2919
1.10k
                startOp("xmlGetDtdEntity");
2920
1.10k
                incNodeIdx();
2921
1.10k
                setNode(0, (xmlNodePtr) xmlGetDtdEntity(
2922
1.10k
                    getDoc(1),
2923
1.10k
                    getStr(0)));
2924
1.10k
                oomReport = 0;
2925
1.10k
                break;
2926
2927
890
            case OP_XML_GET_PARAMETER_ENTITY:
2928
890
                startOp("xmlGetParameterEntity");
2929
890
                incNodeIdx();
2930
890
                setNode(0, (xmlNodePtr) xmlGetParameterEntity(
2931
890
                    getDoc(1),
2932
890
                    getStr(0)));
2933
890
                oomReport = 0;
2934
890
                break;
2935
2936
2.64k
            case OP_XML_ENCODE_ENTITIES_REENTRANT: {
2937
2.64k
                const xmlChar *string;
2938
2.64k
                xmlChar *encoded;
2939
2940
2.64k
                startOp("xmlEncodeEntitiesReentrant");
2941
2.64k
                incStrIdx();
2942
2.64k
                encoded = xmlEncodeEntitiesReentrant(
2943
2.64k
                    getDoc(0),
2944
2.64k
                    string = getStr(1));
2945
2.64k
                oomReport = (string != NULL && encoded == NULL);
2946
2.64k
                moveStr(0, encoded);
2947
2.64k
                endOp();
2948
2.64k
                break;
2949
33.0k
            }
2950
2951
2.27k
            case OP_XML_ENCODE_SPECIAL_CHARS: {
2952
2.27k
                const xmlChar *string;
2953
2.27k
                xmlChar *encoded;
2954
2955
2.27k
                startOp("xmlEncodespecialChars");
2956
2.27k
                incStrIdx();
2957
2.27k
                encoded = xmlEncodeSpecialChars(
2958
2.27k
                    getDoc(0),
2959
2.27k
                    string = getStr(1));
2960
2.27k
                oomReport = (string != NULL && encoded == NULL);
2961
2.27k
                moveStr(0, encoded);
2962
2.27k
                endOp();
2963
2.27k
                break;
2964
33.0k
            }
2965
2966
0
#ifdef LIBXML_HTML_ENABLED
2967
22.8k
            case OP_HTML_NEW_DOC: {
2968
22.8k
                htmlDocPtr doc;
2969
2970
22.8k
                startOp("htmlNewDoc");
2971
22.8k
                incNodeIdx();
2972
22.8k
                doc = htmlNewDoc(
2973
22.8k
                    getStr(0),
2974
22.8k
                    getStr(1));
2975
22.8k
                oomReport = (doc == NULL);
2976
22.8k
                setNode(0, (xmlNodePtr) doc);
2977
22.8k
                break;
2978
33.0k
            }
2979
2980
21.2k
            case OP_HTML_NEW_DOC_NO_DTD: {
2981
21.2k
                htmlDocPtr doc;
2982
2983
21.2k
                startOp("htmlNewDocNoDtD");
2984
21.2k
                incNodeIdx();
2985
21.2k
                doc = htmlNewDocNoDtD(
2986
21.2k
                    getStr(0),
2987
21.2k
                    getStr(1));
2988
21.2k
                oomReport = (doc == NULL);
2989
21.2k
                setNode(0, (xmlNodePtr) doc);
2990
21.2k
                break;
2991
33.0k
            }
2992
2993
5.45k
            case OP_HTML_GET_META_ENCODING: {
2994
5.45k
                const xmlChar *encoding;
2995
2996
5.45k
                startOp("htmlGetMetaEncoding");
2997
5.45k
                incStrIdx();
2998
5.45k
                encoding = htmlGetMetaEncoding(getDoc(0));
2999
5.45k
                if (encoding != NULL)
3000
1.51k
                    oomReport = 0;
3001
5.45k
                copyStr(0, encoding);
3002
5.45k
                break;
3003
33.0k
            }
3004
3005
485
            case OP_HTML_SET_META_ENCODING:
3006
                /* TODO (can destroy inner text) */
3007
485
                break;
3008
3009
921
            case OP_HTML_IS_BOOLEAN_ATTR:
3010
921
                startOp("htmlIsBooleanAttr");
3011
921
                htmlIsBooleanAttr(getStr(0));
3012
921
                oomReport = 0;
3013
921
                endOp();
3014
921
                break;
3015
0
#endif
3016
3017
0
#ifdef LIBXML_VALID_ENABLED
3018
38.2k
            case OP_VALIDATE: {
3019
38.2k
                xmlNodePtr node;
3020
38.2k
                int type;
3021
38.2k
                int res = 1;
3022
3023
38.2k
                startOp("validate");
3024
38.2k
                incIntIdx();
3025
38.2k
                node = getNode(0);
3026
38.2k
                type = node ? node->type : 0;
3027
38.2k
                xmlValidCtxtPtr vctxt = xmlNewValidCtxt();
3028
38.2k
                xmlFuzzResetFailure();
3029
3030
38.2k
                switch (type) {
3031
1.64k
                    case XML_DOCUMENT_NODE:
3032
18.0k
                    case XML_HTML_DOCUMENT_NODE:
3033
18.0k
                        res = xmlValidateDocument(vctxt, (xmlDocPtr) node);
3034
18.0k
                        break;
3035
2.45k
                    case XML_ELEMENT_DECL:
3036
2.45k
                        res = xmlValidateElementDecl(vctxt, node->doc,
3037
2.45k
                            (xmlElementPtr) node);
3038
2.45k
                        break;
3039
4.62k
                    case XML_ATTRIBUTE_DECL:
3040
4.62k
                        res = xmlValidateAttributeDecl(vctxt, node->doc,
3041
4.62k
                            (xmlAttributePtr) node);
3042
4.62k
                        break;
3043
5.46k
                    case XML_ELEMENT_NODE:
3044
5.46k
                        res = xmlValidateElement(vctxt, node->doc, node);
3045
5.46k
                        break;
3046
7.63k
                    default:
3047
7.63k
                        break;
3048
38.2k
                }
3049
3050
38.2k
                if (res != 0)
3051
10.6k
                    oomReport = 0;
3052
38.2k
                xmlFreeValidCtxt(vctxt);
3053
38.2k
                setInt(0, res);
3054
38.2k
                endOp();
3055
38.2k
                break;
3056
38.2k
            }
3057
3058
9.80k
            case OP_XML_VALIDATE_DTD: {
3059
9.80k
                xmlValidCtxtPtr vctxt;
3060
9.80k
                int res;
3061
3062
9.80k
                startOp("xmlValidateDtd");
3063
9.80k
                incIntIdx();
3064
9.80k
                vctxt = xmlNewValidCtxt();
3065
9.80k
                res = xmlValidateDtd(
3066
9.80k
                    vctxt,
3067
9.80k
                    getDoc(0),
3068
9.80k
                    getDtd(1));
3069
9.80k
                if (res != 0)
3070
325
                    oomReport = 0;
3071
9.80k
                xmlFreeValidCtxt(vctxt);
3072
9.80k
                setInt(0, res);
3073
9.80k
                endOp();
3074
9.80k
                break;
3075
38.2k
            }
3076
0
#endif /* LIBXML_VALID_ENABLED */
3077
3078
0
#ifdef LIBXML_OUTPUT_ENABLED
3079
11.9k
            case OP_XML_DOC_DUMP_MEMORY:
3080
15.4k
            case OP_XML_DOC_DUMP_MEMORY_ENC:
3081
25.7k
            case OP_XML_DOC_DUMP_FORMAT_MEMORY:
3082
28.2k
            case OP_XML_DOC_DUMP_FORMAT_MEMORY_ENC:
3083
32.8k
            case OP_HTML_DOC_DUMP_MEMORY:
3084
36.1k
            case OP_HTML_DOC_DUMP_MEMORY_FORMAT: {
3085
36.1k
                xmlDocPtr doc;
3086
36.1k
                xmlChar *out = NULL;
3087
36.1k
                int outSize = 0;
3088
3089
36.1k
                switch (op) {
3090
11.9k
                    case OP_XML_DOC_DUMP_MEMORY:
3091
11.9k
                        startOp("xmlDocDumpMemory"); break;
3092
3.46k
                    case OP_XML_DOC_DUMP_MEMORY_ENC:
3093
3.46k
                        startOp("xmlDocDumpMemoryEnc"); break;
3094
10.3k
                    case OP_XML_DOC_DUMP_FORMAT_MEMORY:
3095
10.3k
                        startOp("xmlDocDumpFormatMemory"); break;
3096
2.46k
                    case OP_XML_DOC_DUMP_FORMAT_MEMORY_ENC:
3097
2.46k
                        startOp("xmlDocDumpFormatMemoryEnc"); break;
3098
4.60k
                    case OP_HTML_DOC_DUMP_MEMORY:
3099
4.60k
                        startOp("htmlDocDumpMemory"); break;
3100
3.29k
                    case OP_HTML_DOC_DUMP_MEMORY_FORMAT:
3101
3.29k
                        startOp("htmlDocDumpMemoryFormat"); break;
3102
36.1k
                }
3103
3104
36.1k
                incStrIdx();
3105
36.1k
                doc = getDoc(0);
3106
3107
36.1k
                switch (op) {
3108
11.9k
                    case OP_XML_DOC_DUMP_MEMORY:
3109
11.9k
                        xmlDocDumpMemory(doc, &out, &outSize);
3110
11.9k
                        break;
3111
3.46k
                    case OP_XML_DOC_DUMP_MEMORY_ENC:
3112
3.46k
                        xmlDocDumpMemoryEnc(doc, &out, &outSize,
3113
3.46k
                            (const char *) getStr(1));
3114
3.46k
                        break;
3115
10.3k
                    case OP_XML_DOC_DUMP_FORMAT_MEMORY:
3116
10.3k
                        xmlDocDumpFormatMemory(doc, &out, &outSize,
3117
10.3k
                            getInt(0));
3118
10.3k
                        break;
3119
2.46k
                    case OP_XML_DOC_DUMP_FORMAT_MEMORY_ENC:
3120
2.46k
                        xmlDocDumpFormatMemoryEnc(doc, &out, &outSize,
3121
2.46k
                            (const char *) getStr(1),
3122
2.46k
                            getInt(0));
3123
2.46k
                        break;
3124
0
#ifdef LIBXML_HTML_ENABLED
3125
4.60k
                    case OP_HTML_DOC_DUMP_MEMORY:
3126
4.60k
                        htmlDocDumpMemory(doc, &out, &outSize);
3127
4.60k
                        break;
3128
3.29k
                    case OP_HTML_DOC_DUMP_MEMORY_FORMAT:
3129
3.29k
                        htmlDocDumpMemoryFormat(doc, &out, &outSize,
3130
3.29k
                            getInt(0));
3131
3.29k
                        break;
3132
36.1k
#endif /* LIBXML_HTML_ENABLED */
3133
36.1k
                }
3134
3135
                /* Could be an unknown encoding */
3136
36.1k
                if (out != NULL)
3137
30.5k
                    oomReport = 0;
3138
36.1k
                moveStr(0, out);
3139
36.1k
                endOp();
3140
36.1k
                break;
3141
36.1k
            }
3142
3143
17.4k
            case OP_XML_NODE_DUMP:
3144
21.9k
            case OP_XML_NODE_BUF_GET_CONTENT:
3145
29.4k
            case OP_XML_ATTR_SERIALIZE_TXT_CONTENT:
3146
31.9k
            case OP_XML_DUMP_ELEMENT_DECL:
3147
34.9k
            case OP_XML_DUMP_ELEMENT_TABLE:
3148
38.9k
            case OP_XML_DUMP_ATTRIBUTE_DECL:
3149
41.9k
            case OP_XML_DUMP_ATTRIBUTE_TABLE:
3150
46.1k
            case OP_XML_DUMP_ENTITY_DECL:
3151
49.8k
            case OP_XML_DUMP_ENTITIES_TABLE:
3152
51.3k
            case OP_XML_DUMP_NOTATION_DECL:
3153
56.6k
            case OP_XML_DUMP_NOTATION_TABLE:
3154
62.4k
            case OP_HTML_NODE_DUMP: {
3155
62.4k
                xmlNodePtr node;
3156
62.4k
                xmlDocPtr doc;
3157
62.4k
                xmlBufferPtr buffer;
3158
62.4k
                xmlChar *dump;
3159
62.4k
                int level, format, res;
3160
3161
62.4k
                switch (op) {
3162
17.4k
                    case OP_XML_NODE_DUMP:
3163
17.4k
                        startOp("xmlNodeDump"); break;
3164
4.49k
                    case OP_XML_NODE_BUF_GET_CONTENT:
3165
4.49k
                        startOp("xmlNodeBufGetContent"); break;
3166
7.54k
                    case OP_XML_ATTR_SERIALIZE_TXT_CONTENT:
3167
7.54k
                        startOp("xmlAttrSerializeTxtContent"); break;
3168
2.45k
                    case OP_XML_DUMP_ELEMENT_DECL:
3169
2.45k
                        startOp("xmlDumpElementDecl"); break;
3170
3.05k
                    case OP_XML_DUMP_ELEMENT_TABLE:
3171
3.05k
                        startOp("xmlDumpElementTable"); break;
3172
4.01k
                    case OP_XML_DUMP_ATTRIBUTE_DECL:
3173
4.01k
                        startOp("xmlDumpAttributeDecl"); break;
3174
2.98k
                    case OP_XML_DUMP_ATTRIBUTE_TABLE:
3175
2.98k
                        startOp("xmlDumpAttributeTable"); break;
3176
4.23k
                    case OP_XML_DUMP_ENTITY_DECL:
3177
4.23k
                        startOp("xmlDumpEntityDecl"); break;
3178
3.65k
                    case OP_XML_DUMP_ENTITIES_TABLE:
3179
3.65k
                        startOp("xmlDumpEntitiesTable"); break;
3180
1.50k
                    case OP_XML_DUMP_NOTATION_DECL:
3181
1.50k
                        startOp("xmlDumpNotationDecl"); break;
3182
5.27k
                    case OP_XML_DUMP_NOTATION_TABLE:
3183
5.27k
                        startOp("xmlDumpNotationTable"); break;
3184
5.77k
                    case OP_HTML_NODE_DUMP:
3185
5.77k
                        startOp("htmlNodeDump"); break;
3186
62.4k
                }
3187
3188
62.4k
                incStrIdx();
3189
62.4k
                buffer = xmlBufferCreate();
3190
62.4k
                xmlFuzzResetFailure();
3191
62.4k
                node = getNode(0);
3192
62.4k
                doc = node ? node->doc : NULL;
3193
62.4k
                level = getInt(0);
3194
62.4k
                format = getInt(0);
3195
62.4k
                res = 0;
3196
3197
62.4k
                switch (op) {
3198
17.4k
                    case OP_XML_NODE_DUMP:
3199
17.4k
                        res = xmlNodeDump(buffer, doc, node, level, format);
3200
17.4k
                        break;
3201
4.49k
                    case OP_XML_NODE_BUF_GET_CONTENT:
3202
4.49k
                        res = xmlNodeBufGetContent(buffer, node);
3203
4.49k
                        break;
3204
7.54k
                    case OP_XML_ATTR_SERIALIZE_TXT_CONTENT:
3205
7.54k
                        if (node != NULL && node->type != XML_ATTRIBUTE_NODE)
3206
4.53k
                            node = NULL;
3207
7.54k
                        xmlAttrSerializeTxtContent(
3208
7.54k
                            buffer, doc,
3209
7.54k
                            (xmlAttrPtr) node,
3210
7.54k
                            getStr(1));
3211
7.54k
                        break;
3212
2.45k
                    case OP_XML_DUMP_ELEMENT_DECL:
3213
2.45k
                        if (node != NULL && node->type != XML_ELEMENT_DECL)
3214
894
                            node = NULL;
3215
2.45k
                        xmlDumpElementDecl(buffer, (xmlElementPtr) node);
3216
2.45k
                        break;
3217
4.01k
                    case OP_XML_DUMP_ATTRIBUTE_DECL:
3218
4.01k
                        if (node != NULL && node->type != XML_ATTRIBUTE_DECL)
3219
1.76k
                            node = NULL;
3220
4.01k
                        xmlDumpAttributeDecl(buffer, (xmlAttributePtr) node);
3221
4.01k
                        break;
3222
1.50k
                    case OP_XML_DUMP_NOTATION_DECL:
3223
                        /* TODO */
3224
1.50k
                        break;
3225
4.23k
                    case OP_XML_DUMP_ENTITY_DECL:
3226
4.23k
                        if (node != NULL && node->type != XML_ENTITY_DECL)
3227
2.16k
                            node = NULL;
3228
4.23k
                        xmlDumpEntityDecl(buffer, (xmlEntityPtr) node);
3229
4.23k
                        break;
3230
3.05k
                    case OP_XML_DUMP_ELEMENT_TABLE: {
3231
3.05k
                        xmlElementTablePtr table;
3232
3233
3.05k
                        table = node != NULL && node->type == XML_DTD_NODE ?
3234
639
                                ((xmlDtdPtr) node)->elements :
3235
3.05k
                                NULL;
3236
3.05k
                        xmlDumpElementTable(buffer, table);
3237
3.05k
                        break;
3238
0
                    }
3239
2.98k
                    case OP_XML_DUMP_ATTRIBUTE_TABLE: {
3240
2.98k
                        xmlAttributeTablePtr table;
3241
3242
2.98k
                        table = node != NULL && node->type == XML_DTD_NODE ?
3243
578
                                ((xmlDtdPtr) node)->attributes :
3244
2.98k
                                NULL;
3245
2.98k
                        xmlDumpAttributeTable(buffer, table);
3246
2.98k
                        break;
3247
0
                    }
3248
5.27k
                    case OP_XML_DUMP_NOTATION_TABLE: {
3249
5.27k
                        xmlNotationTablePtr table;
3250
3251
5.27k
                        table = node != NULL && node->type == XML_DTD_NODE ?
3252
750
                                ((xmlDtdPtr) node)->notations :
3253
5.27k
                                NULL;
3254
5.27k
                        xmlDumpNotationTable(buffer, table);
3255
5.27k
                        break;
3256
0
                    }
3257
3.65k
                    case OP_XML_DUMP_ENTITIES_TABLE: {
3258
3.65k
                        xmlEntitiesTablePtr table;
3259
3260
3.65k
                        table = node != NULL && node->type == XML_DTD_NODE ?
3261
493
                                ((xmlDtdPtr) node)->entities :
3262
3.65k
                                NULL;
3263
3.65k
                        xmlDumpEntitiesTable(buffer, table);
3264
3.65k
                        break;
3265
0
                    }
3266
0
#ifdef LIBXML_HTML_ENABLED
3267
5.77k
                    case OP_HTML_NODE_DUMP:
3268
5.77k
                        res = htmlNodeDump(buffer, doc, node);
3269
5.77k
                        break;
3270
62.4k
#endif /* LIBXML_HTML_ENABLED */
3271
62.4k
                }
3272
3273
62.4k
                dump = xmlBufferDetach(buffer);
3274
62.4k
                if (res == 0 && dump != NULL)
3275
39.3k
                    oomReport = 0;
3276
62.4k
                moveStr(0, dump);
3277
62.4k
                xmlBufferFree(buffer);
3278
62.4k
                endOp();
3279
62.4k
                break;
3280
62.4k
            }
3281
3282
5.10k
            case OP_XML_SAVE_FILE_TO:
3283
10.9k
            case OP_XML_SAVE_FORMAT_FILE_TO:
3284
23.4k
            case OP_XML_NODE_DUMP_OUTPUT:
3285
25.5k
            case OP_HTML_DOC_CONTENT_DUMP_OUTPUT:
3286
28.0k
            case OP_HTML_DOC_CONTENT_DUMP_FORMAT_OUTPUT:
3287
35.0k
            case OP_HTML_NODE_DUMP_OUTPUT:
3288
37.8k
            case OP_HTML_NODE_DUMP_FORMAT_OUTPUT: {
3289
37.8k
                xmlNodePtr node;
3290
37.8k
                xmlDocPtr doc;
3291
37.8k
                xmlOutputBufferPtr output;
3292
37.8k
                const char *encoding;
3293
37.8k
                int level, format, argsOk, res, closed;
3294
3295
37.8k
                switch (op) {
3296
5.10k
                    case OP_XML_SAVE_FILE_TO:
3297
5.10k
                        startOp("xmlSaveFileTo"); break;
3298
5.80k
                    case OP_XML_SAVE_FORMAT_FILE_TO:
3299
5.80k
                        startOp("xmlSaveFormatFileTo"); break;
3300
12.5k
                    case OP_XML_NODE_DUMP_OUTPUT:
3301
12.5k
                        startOp("xmlNodeDumpOutput"); break;
3302
2.10k
                    case OP_HTML_DOC_CONTENT_DUMP_OUTPUT:
3303
2.10k
                        startOp("htmlDocContentDumpOutput"); break;
3304
2.53k
                    case OP_HTML_DOC_CONTENT_DUMP_FORMAT_OUTPUT:
3305
2.53k
                        startOp("htmlDocContentDumpFormatOutput"); break;
3306
7.00k
                    case OP_HTML_NODE_DUMP_OUTPUT:
3307
7.00k
                        startOp("htmlNodeDumpOutput"); break;
3308
2.82k
                    case OP_HTML_NODE_DUMP_FORMAT_OUTPUT:
3309
2.82k
                        startOp("htmlNodeDumpFormatOutput"); break;
3310
37.8k
                }
3311
3312
37.8k
                incStrIdx();
3313
37.8k
                output = xmlOutputBufferCreateIO(xmlFuzzOutputWrite,
3314
37.8k
                                                 xmlFuzzOutputClose, NULL, NULL);
3315
37.8k
                xmlFuzzResetFailure();
3316
37.8k
                node = getNode(0);
3317
37.8k
                doc = node ? node->doc : NULL;
3318
37.8k
                encoding = (const char *) getStr(1);
3319
37.8k
                level = getInt(0);
3320
37.8k
                format = getInt(0);
3321
37.8k
                argsOk = (output != NULL);
3322
37.8k
                res = 0;
3323
37.8k
                closed = 0;
3324
3325
37.8k
                switch (op) {
3326
5.10k
                    case OP_XML_SAVE_FILE_TO:
3327
5.10k
                        argsOk &= (doc != NULL);
3328
5.10k
                        res = xmlSaveFileTo(output, doc, encoding);
3329
5.10k
                        closed = 1;
3330
5.10k
                        break;
3331
5.80k
                    case OP_XML_SAVE_FORMAT_FILE_TO:
3332
5.80k
                        argsOk &= (doc != NULL);
3333
5.80k
                        res = xmlSaveFormatFileTo(output, doc, encoding, format);
3334
5.80k
                        closed = 1;
3335
5.80k
                        break;
3336
12.5k
                    case OP_XML_NODE_DUMP_OUTPUT:
3337
12.5k
                        argsOk &= (node != NULL);
3338
12.5k
                        xmlNodeDumpOutput(output, doc, node, level, format,
3339
12.5k
                                          encoding);
3340
12.5k
                        break;
3341
0
#ifdef LIBXML_HTML_ENABLED
3342
2.10k
                    case OP_HTML_DOC_CONTENT_DUMP_OUTPUT:
3343
2.10k
                        argsOk &= (doc != NULL);
3344
2.10k
                        htmlDocContentDumpOutput(output, doc, encoding);
3345
2.10k
                        break;
3346
2.53k
                    case OP_HTML_DOC_CONTENT_DUMP_FORMAT_OUTPUT:
3347
2.53k
                        argsOk &= (doc != NULL);
3348
2.53k
                        htmlDocContentDumpFormatOutput(output, doc, encoding,
3349
2.53k
                                                       format);
3350
2.53k
                        break;
3351
7.00k
                    case OP_HTML_NODE_DUMP_OUTPUT:
3352
7.00k
                        argsOk &= (node != NULL);
3353
7.00k
                        htmlNodeDumpOutput(output, doc, node, encoding);
3354
7.00k
                        break;
3355
2.82k
                    case OP_HTML_NODE_DUMP_FORMAT_OUTPUT:
3356
2.82k
                        argsOk &= (node != NULL);
3357
2.82k
                        htmlNodeDumpFormatOutput(output, doc, node, encoding,
3358
2.82k
                                                 format);
3359
2.82k
                        break;
3360
37.8k
#endif /* LIBXML_HTML_ENABLED */
3361
37.8k
                }
3362
3363
37.8k
                if (closed) {
3364
10.9k
                    if (res >= 0)
3365
7.64k
                        oomReport = 0;
3366
3.26k
                    else
3367
3.26k
                        ioReport = -1;
3368
10.9k
                    moveStr(0, NULL);
3369
26.9k
                } else {
3370
26.9k
                    if (argsOk && !output->error)
3371
25.0k
                        copyStr(0, xmlBufContent(output->buffer));
3372
1.94k
                    else
3373
1.94k
                        moveStr(0, NULL);
3374
26.9k
                    res = xmlOutputBufferClose(output);
3375
26.9k
                    oomReport = (res == -XML_ERR_NO_MEMORY);
3376
26.9k
                    ioReport  = (res == -XML_IO_EIO);
3377
26.9k
                }
3378
37.8k
                endOp();
3379
37.8k
                break;
3380
37.8k
            }
3381
0
#endif /* LIBXML_OUTPUT_ENABLED */
3382
3383
4.58k
            case OP_XML_DOM_WRAP_RECONCILE_NAMESPACES: {
3384
4.58k
                xmlNodePtr node;
3385
4.58k
                int res;
3386
3387
4.58k
                startOp("xmlDOMWrapReconcileNamespaces");
3388
4.58k
                res = xmlDOMWrapReconcileNamespaces(
3389
4.58k
                    NULL,
3390
4.58k
                    node = getNode(0),
3391
4.58k
                    getInt(0));
3392
4.58k
                oomReport =
3393
4.58k
                    (node != NULL &&
3394
4.20k
                     node->doc != NULL &&
3395
3.94k
                     node->type == XML_ELEMENT_NODE &&
3396
3.51k
                     res < 0);
3397
4.58k
                endOp();
3398
4.58k
                break;
3399
37.8k
            }
3400
3401
12.7k
            case OP_XML_DOM_WRAP_ADOPT_NODE: {
3402
12.7k
                xmlDOMWrapCtxtPtr ctxt;
3403
12.7k
                xmlDocPtr doc, destDoc, oldDoc;
3404
12.7k
                xmlNodePtr node, destParent, oldParent;
3405
12.7k
                int res;
3406
3407
12.7k
                startOp("xmlDOMWrapAdoptNode");
3408
12.7k
                ctxt = xmlDOMWrapNewCtxt();
3409
12.7k
                doc = getDoc(0);
3410
12.7k
                node = getNode(1);
3411
12.7k
                destDoc = getDoc(2);
3412
12.7k
                destParent = getNode(3);
3413
3414
12.7k
                if (!isValidChild(destParent, node))
3415
2.93k
                    destParent = NULL;
3416
3417
12.7k
                oldParent = node ? node->parent : NULL;
3418
12.7k
                oldDoc = node ? node->doc : NULL;
3419
3420
12.7k
                res = xmlDOMWrapAdoptNode(
3421
12.7k
                    ctxt,
3422
12.7k
                    doc,
3423
12.7k
                    node,
3424
12.7k
                    destDoc,
3425
12.7k
                    destParent,
3426
12.7k
                    getInt(0));
3427
12.7k
                if (ctxt == NULL)
3428
18
                    oomReport = 1;
3429
12.6k
                else if (res == 0)
3430
5.92k
                    oomReport = 0;
3431
3432
12.7k
                if (node != NULL) {
3433
                    /* Node can reference destParent's namespaces */
3434
12.0k
                    if (destParent != NULL &&
3435
7.54k
                        node->parent == NULL &&
3436
6.19k
                        node->doc == destParent->doc) {
3437
5.98k
                        if (node->type == XML_ATTRIBUTE_NODE) {
3438
3.08k
                            xmlNodePtr prop;
3439
3440
                            /* Insert without removing duplicates */
3441
3.08k
                            node->parent = destParent;
3442
3.08k
                            prop = (xmlNodePtr) destParent->properties;
3443
3.08k
                            node->next = prop;
3444
3.08k
                            if (prop != NULL)
3445
316
                                prop->prev = node;
3446
3.08k
                            destParent->properties = (xmlAttrPtr) node;
3447
3.08k
                        } else if (node->type != XML_TEXT_NODE) {
3448
2.70k
                            xmlAddChild(destParent, node);
3449
2.70k
                        }
3450
5.98k
                    }
3451
3452
                    /* Node can be unlinked and moved to a new document. */
3453
12.0k
                    if (oldParent != NULL && node->parent != oldParent)
3454
6.61k
                        dropNode(oldParent);
3455
5.38k
                    else if (node->doc != oldDoc)
3456
906
                        dropNode((xmlNodePtr) oldDoc);
3457
12.0k
                }
3458
3459
12.7k
                xmlDOMWrapFreeCtxt(ctxt);
3460
12.7k
                endOp();
3461
12.7k
                break;
3462
37.8k
            }
3463
3464
6.30k
            case OP_XML_DOM_WRAP_REMOVE_NODE: {
3465
6.30k
                xmlDocPtr doc;
3466
6.30k
                xmlNodePtr node, oldParent;
3467
6.30k
                int res;
3468
3469
6.30k
                startOp("xmlDOMWrapRemoveNode");
3470
6.30k
                doc = getDoc(0);
3471
6.30k
                node = getNode(1);
3472
6.30k
                oldParent = node ? node->parent : NULL;
3473
6.30k
                res = xmlDOMWrapRemoveNode(NULL, doc, node, 0);
3474
6.30k
                oomReport =
3475
6.30k
                    (node != NULL &&
3476
5.79k
                     doc != NULL &&
3477
5.05k
                     node->doc == doc &&
3478
4.73k
                     res < 0);
3479
6.30k
                if (node != NULL && node->parent != oldParent) {
3480
3.40k
                    if (fixNs(node) < 0)
3481
2
                        oomReport = 1;
3482
3.40k
                    dropNode(oldParent);
3483
3.40k
                }
3484
6.30k
                endOp();
3485
6.30k
                break;
3486
37.8k
            }
3487
3488
16.6k
            case OP_XML_DOM_WRAP_CLONE_NODE: {
3489
16.6k
                xmlDOMWrapCtxtPtr ctxt;
3490
16.6k
                xmlDocPtr doc, destDoc;
3491
16.6k
                xmlNodePtr node, destParent, copy = NULL;
3492
16.6k
                int res;
3493
3494
16.6k
                startOp("xmlDOMWrapCloneNode");
3495
16.6k
                incNodeIdx();
3496
16.6k
                ctxt = xmlDOMWrapNewCtxt();
3497
16.6k
                doc = getDoc(1);
3498
16.6k
                node = getNode(2);
3499
16.6k
                destDoc = getDoc(3);
3500
16.6k
                destParent = getNode(4);
3501
3502
16.6k
                if (destParent != NULL &&
3503
12.1k
                    node != NULL &&
3504
10.9k
                    !isValidChildType(destParent, node->type))
3505
942
                    destParent = NULL;
3506
3507
                /* xmlDOMWrapCloneNode returns a garbage node on error. */
3508
16.6k
                res = xmlDOMWrapCloneNode(
3509
16.6k
                    ctxt,
3510
16.6k
                    doc,
3511
16.6k
                    node,
3512
16.6k
                    &copy,
3513
16.6k
                    destDoc,
3514
16.6k
                    destParent,
3515
16.6k
                    getInt(0),
3516
16.6k
                    0);
3517
16.6k
                if (ctxt == NULL)
3518
22
                    oomReport = 1;
3519
16.6k
                else if (res == 0)
3520
11.6k
                    oomReport = 0;
3521
16.6k
                copy = checkCopy(copy);
3522
3523
                /* Copy can reference destParent's namespaces */
3524
16.6k
                if (destParent != NULL && copy != NULL) {
3525
8.97k
                    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
8.97k
                    } else if (copy->type != XML_TEXT_NODE) {
3536
8.97k
                        xmlAddChild(destParent, copy);
3537
8.97k
                    }
3538
8.97k
                }
3539
3540
16.6k
                xmlDOMWrapFreeCtxt(ctxt);
3541
16.6k
                setNode(0, copy);
3542
16.6k
                break;
3543
37.8k
            }
3544
3545
2.43k
            case OP_XML_CHILD_ELEMENT_COUNT:
3546
2.43k
                startOp("xmlChildElementCount");
3547
2.43k
                incIntIdx();
3548
2.43k
                setInt(0, xmlChildElementCount(getNode(0)));
3549
2.43k
                oomReport = 0;
3550
2.43k
                break;
3551
3552
4.05k
            case OP_XML_FIRST_ELEMENT_CHILD:
3553
4.05k
                startOp("xmlFirstElementChild");
3554
4.05k
                incNodeIdx();
3555
4.05k
                setNode(0, xmlFirstElementChild(getNode(1)));
3556
4.05k
                oomReport = 0;
3557
4.05k
                break;
3558
3559
2.82k
            case OP_XML_LAST_ELEMENT_CHILD:
3560
2.82k
                startOp("xmlLastElementChild");
3561
2.82k
                incNodeIdx();
3562
2.82k
                setNode(0, xmlLastElementChild(getNode(1)));
3563
2.82k
                oomReport = 0;
3564
2.82k
                break;
3565
3566
2.66k
            case OP_XML_NEXT_ELEMENT_SIBLING:
3567
2.66k
                startOp("xmlNextElementSibling");
3568
2.66k
                incNodeIdx();
3569
2.66k
                setNode(0, xmlNextElementSibling(getNode(1)));
3570
2.66k
                oomReport = 0;
3571
2.66k
                break;
3572
3573
2.80k
            case OP_XML_PREVIOUS_ELEMENT_SIBLING:
3574
2.80k
                startOp("xmlPreviousElementSibling");
3575
2.80k
                incNodeIdx();
3576
2.80k
                setNode(0, xmlPreviousElementSibling(getNode(1)));
3577
2.80k
                oomReport = 0;
3578
2.80k
                break;
3579
3580
55.9k
            default:
3581
55.9k
                break;
3582
1.14M
        }
3583
3584
1.14M
        xmlFuzzCheckFailureReport(vars->opName, oomReport, ioReport);
3585
1.14M
    }
3586
3587
334k
    for (i = 0; i < REG_MAX; i++)
3588
297k
        xmlFree(vars->strings[i]);
3589
3590
334k
    for (i = 0; i < REG_MAX; i++) {
3591
297k
        xmlNodePtr node = vars->nodes[i];
3592
3593
297k
        vars->nodes[i] = NULL;
3594
297k
        dropNode(node);
3595
297k
    }
3596
3597
37.1k
    xmlFuzzInjectFailure(0);
3598
37.1k
    xmlFuzzDataCleanup();
3599
37.1k
    xmlResetLastError();
3600
37.1k
    return(0);
3601
37.1k
}
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