diff options
| -rw-r--r-- | tests/data/truncation.xml | 19 | ||||
| -rw-r--r-- | tests/test_document.cpp | 12 | ||||
| -rw-r--r-- | tests/test_parse_doctype.cpp | 47 | ||||
| -rw-r--r-- | tests/test_xpath_xalan_2.cpp | 34 | 
4 files changed, 85 insertions, 27 deletions
| 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; + +	std::basic_string<char_t> query; +	query.reserve(17 * count); + +	query += STR("concat("); -	for (int i = 1; i < 1000; ++i) +	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()); | 
