From ab72b14d17a1f80ee049cdd8c77e973960fea108 Mon Sep 17 00:00:00 2001 From: "arseny.kapoulkine" Date: Sun, 13 Jun 2010 19:24:20 +0000 Subject: 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 --- tests/main.cpp | 2 +- tests/test_dom_modify.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++++++ tests/test_parse.cpp | 31 +++++++++++++++++++ 3 files changed, 109 insertions(+), 1 deletion(-) (limited to 'tests') 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("")); } + +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("t")); +} + +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("")).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("")); + + delete[] text; +} -- cgit v1.2.3