xref: /aosp_15_r20/tools/security/fuzzing/llm/tinyxml2_fuzzer/tinyxml_parse_fuzzer.cpp (revision d9ecfb0f4d734c9ce41cde8ac4d585b094fd4222)
1 #include <fuzzer/FuzzedDataProvider.h>
2 #include <tinyxml2.h>
3 #include <string>
4 #include <vector>
5 
6 struct XMLElement {
7     std::string name;
8     std::vector<std::pair<std::string, std::string>> attributes;
9     std::vector<XMLElement> children;
10     std::string textContent;
11 };
12 
serializeXML(const XMLElement & element)13 std::string serializeXML(const XMLElement& element) {
14     std::string xml = "<" + element.name;
15 
16     // Add attributes
17     for (const auto& attr : element.attributes) {
18         xml += " " + attr.first + "=\"" + attr.second + "\"";
19     }
20 
21     xml += ">";
22 
23     // Add text content
24     xml += element.textContent;
25 
26     // Add child elements (recursively)
27     for (const auto& child : element.children) {
28         xml += serializeXML(child);
29     }
30 
31     xml += "</" + element.name + ">";
32     return xml;
33 }
34 
GenerateXML(FuzzedDataProvider * stream,XMLElement * element,int maxDepth=3)35 void GenerateXML(FuzzedDataProvider* stream, XMLElement* element, int maxDepth = 3) {
36     element->name = stream->ConsumeRandomLengthString(20);
37 
38     int numAttributes = stream->ConsumeIntegralInRange<int>(0, 5);
39     for (int i = 0; i < numAttributes; ++i) {
40     element->attributes.push_back({
41       stream->ConsumeRandomLengthString(15), // Attribute name
42       stream->ConsumeRandomLengthString(30)  // Attribute value
43     });
44     }
45 
46     int numChildren = stream->ConsumeIntegralInRange<int>(0, 3);
47     for (int i = 0; i < numChildren; ++i) {
48         XMLElement child;
49 
50         // Recursive generation for nested elements
51         if (maxDepth > 0) {
52             GenerateXML(stream, &child, maxDepth - 1);
53         } else {
54             // Populate text content at the leaves
55             child.textContent = stream->ConsumeRandomLengthString(30);
56         }
57 
58         element->children.push_back(child);
59     }
60 }
61 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)62 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
63     FuzzedDataProvider stream(data, size);
64 
65     XMLElement rootElement;
66     GenerateXML(&stream, &rootElement);
67 
68     // Convert the generated XMLElement structure into an XML string
69     std::string xmlString = serializeXML(rootElement);
70 
71     tinyxml2::XMLDocument doc;
72     doc.Parse(xmlString.c_str(), xmlString.length());
73 
74     return 0;
75 }
76