Coverage Report

Created: 2025-11-11 06:31

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