summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorarseny.kapoulkine <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640>2010-06-13 19:24:20 +0000
committerarseny.kapoulkine <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640>2010-06-13 19:24:20 +0000
commitab72b14d17a1f80ee049cdd8c77e973960fea108 (patch)
tree9e86e841eb0e5c2ca73198bdce2718e80e25317d /tests
parente5014db32a79816c3a114b3de586ae28beb28c95 (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.cpp2
-rw-r--r--tests/test_dom_modify.cpp77
-rw-r--r--tests/test_parse.cpp31
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;
+}