From 7ed2b09bc0e5b6840be1198702165f5830933eb9 Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Fri, 9 Sep 2022 10:16:36 +0800 Subject: [PATCH] Fix parsing of XML CDATA and add test cases --- core/io/xml_parser.cpp | 2 +- main/tests/test_xml_parser.cpp | 193 ++++++++++++++++++++++++++++++++- 2 files changed, 190 insertions(+), 5 deletions(-) diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp index e4e3f5f3fd8..fb56ea76749 100644 --- a/core/io/xml_parser.cpp +++ b/core/io/xml_parser.cpp @@ -137,7 +137,7 @@ bool XMLParser::_parse_cdata() { ++P; } - if (cDataEnd) { + if (!cDataEnd) { cDataEnd = P; } node_name = String::utf8(cDataBegin, (int)(cDataEnd - cDataBegin)); diff --git a/main/tests/test_xml_parser.cpp b/main/tests/test_xml_parser.cpp index c6014b401c6..766ffa737ed 100644 --- a/main/tests/test_xml_parser.cpp +++ b/main/tests/test_xml_parser.cpp @@ -33,6 +33,7 @@ #include "core/os/os.h" namespace TestXMLParser { + #define CHECK(X) \ if (!(X)) { \ OS::get_singleton()->print("\tFAIL at %s\n", #X); \ @@ -40,15 +41,28 @@ namespace TestXMLParser { } else { \ OS::get_singleton()->print("\tPASS\n"); \ } +#define REQUIRE_EQ(X, Y) \ + if ((X) != (Y)) { \ + OS::get_singleton()->print("\tFAIL at %s != %s\n", #X, #Y); \ + return false; \ + } else { \ + OS::get_singleton()->print("\tPASS\n"); \ + } + +Vector _to_buffer(const String &p_text) { + Vector buff; + for (int i = 0; i < p_text.length(); i++) { + buff.push_back(p_text.get(i)); + } + return buff; +} + bool test_1() { String source = "\ \ Text<AB>\ "; - Vector buff; - for (int i = 0; i < source.length(); i++) { - buff.push_back(source.get(i)); - } + Vector buff = _to_buffer(source); XMLParser parser; parser.open_buffer(buff); @@ -74,9 +88,180 @@ bool test_1() { return true; } +bool test_comments() { + XMLParser parser; + + // Missing end of comment. + { + const String input = ""; + REQUIRE_EQ(parser.open_buffer(_to_buffer(input)), OK); + REQUIRE_EQ(parser.read(), OK); + REQUIRE_EQ(parser.get_node_type(), XMLParser::NodeType::NODE_COMMENT); + REQUIRE_EQ(parser.get_node_name(), " example << "); + } + + // Doctype. + { + const String input = "]>"; + REQUIRE_EQ(parser.open_buffer(_to_buffer(input)), OK); + REQUIRE_EQ(parser.read(), OK); + REQUIRE_EQ(parser.get_node_type(), XMLParser::NodeType::NODE_COMMENT); + REQUIRE_EQ(parser.get_node_name(), "DOCTYPE greeting []"); + } + + return true; +} + +bool test_premature_endings() { + struct Case { + String input; + String expected_name; + XMLParser::NodeType expected_type; + } const cases[] = { + // Incomplete unknown. + { "