diff --git a/tests/data/truncation.xml b/tests/data/truncation.xml
new file mode 100644
index 0000000..9cdbe13
--- /dev/null
+++ b/tests/data/truncation.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+ some text
+
+ some more text
+
+
+ <æ+%è¯- å__å--="name" ä>·å__="value">ä¸-ç_æ_%å__å¤_è¯-è¨_ð¤-¢æ+%è¯->
+
+
+ <æ°_å__>
+ <æ°_>å++ç"°æ°_>
+ <å__>太é__å__>
+ æ°_å__>
+
+
diff --git a/tests/test_document.cpp b/tests/test_document.cpp
index f693579..37ec021 100644
--- a/tests/test_document.cpp
+++ b/tests/test_document.cpp
@@ -742,22 +742,24 @@ TEST(document_progressive_truncation)
char* original_data;
size_t original_size;
- CHECK(load_file_in_memory("tests/data/utftest_utf8.xml", original_data, original_size));
+ CHECK(load_file_in_memory("tests/data/truncation.xml", original_data, original_size));
+
+ char* buffer = new char[original_size];
for (size_t i = 1; i < original_size; ++i)
{
- char* truncated_data = new char[i];
+ char* truncated_data = buffer + original_size - i;
+
memcpy(truncated_data, original_data, i);
xml_document doc;
- bool result = doc.load_buffer(truncated_data, i);
+ bool result = doc.load_buffer_inplace(truncated_data, i);
// some truncate locations are parseable - those that come after declaration, declaration + doctype, declaration + doctype + comment and eof
CHECK(((i - 21) < 3 || (i - 66) < 3 || (i - 95) < 3 || i >= 3325) ? result : !result);
-
- delete[] truncated_data;
}
+ delete[] buffer;
delete[] original_data;
}
diff --git a/tests/test_parse_doctype.cpp b/tests/test_parse_doctype.cpp
index 57f38fb..c633467 100644
--- a/tests/test_parse_doctype.cpp
+++ b/tests/test_parse_doctype.cpp
@@ -1,42 +1,63 @@
+#define _CRT_SECURE_NO_WARNINGS
+
#include "common.hpp"
+#include
+#include
#include
-static bool test_doctype_wf(const std::basic_string& decl)
+static xml_parse_result load_concat(xml_document& doc, const char_t* a, const char_t* b = STR(""), const char_t* c = STR(""))
+{
+ char_t buffer[768];
+
+#ifdef PUGIXML_WCHAR_MODE
+ wcscpy(buffer, a);
+ wcscat(buffer, b);
+ wcscat(buffer, c);
+#else
+ strcpy(buffer, a);
+ strcat(buffer, b);
+ strcat(buffer, c);
+#endif
+
+ return doc.load(buffer);
+}
+
+static bool test_doctype_wf(const char_t* decl)
{
xml_document doc;
// standalone
- if (!doc.load(decl.c_str()) || (bool)doc.first_child()) return false;
+ if (!load_concat(doc, decl) || (bool)doc.first_child()) return false;
// pcdata pre/postfix
- if (!doc.load((STR("a") + decl).c_str()) || (bool)doc.first_child()) return false;
- if (!doc.load((decl + STR("b")).c_str()) || (bool)doc.first_child()) return false;
- if (!doc.load((STR("a") + decl + STR("b")).c_str()) || (bool)doc.first_child()) return false;
+ if (!load_concat(doc, STR("a"), decl) || (bool)doc.first_child()) return false;
+ if (!load_concat(doc, decl, STR("b")) || (bool)doc.first_child()) return false;
+ if (!load_concat(doc, STR("a"), decl, STR("b")) || (bool)doc.first_child()) return false;
// node pre/postfix
- if (!doc.load((STR("") + decl).c_str()) || !test_node(doc, STR(""), STR(""), format_raw)) return false;
- if (!doc.load((decl + STR("")).c_str()) || !test_node(doc, STR(""), STR(""), format_raw)) return false;
- if (!doc.load((STR("") + decl + STR("")).c_str()) || !test_node(doc, STR(""), STR(""), format_raw)) return false;
+ if (!load_concat(doc, STR(""), decl) || !test_node(doc, STR(""), STR(""), format_raw)) return false;
+ if (!load_concat(doc, decl, STR("")) || !test_node(doc, STR(""), STR(""), format_raw)) return false;
+ if (!load_concat(doc, STR(""), decl, STR("")) || !test_node(doc, STR(""), STR(""), format_raw)) return false;
// wrap in node to check that doctype is parsed fully (does not leave any "pcdata")
- if (!doc.load((STR("") + decl + STR("")).c_str()) || !test_node(doc, STR(""), STR(""), format_raw)) return false;
+ if (!load_concat(doc, STR(""), decl, STR("")) || !test_node(doc, STR(""), STR(""), format_raw)) return false;
return true;
}
-static bool test_doctype_nwf(const std::basic_string& decl)
+static bool test_doctype_nwf(const char_t* decl)
{
xml_document doc;
// standalone
- if (doc.load(decl.c_str()).status != status_bad_doctype) return false;
+ if (load_concat(doc, decl).status != status_bad_doctype) return false;
// pcdata postfix
- if (doc.load((decl + STR("b")).c_str()).status != status_bad_doctype) return false;
+ if (load_concat(doc, decl, STR("b")).status != status_bad_doctype) return false;
// node postfix
- if (doc.load((decl + STR("")).c_str()).status != status_bad_doctype) return false;
+ if (load_concat(doc, decl, STR("")).status != status_bad_doctype) return false;
return true;
}
diff --git a/tests/test_xpath_xalan_2.cpp b/tests/test_xpath_xalan_2.cpp
index aa8ae17..4ab4928 100644
--- a/tests/test_xpath_xalan_2.cpp
+++ b/tests/test_xpath_xalan_2.cpp
@@ -5,6 +5,7 @@
#include "common.hpp"
#include
+#include
TEST_XML(xpath_xalan_string_1, "ENCYCLOPEDIA")
{
@@ -129,38 +130,53 @@ TEST_XML(xpath_xalan_string_4, "abcdef number_to_string(int number)
+static const char_t* number_to_string_unsafe(int number)
{
- std::basic_string result;
+ static char_t buffer[16];
+
+ // construct number in reverse
+ char_t* it = buffer;
while (number)
{
- result = static_cast('0' + number % 10) + result;
+ *it++ = static_cast('0' + number % 10);
number /= 10;
}
- return result;
+ // zero terminate
+ *it = 0;
+
+ // reverse to get final result
+ std::reverse(buffer, it);
+
+ return buffer;
}
TEST(xpath_xalan_string_5)
{
- std::basic_string query = STR("concat(");
+ const int count = 1000;
- for (int i = 1; i < 1000; ++i)
+ std::basic_string query;
+ query.reserve(17 * count);
+
+ query += STR("concat(");
+
+ for (int i = 1; i < count; ++i)
{
query += STR("concat('t',");
- query += number_to_string(i);
+ query += number_to_string_unsafe(i);
query += STR("), ");
}
query += STR("'')");
std::basic_string expected;
+ expected.reserve(4 * count);
- for (int j = 1; j < 1000; ++j)
+ for (int j = 1; j < count; ++j)
{
expected += STR("t");
- expected += number_to_string(j);
+ expected += number_to_string_unsafe(j);
}
CHECK_XPATH_STRING(xml_node(), query.c_str(), expected.c_str());