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 @@
+<?xml version="1.0"?>
+<!DOCTYPE é_+å + SYSTEM "weekly-utf-8.dtd">
+<!-- é_+å +ã'÷ã__ã_-ã_< -->
+<mesh name="mesh_root">
+	<!-- here is a mesh node -->
+	some text
+	<![CDATA[someothertext]]>
+	some more text
+	<node attr1="value1" attr2="value2" />
+	<node attr1="value2">
+		<æ+%è¯- å__å--="name" ä>·å__="value">ä¸-ç_æ_%å__å¤_è¯-è¨_ð¤-¢</æ+%è¯->
+		<innernode/>
+	</node>
+	<æ°_å__>
+		<æ°_>å++ç"°</æ°_>
+		<å__>å¤ªé__</å__>
+	</æ°_å__>
+	<?include somedata?>
+</mesh>
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 <string.h>
+#include <wchar.h>
 #include <string>
 
-static bool test_doctype_wf(const std::basic_string<char_t>& 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("<nodea/>") + decl).c_str()) || !test_node(doc, STR("<nodea />"), STR(""), format_raw)) return false;
-	if (!doc.load((decl + STR("<nodeb/>")).c_str()) || !test_node(doc, STR("<nodeb />"), STR(""), format_raw)) return false;
-	if (!doc.load((STR("<nodea/>") + decl + STR("<nodeb/>")).c_str()) || !test_node(doc, STR("<nodea /><nodeb />"), STR(""), format_raw)) return false;
+	if (!load_concat(doc, STR("<nodea/>"), decl) || !test_node(doc, STR("<nodea />"), STR(""), format_raw)) return false;
+	if (!load_concat(doc, decl, STR("<nodeb/>")) || !test_node(doc, STR("<nodeb />"), STR(""), format_raw)) return false;
+	if (!load_concat(doc, STR("<nodea/>"), decl, STR("<nodeb/>")) || !test_node(doc, STR("<nodea /><nodeb />"), STR(""), format_raw)) return false;
 
 	// wrap in node to check that doctype is parsed fully (does not leave any "pcdata")
-	if (!doc.load((STR("<node>") + decl + STR("</node>")).c_str()) || !test_node(doc, STR("<node />"), STR(""), format_raw)) return false;
+	if (!load_concat(doc, STR("<node>"), decl, STR("</node>")) || !test_node(doc, STR("<node />"), STR(""), format_raw)) return false;
 
 	return true;
 }
 
-static bool test_doctype_nwf(const std::basic_string<char_t>& 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("<nodeb/>")).c_str()).status != status_bad_doctype) return false;
+	if (load_concat(doc, decl, STR("<nodeb/>")).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 <string>
+#include <algorithm>
 
 TEST_XML(xpath_xalan_string_1, "<doc a='test'>ENCYCLOPEDIA</doc>")
 {
@@ -129,38 +130,53 @@ TEST_XML(xpath_xalan_string_4, "<doc><a>a</a><b>b</b><c>c</c><d>d</d><e>ef</e><f
 	CHECK_XPATH_STRING(c, STR("translate('quan+ti-ty', 'AQU-+EOS', concat(\"aqu'\", '\"eos'))"), STR("quan\"ti'ty"));
 }
 
-static std::basic_string<char_t> number_to_string(int number)
+static const char_t* number_to_string_unsafe(int number)
 {
-	std::basic_string<char_t> result;
+	static char_t buffer[16];
+
+	// construct number in reverse
+	char_t* it = buffer;
 
 	while (number)
 	{
-		result = static_cast<char_t>('0' + number % 10) + result;
+		*it++ = static_cast<char_t>('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<char_t> query = STR("concat(");
+	const int count = 1000;
 
-	for (int i = 1; i < 1000; ++i)
+	std::basic_string<char_t> 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<char_t> 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());
