| // 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. |
| } |