diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 53a0526..11995bf 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -264,7 +264,7 @@ PUGI_IMPL_NS_BEGIN while (srclen && *dst && *src == *dst) { - --srclen; ++dst; ++src; + --srclen; ++dst; ++src; } return srclen == 0 && *dst == 0; } @@ -4780,6 +4780,9 @@ PUGI_IMPL_NS_BEGIN // if convert_buffer below throws bad_alloc, we still need to deallocate contents if we own it auto_deleter contents_guard(own ? contents : NULL, xml_memory::deallocate); + // early-out for empty documents to avoid buffer allocation overhead + if (size == 0) return make_parse_result((options & parse_fragment) ? status_ok : status_no_document_element); + // get private buffer char_t* buffer = NULL; size_t length = 0; diff --git a/tests/test_document.cpp b/tests/test_document.cpp index 2226177..7d6a1f1 100644 --- a/tests/test_document.cpp +++ b/tests/test_document.cpp @@ -473,6 +473,17 @@ TEST(document_load_string) CHECK_NODE(doc, STR("")); } +TEST(document_load_string_empty) +{ + xml_document doc; + + CHECK(doc.load_string(STR("")).status == status_no_document_element); + CHECK(!doc.first_child()); + + CHECK(doc.load_string(STR(""), parse_fragment)); + CHECK(!doc.first_child()); +} + TEST(document_load_file) { xml_document doc; @@ -864,6 +875,19 @@ TEST(document_load_buffer_inplace_own) CHECK_NODE(doc, STR("")); } +TEST(document_load_buffer_inplace_own_empty) +{ + allocation_function alloc = get_memory_allocation_function(); + + void* text1 = alloc(1); + void* text2 = alloc(1); + CHECK(text1 && text2); + + xml_document doc; + CHECK(doc.load_buffer_inplace_own(text1, 0, parse_fragment)); + CHECK(doc.load_buffer_inplace_own(text2, 0).status == status_no_document_element); +} + TEST(document_parse_result_bool) { xml_parse_result result;