Coverage Report

Created: 2026-10-13 06:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pupnp/fuzzer/FuzzIxmlDom.c
Line
Count
Source
1
#include "ixml.h"
2
3
#include <stddef.h>
4
#include <stdint.h>
5
#include <stdlib.h>
6
#include <string.h>
7
8
196k
#define MAX_DEPTH 64
9
586
#define MAX_NODES 4096
10
11
static void visit_attributes(IXML_Node *nodeptr)
12
937
{
13
937
  IXML_NamedNodeMap *map;
14
937
  unsigned long i;
15
937
  unsigned long len;
16
17
937
  map = ixmlNode_getAttributes(nodeptr);
18
937
  if (!map) {
19
0
    return;
20
0
  }
21
22
937
  len = ixmlNamedNodeMap_getLength(map);
23
3.28k
  for (i = 0; i < len; i++) {
24
2.34k
    IXML_Node *attr = ixmlNamedNodeMap_item(map, i);
25
2.34k
    const DOMString name;
26
27
2.34k
    if (!attr) {
28
0
      continue;
29
0
    }
30
2.34k
    (void)ixmlNode_getNodeValue(attr);
31
2.34k
    (void)ixmlNode_getLocalName(attr);
32
2.34k
    (void)ixmlNode_getNamespaceURI(attr);
33
2.34k
    (void)ixmlNode_getPrefix(attr);
34
35
2.34k
    name = ixmlNode_getNodeName(attr);
36
2.34k
    if (name) {
37
2.34k
      (void)ixmlNamedNodeMap_getNamedItem(map, name);
38
2.34k
    }
39
2.34k
  }
40
937
  ixmlNamedNodeMap_free(map);
41
937
}
42
43
static void walk(IXML_Node *nodeptr, int depth, unsigned long *budget)
44
98.3k
{
45
98.3k
  IXML_Node *child;
46
47
98.3k
  if (!nodeptr || depth > MAX_DEPTH || *budget == 0) {
48
28.6k
    return;
49
28.6k
  }
50
69.7k
  (*budget)--;
51
52
69.7k
  if (ixmlNode_hasAttributes(nodeptr)) {
53
937
    visit_attributes(nodeptr);
54
937
  }
55
56
167k
  for (child = ixmlNode_getFirstChild(nodeptr); child;
57
97.7k
    child = ixmlNode_getNextSibling(child)) {
58
97.7k
    walk(child, depth + 1, budget);
59
97.7k
  }
60
69.7k
}
61
62
static void visit_child_list(IXML_Node *nodeptr)
63
586
{
64
586
  IXML_NodeList *children = ixmlNode_getChildNodes(nodeptr);
65
586
  unsigned long i;
66
586
  unsigned long len;
67
68
586
  if (!children) {
69
0
    return;
70
0
  }
71
586
  len = ixmlNodeList_length(children);
72
1.17k
  for (i = 0; i < len; i++) {
73
586
    (void)ixmlNodeList_item(children, i);
74
586
  }
75
586
  ixmlNodeList_free(children);
76
586
}
77
78
static void query_document(IXML_Document *doc)
79
586
{
80
586
  IXML_NodeList *list;
81
586
  IXML_Node *first;
82
83
586
  list = ixmlDocument_getElementsByTagName(doc, "*");
84
586
  if (list) {
85
521
    unsigned long i;
86
521
    unsigned long len = ixmlNodeList_length(list);
87
88
63.7k
    for (i = 0; i < len; i++) {
89
63.2k
      IXML_Node *node = ixmlNodeList_item(list, i);
90
63.2k
      IXML_Element *element = (IXML_Element *)node;
91
63.2k
      const DOMString tag;
92
93
63.2k
      if (!node) {
94
0
        continue;
95
0
      }
96
63.2k
      tag = ixmlElement_getTagName(element);
97
63.2k
      if (tag) {
98
63.2k
        (void)ixmlElement_getAttribute(element, tag);
99
63.2k
        (void)ixmlElement_hasAttribute(element, tag);
100
63.2k
        (void)ixmlElement_getAttributeNode(
101
63.2k
          element, tag);
102
63.2k
      }
103
63.2k
    }
104
521
    ixmlNodeList_free(list);
105
521
  }
106
107
586
  list = ixmlDocument_getElementsByTagNameNS(doc, "*", "*");
108
586
  if (list) {
109
34
    ixmlNodeList_free(list);
110
34
  }
111
112
586
  first = ixmlNode_getFirstChild((IXML_Node *)doc);
113
586
  if (first) {
114
521
    IXML_Node *clone = ixmlNode_cloneNode(first, 1);
115
116
521
    if (clone) {
117
521
      (void)ixmlNode_getFirstChild(clone);
118
521
      (void)ixmlNode_hasChildNodes(clone);
119
521
      ixmlNode_free(clone);
120
521
    }
121
521
  }
122
586
}
123
124
extern int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
125
4.48k
{
126
4.48k
  IXML_Document *doc = NULL;
127
4.48k
  char *xml;
128
129
4.48k
  if (Size < 1 || Size > 65536) {
130
7
    return 0;
131
7
  }
132
133
4.47k
  xml = malloc(Size + 1);
134
4.47k
  if (!xml) {
135
0
    return 0;
136
0
  }
137
4.47k
  memcpy(xml, Data, Size);
138
4.47k
  xml[Size] = '\0';
139
140
4.47k
  if (ixmlParseBufferEx(xml, &doc) == IXML_SUCCESS && doc) {
141
586
    unsigned long budget = MAX_NODES;
142
143
586
    walk((IXML_Node *)doc, 0, &budget);
144
586
    visit_child_list((IXML_Node *)doc);
145
586
    query_document(doc);
146
586
    ixmlDocument_free(doc);
147
586
  }
148
149
4.47k
  free(xml);
150
151
4.47k
  return 0;
152
4.47k
}