blob: 80280a36bffa55be152a822be74f52d8733b2093 [file] [log] [blame] [edit]
// NOTE: This example uses cc_test in its BUILD file instead of cc_fuzz_test
// due to difficulties in locating the correct Bazel macro for cc_fuzz_test
// in the testing environment. When integrating FuzzTest into your own project,
// ensure your Bazel setup is correct to use cc_fuzz_test for full fuzzing
// capabilities (corpus generation, coverage guidance, etc.).
// The FUZZ_TEST macro itself is still used here and should work with a
// FuzzTest-compatible main function (like fuzztest_gtest_main).
#include "fuzztest/fuzztest.h"
#include "fuzztest/internal/domains/xml_domain.h" // Adjust path as necessary
#include <string>
#include <iostream>
#include <stack>
#include <regex>
// A simple placeholder function to "consume" XML strings.
// For a real test, this would be a proper XML parser or processing function.
// This example will just print the generated XML and perform a trivial check.
void ProcessXml(const std::string& xml_string) {
// std::cout << "Generated XML: " << xml_string << std::endl;
// Trivial check: Ensure all opening tags have corresponding closing tags.
// This is a very simplified check and not a full XML validation.
std::regex tag_regex("<([a-zA-Z0-9_:]+)([^>]*)>");
std::smatch match;
std::string::const_iterator search_start(xml_string.cbegin());
std::stack<std::string> open_tags;
while (std::regex_search(search_start, xml_string.cend(), match, tag_regex)) {
std::string tag_name = match[1].str();
std::string full_tag = match[0].str();
if (full_tag.size() > 1 && full_tag[full_tag.size() - 2] == '/') {
// Self-closing tag, ignore for stack balancing.
} else if (full_tag.size() > 0 && full_tag[1] == '/') {
// Closing tag
std::string actual_tag_name = tag_name.substr(1); // Remove '/'
if (open_tags.empty() || open_tags.top() != actual_tag_name) {
// Mismatched closing tag or closing tag without opening.
// For this simple test, we might not fail here,
// as the generator should ideally produce valid structures.
// However, real-world fuzzing would catch this with a proper parser.
// For now, we'll just note it.
// std::cerr << "Mismatched closing tag: " << actual_tag_name << std::endl;
// FUZZTEST_FAIL("Mismatched closing tag"); // Could enable this for stricter test
return; // Stop processing on error
}
if (!open_tags.empty()) {
open_tags.pop();
}
} else {
// Opening tag
open_tags.push(tag_name);
}
search_start = match.suffix().first;
}
// FUZZTEST_ASSERT(open_tags.empty()); // Assert all tags were closed
// If open_tags is not empty, it means some tags were not closed.
// Depending on how strict we want to be with the generator:
if (!open_tags.empty()) {
// std::cerr << "Not all tags were closed. Open tags: " << open_tags.size() << std::endl;
// FUZZTEST_FAIL("Not all tags were closed.");
}
}
// Fuzz test for the ProcessXml function using the XML domain
FUZZ_TEST(XmlFuzzTest, ProcessXmlConsumesValidXml)
.WithDomains(fuzztest::internal::XmlElementDomain());
// Basic test with a fixed string to ensure ProcessXml works as expected for a simple case.
// This is more of a unit test for ProcessXml itself.
TEST(XmlFuzzTest, ProcessXmlSimpleValidCase) {
ProcessXml("<root><item>Test</item></root>");
}
TEST(XmlFuzzTest, ProcessXmlSimpleSelfClosing) {
ProcessXml("<root><item name=\"test\"/></root>");
}
TEST(XmlFuzzTest, ProcessXmlSimpleMismatch) {
// This test is expected to "pass" as ProcessXml currently doesn't hard fail.
ProcessXml("<root><item>Test</mismatch></root>");
}
// To run this test, you would typically need to link against the FuzzTest library
// and have a BUILD file entry. For example (using Bazel):
//
// cc_fuzz_test(
// name = "xml_fuzz_test",
// srcs = ["xml_fuzz_test.cc"],
// corpus = [], // Add seed corpus if any
// deps = [
// "//fuzztest",
// "//fuzztest/internal/domains:xml_domain_h_library", // Assuming xml_domain.h is part of a library
// ],
// )
// For CMake, you would add an executable and link fuzztest::fuzztest_main and other necessary targets.
int main(int argc, char** argv) {
// Initialize FuzzTest
// This is usually handled by cc_fuzz_test in Bazel,
// but if running as a standalone gtest, you might need it.
// testing::InitGoogleTest(&argc, argv); // If mixing with GTest tests.
// return RUN_ALL_TESTS();
// For a pure FuzzTest setup, FuzzTest automatically registers and runs tests.
// If FUZZ_TEST is defined, it implies FuzzTest's main.
// If only TEST is defined, you need Google Test's main.
// The FuzzTest library provides a main function when `FUZZ_TEST` macros are used.
// So, a custom main is often not needed unless for specific GTest setups.
// For Bazel's cc_fuzz_test, no main() is needed here.
// For other build systems, you might need to link with FuzzTest's main library.
return 0; // Placeholder main, actual execution is handled by FuzzTest framework.
}