diff options
| author | arseny.kapoulkine <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640> | 2010-06-13 19:24:20 +0000 | 
|---|---|---|
| committer | arseny.kapoulkine <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640> | 2010-06-13 19:24:20 +0000 | 
| commit | ab72b14d17a1f80ee049cdd8c77e973960fea108 (patch) | |
| tree | 9e86e841eb0e5c2ca73198bdce2718e80e25317d /tests | |
| parent | e5014db32a79816c3a114b3de586ae28beb28c95 (diff) | |
Internal XML parsing error handling is done via setjmp/longjmp, all allocation errors are now handled correctly (parser returns status_out_of_memory, modification functions return errors); added tests for some out of memory situations
git-svn-id: http://pugixml.googlecode.com/svn/trunk@520 99668b35-9821-0410-8761-19e4c4f06640
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/main.cpp | 2 | ||||
| -rw-r--r-- | tests/test_dom_modify.cpp | 77 | ||||
| -rw-r--r-- | tests/test_parse.cpp | 31 | 
3 files changed, 109 insertions, 1 deletions
| diff --git a/tests/main.cpp b/tests/main.cpp index 444b188..b8d4e53 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -15,7 +15,7 @@ static size_t g_memory_total_count = 0;  static void* custom_allocate(size_t size)
  {
 -	if (test_runner::_memory_fail_threshold > 0 && test_runner::_memory_fail_threshold < size)
 +	if (test_runner::_memory_fail_threshold > 0 && test_runner::_memory_fail_threshold < g_memory_total_size + size)
  		return 0;
  	else
  	{
 diff --git a/tests/test_dom_modify.cpp b/tests/test_dom_modify.cpp index e1e47f7..fac3eba 100644 --- a/tests/test_dom_modify.cpp +++ b/tests/test_dom_modify.cpp @@ -580,3 +580,80 @@ TEST(dom_node_declaration_copy)  	CHECK_NODE(doc, STR("<?xml?><node />"));
  }
 +
 +TEST(dom_string_out_of_memory)
 +{
 +	unsigned int length = 65536;
 +
 +	char_t* string = new char_t[length + 1];
 +	for (unsigned int i = 0; i < length; ++i) string[i] = 'a';
 +	string[length] = 0;
 +
 +	xml_document doc;
 +	xml_node node = doc.append_child();
 +	xml_attribute attr = node.append_attribute(STR("a"));
 +	xml_node text = node.append_child(node_pcdata);
 +
 +	// no value => long value
 +	test_runner::_memory_fail_threshold = 32;
 +
 +	CHECK(!node.set_name(string));
 +	CHECK(!text.set_value(string));
 +	CHECK(!attr.set_name(string));
 +	CHECK(!attr.set_value(string));
 +
 +	// set some names/values
 +	test_runner::_memory_fail_threshold = 0;
 +
 +	node.set_name(STR("n"));
 +	attr.set_value(STR("v"));
 +	text.set_value(STR("t"));
 +
 +	// some value => long value
 +	test_runner::_memory_fail_threshold = 32;
 +
 +	CHECK(!node.set_name(string));
 +	CHECK(!text.set_value(string));
 +	CHECK(!attr.set_name(string));
 +	CHECK(!attr.set_value(string));
 +
 +	// check that original state was preserved
 +	test_runner::_memory_fail_threshold = 0;
 +
 +	CHECK_NODE(doc, STR("<n a=\"v\">t</n>"));
 +}
 +
 +TEST(dom_node_out_of_memory)
 +{
 +	test_runner::_memory_fail_threshold = 65536;
 +
 +	// exhaust memory limit
 +	xml_document doc;
 +
 +	xml_node n = doc.append_child();
 +	CHECK(n.set_name(STR("n")));
 +
 +	xml_attribute a = n.append_attribute(STR("a"));
 +	CHECK(a);
 +
 +	while (n.append_child(node_comment) || n.append_attribute(STR("b")))
 +	{
 +		// nop
 +	}
 +
 +	// verify all node modification operations
 +	CHECK(!n.append_child());
 +	CHECK(!n.insert_child_after(node_element, n.first_child()));
 +	CHECK(!n.insert_child_before(node_element, n.first_child()));
 +	CHECK(!n.append_attribute(STR("")));
 +	CHECK(!n.insert_attribute_after(STR(""), a));
 +	CHECK(!n.insert_attribute_before(STR(""), a));
 +
 +	// verify node copy operations
 +	CHECK(!n.append_copy(n.first_child()));
 +	CHECK(!n.insert_copy_after(n.first_child(), n.first_child()));
 +	CHECK(!n.insert_copy_before(n.first_child(), n.first_child()));
 +	CHECK(!n.append_copy(a));
 +	CHECK(!n.insert_copy_after(a, a));
 +	CHECK(!n.insert_copy_before(a, a));
 +}
 diff --git a/tests/test_parse.cpp b/tests/test_parse.cpp index 7d4958a..735f1bc 100644 --- a/tests/test_parse.cpp +++ b/tests/test_parse.cpp @@ -585,3 +585,34 @@ TEST(parse_empty)  	xml_document doc;
  	CHECK(doc.load(STR("")) && !doc.first_child());
  }
 +
 +TEST(parse_out_of_memory)
 +{
 +	test_runner::_memory_fail_threshold = 256;
 +
 +	xml_document doc;
 +	CHECK(doc.load(STR("<foo a='1'/>")).status == status_out_of_memory);
 +	CHECK(!doc.first_child());
 +}
 +
 +TEST(parse_out_of_memory_halfway)
 +{
 +	unsigned int count = 10000;
 +	char_t* text = new char_t[count * 4];
 +
 +	for (unsigned int i = 0; i < count; ++i)
 +	{
 +		text[4*i + 0] = '<';
 +		text[4*i + 1] = 'n';
 +		text[4*i + 2] = '/';
 +		text[4*i + 3] = '>';
 +	}
 +
 +	test_runner::_memory_fail_threshold = 65536;
 +
 +	xml_document doc;
 +	CHECK(doc.load_buffer_inplace(text, count * 4).status == status_out_of_memory);
 +	CHECK_NODE(doc.first_child(), STR("<n />"));
 +
 +	delete[] text;
 +}
 | 
