Merge branch 'master' into compact
This commit is contained in:
commit
a19da1c246
4
Makefile
4
Makefile
@ -30,6 +30,10 @@ ifneq ($(defines),standard)
|
|||||||
CXXFLAGS+=-D $(subst $(COMMA), -D ,$(defines))
|
CXXFLAGS+=-D $(subst $(COMMA), -D ,$(defines))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq ($(findstring PUGIXML_NO_EXCEPTIONS,$(defines)),)
|
||||||
|
CXXFLAGS+=-fno-exceptions
|
||||||
|
endif
|
||||||
|
|
||||||
OBJECTS=$(SOURCES:%=$(BUILD)/%.o)
|
OBJECTS=$(SOURCES:%=$(BUILD)/%.o)
|
||||||
|
|
||||||
all: $(EXECUTABLE)
|
all: $(EXECUTABLE)
|
||||||
|
111
src/pugixml.cpp
111
src/pugixml.cpp
@ -1088,11 +1088,11 @@ PUGI__NS_BEGIN
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
inline xml_allocator& get_allocator(const xml_node_struct* node)
|
template <typename Object> inline xml_allocator& get_allocator(const Object* object)
|
||||||
{
|
{
|
||||||
assert(node);
|
assert(object);
|
||||||
|
|
||||||
return *reinterpret_cast<xml_memory_page*>(node->header & xml_memory_page_pointer_mask)->allocator;
|
return *reinterpret_cast<xml_memory_page*>(object->header & xml_memory_page_pointer_mask)->allocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Object> inline xml_document_struct& get_document(const Object* object)
|
template <typename Object> inline xml_document_struct& get_document(const Object* object)
|
||||||
@ -2235,9 +2235,6 @@ PUGI__NS_BEGIN
|
|||||||
|
|
||||||
assert(begin + size == end);
|
assert(begin + size == end);
|
||||||
(void)!end;
|
(void)!end;
|
||||||
|
|
||||||
// zero-terminate
|
|
||||||
buffer[size] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef PUGIXML_NO_STL
|
#ifndef PUGIXML_NO_STL
|
||||||
@ -4383,6 +4380,15 @@ PUGI__NS_BEGIN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PUGI__FN void node_copy_attribute(xml_attribute_struct* da, xml_attribute_struct* sa)
|
||||||
|
{
|
||||||
|
xml_allocator& alloc = get_allocator(da);
|
||||||
|
xml_allocator* shared_alloc = (&alloc == &get_allocator(sa)) ? &alloc : 0;
|
||||||
|
|
||||||
|
node_copy_string(da->name, da->header, xml_memory_page_name_allocated_mask, sa->name, sa->header, shared_alloc);
|
||||||
|
node_copy_string(da->value, da->header, xml_memory_page_value_allocated_mask, sa->value, sa->header, shared_alloc);
|
||||||
|
}
|
||||||
|
|
||||||
inline bool is_text_node(xml_node_struct* node)
|
inline bool is_text_node(xml_node_struct* node)
|
||||||
{
|
{
|
||||||
xml_node_type type = PUGI__NODETYPE(node);
|
xml_node_type type = PUGI__NODETYPE(node);
|
||||||
@ -4623,6 +4629,7 @@ PUGI__NS_BEGIN
|
|||||||
return status_ok;
|
return status_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function assumes that buffer has extra sizeof(char_t) writable bytes after size
|
||||||
PUGI__FN size_t zero_terminate_buffer(void* buffer, size_t size, xml_encoding encoding)
|
PUGI__FN size_t zero_terminate_buffer(void* buffer, size_t size, xml_encoding encoding)
|
||||||
{
|
{
|
||||||
// We only need to zero-terminate if encoding conversion does not do it for us
|
// We only need to zero-terminate if encoding conversion does not do it for us
|
||||||
@ -4859,6 +4866,9 @@ PUGI__NS_BEGIN
|
|||||||
// second pass: convert to utf8
|
// second pass: convert to utf8
|
||||||
as_utf8_end(result, size, str, length);
|
as_utf8_end(result, size, str, length);
|
||||||
|
|
||||||
|
// zero-terminate
|
||||||
|
result[size] = 0;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5590,41 +5600,59 @@ namespace pugi
|
|||||||
PUGI__FN xml_attribute xml_node::append_copy(const xml_attribute& proto)
|
PUGI__FN xml_attribute xml_node::append_copy(const xml_attribute& proto)
|
||||||
{
|
{
|
||||||
if (!proto) return xml_attribute();
|
if (!proto) return xml_attribute();
|
||||||
|
if (!impl::allow_insert_attribute(type())) return xml_attribute();
|
||||||
|
|
||||||
xml_attribute result = append_attribute(proto.name());
|
xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root)));
|
||||||
result.set_value(proto.value());
|
if (!a) return xml_attribute();
|
||||||
|
|
||||||
return result;
|
impl::append_attribute(a._attr, _root);
|
||||||
|
impl::node_copy_attribute(a._attr, proto._attr);
|
||||||
|
|
||||||
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
PUGI__FN xml_attribute xml_node::prepend_copy(const xml_attribute& proto)
|
PUGI__FN xml_attribute xml_node::prepend_copy(const xml_attribute& proto)
|
||||||
{
|
{
|
||||||
if (!proto) return xml_attribute();
|
if (!proto) return xml_attribute();
|
||||||
|
if (!impl::allow_insert_attribute(type())) return xml_attribute();
|
||||||
|
|
||||||
xml_attribute result = prepend_attribute(proto.name());
|
xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root)));
|
||||||
result.set_value(proto.value());
|
if (!a) return xml_attribute();
|
||||||
|
|
||||||
return result;
|
impl::prepend_attribute(a._attr, _root);
|
||||||
|
impl::node_copy_attribute(a._attr, proto._attr);
|
||||||
|
|
||||||
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
PUGI__FN xml_attribute xml_node::insert_copy_after(const xml_attribute& proto, const xml_attribute& attr)
|
PUGI__FN xml_attribute xml_node::insert_copy_after(const xml_attribute& proto, const xml_attribute& attr)
|
||||||
{
|
{
|
||||||
if (!proto) return xml_attribute();
|
if (!proto) return xml_attribute();
|
||||||
|
if (!impl::allow_insert_attribute(type())) return xml_attribute();
|
||||||
|
if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute();
|
||||||
|
|
||||||
xml_attribute result = insert_attribute_after(proto.name(), attr);
|
xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root)));
|
||||||
result.set_value(proto.value());
|
if (!a) return xml_attribute();
|
||||||
|
|
||||||
return result;
|
impl::insert_attribute_after(a._attr, attr._attr, _root);
|
||||||
|
impl::node_copy_attribute(a._attr, proto._attr);
|
||||||
|
|
||||||
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
PUGI__FN xml_attribute xml_node::insert_copy_before(const xml_attribute& proto, const xml_attribute& attr)
|
PUGI__FN xml_attribute xml_node::insert_copy_before(const xml_attribute& proto, const xml_attribute& attr)
|
||||||
{
|
{
|
||||||
if (!proto) return xml_attribute();
|
if (!proto) return xml_attribute();
|
||||||
|
if (!impl::allow_insert_attribute(type())) return xml_attribute();
|
||||||
|
if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute();
|
||||||
|
|
||||||
xml_attribute result = insert_attribute_before(proto.name(), attr);
|
xml_attribute a(impl::allocate_attribute(impl::get_allocator(_root)));
|
||||||
result.set_value(proto.value());
|
if (!a) return xml_attribute();
|
||||||
|
|
||||||
return result;
|
impl::insert_attribute_before(a._attr, attr._attr, _root);
|
||||||
|
impl::node_copy_attribute(a._attr, proto._attr);
|
||||||
|
|
||||||
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
PUGI__FN xml_node xml_node::append_child(xml_node_type type_)
|
PUGI__FN xml_node xml_node::append_child(xml_node_type type_)
|
||||||
@ -5975,20 +6003,35 @@ namespace pugi
|
|||||||
#ifndef PUGIXML_NO_STL
|
#ifndef PUGIXML_NO_STL
|
||||||
PUGI__FN string_t xml_node::path(char_t delimiter) const
|
PUGI__FN string_t xml_node::path(char_t delimiter) const
|
||||||
{
|
{
|
||||||
xml_node cursor = *this; // Make a copy.
|
if (!_root) return string_t();
|
||||||
|
|
||||||
string_t result = cursor.name();
|
size_t offset = 0;
|
||||||
|
|
||||||
while (cursor.parent())
|
for (xml_node_struct* i = _root; i; i = i->parent)
|
||||||
{
|
{
|
||||||
cursor = cursor.parent();
|
offset += (i != _root);
|
||||||
|
offset += i->name ? impl::strlength(i->name) : 0;
|
||||||
string_t temp = cursor.name();
|
|
||||||
temp += delimiter;
|
|
||||||
temp += result;
|
|
||||||
result.swap(temp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string_t result;
|
||||||
|
result.resize(offset);
|
||||||
|
|
||||||
|
for (xml_node_struct* j = _root; j; j = j->parent)
|
||||||
|
{
|
||||||
|
if (j != _root)
|
||||||
|
result[--offset] = delimiter;
|
||||||
|
|
||||||
|
if (j->name && *j->name)
|
||||||
|
{
|
||||||
|
size_t length = impl::strlength(j->name);
|
||||||
|
|
||||||
|
offset -= length;
|
||||||
|
memcpy(&result[offset], j->name, length * sizeof(char_t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(offset == 0);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -6825,12 +6868,14 @@ namespace pugi
|
|||||||
PUGI__FN bool xml_document::save_file(const char* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const
|
PUGI__FN bool xml_document::save_file(const char* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const
|
||||||
{
|
{
|
||||||
FILE* file = fopen(path_, (flags & format_save_file_text) ? "w" : "wb");
|
FILE* file = fopen(path_, (flags & format_save_file_text) ? "w" : "wb");
|
||||||
|
|
||||||
return impl::save_file_impl(*this, file, indent, flags, encoding);
|
return impl::save_file_impl(*this, file, indent, flags, encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
PUGI__FN bool xml_document::save_file(const wchar_t* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const
|
PUGI__FN bool xml_document::save_file(const wchar_t* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const
|
||||||
{
|
{
|
||||||
FILE* file = impl::open_file_wide(path_, (flags & format_save_file_text) ? L"w" : L"wb");
|
FILE* file = impl::open_file_wide(path_, (flags & format_save_file_text) ? L"w" : L"wb");
|
||||||
|
|
||||||
return impl::save_file_impl(*this, file, indent, flags, encoding);
|
return impl::save_file_impl(*this, file, indent, flags, encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8351,7 +8396,7 @@ PUGI__NS_BEGIN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PUGI__FN xpath_variable* get_variable_scratch(char_t (&buffer)[32], xpath_variable_set* set, const char_t* begin, const char_t* end)
|
PUGI__FN bool get_variable_scratch(char_t (&buffer)[32], xpath_variable_set* set, const char_t* begin, const char_t* end, xpath_variable** out_result)
|
||||||
{
|
{
|
||||||
size_t length = static_cast<size_t>(end - begin);
|
size_t length = static_cast<size_t>(end - begin);
|
||||||
char_t* scratch = buffer;
|
char_t* scratch = buffer;
|
||||||
@ -8360,19 +8405,19 @@ PUGI__NS_BEGIN
|
|||||||
{
|
{
|
||||||
// need to make dummy on-heap copy
|
// need to make dummy on-heap copy
|
||||||
scratch = static_cast<char_t*>(xml_memory::allocate((length + 1) * sizeof(char_t)));
|
scratch = static_cast<char_t*>(xml_memory::allocate((length + 1) * sizeof(char_t)));
|
||||||
if (!scratch) return 0;
|
if (!scratch) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy string to zero-terminated buffer and perform lookup
|
// copy string to zero-terminated buffer and perform lookup
|
||||||
memcpy(scratch, begin, length * sizeof(char_t));
|
memcpy(scratch, begin, length * sizeof(char_t));
|
||||||
scratch[length] = 0;
|
scratch[length] = 0;
|
||||||
|
|
||||||
xpath_variable* result = set->get(scratch);
|
*out_result = set->get(scratch);
|
||||||
|
|
||||||
// free dummy buffer
|
// free dummy buffer
|
||||||
if (scratch != buffer) xml_memory::deallocate(scratch);
|
if (scratch != buffer) xml_memory::deallocate(scratch);
|
||||||
|
|
||||||
return result;
|
return true;
|
||||||
}
|
}
|
||||||
PUGI__NS_END
|
PUGI__NS_END
|
||||||
|
|
||||||
@ -10945,7 +10990,9 @@ PUGI__NS_BEGIN
|
|||||||
if (!_variables)
|
if (!_variables)
|
||||||
throw_error("Unknown variable: variable set is not provided");
|
throw_error("Unknown variable: variable set is not provided");
|
||||||
|
|
||||||
xpath_variable* var = get_variable_scratch(_scratch, _variables, name.begin, name.end);
|
xpath_variable* var = 0;
|
||||||
|
if (!get_variable_scratch(_scratch, _variables, name.begin, name.end, &var))
|
||||||
|
throw_error_oom();
|
||||||
|
|
||||||
if (!var)
|
if (!var)
|
||||||
throw_error("Unknown variable: variable set does not contain the given name");
|
throw_error("Unknown variable: variable set does not contain the given name");
|
||||||
|
@ -27,11 +27,13 @@ const char* test_runner::_temp_path;
|
|||||||
|
|
||||||
static size_t g_memory_total_size = 0;
|
static size_t g_memory_total_size = 0;
|
||||||
static size_t g_memory_total_count = 0;
|
static size_t g_memory_total_count = 0;
|
||||||
|
static size_t g_memory_fail_triggered = false;
|
||||||
|
|
||||||
static void* custom_allocate(size_t size)
|
static void* custom_allocate(size_t size)
|
||||||
{
|
{
|
||||||
if (test_runner::_memory_fail_threshold > 0 && test_runner::_memory_fail_threshold < g_memory_total_size + size)
|
if (test_runner::_memory_fail_threshold > 0 && test_runner::_memory_fail_threshold < g_memory_total_size + size)
|
||||||
{
|
{
|
||||||
|
g_memory_fail_triggered = true;
|
||||||
test_runner::_memory_fail_triggered = true;
|
test_runner::_memory_fail_triggered = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -88,6 +90,7 @@ static bool run_test(test_runner* test)
|
|||||||
#endif
|
#endif
|
||||||
g_memory_total_size = 0;
|
g_memory_total_size = 0;
|
||||||
g_memory_total_count = 0;
|
g_memory_total_count = 0;
|
||||||
|
g_memory_fail_triggered = false;
|
||||||
test_runner::_memory_fail_threshold = 0;
|
test_runner::_memory_fail_threshold = 0;
|
||||||
test_runner::_memory_fail_triggered = false;
|
test_runner::_memory_fail_triggered = false;
|
||||||
|
|
||||||
@ -113,6 +116,12 @@ static bool run_test(test_runner* test)
|
|||||||
|
|
||||||
test->run();
|
test->run();
|
||||||
|
|
||||||
|
if (test_runner::_memory_fail_triggered)
|
||||||
|
{
|
||||||
|
printf("Test %s failed: unguarded memory fail triggered\n", test->_name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (g_memory_total_size != 0 || g_memory_total_count != 0)
|
if (g_memory_total_size != 0 || g_memory_total_count != 0)
|
||||||
{
|
{
|
||||||
printf("Test %s failed: memory leaks found (%u bytes in %u allocations)\n", test->_name, static_cast<unsigned int>(g_memory_total_size), static_cast<unsigned int>(g_memory_total_count));
|
printf("Test %s failed: memory leaks found (%u bytes in %u allocations)\n", test->_name, static_cast<unsigned int>(g_memory_total_size), static_cast<unsigned int>(g_memory_total_count));
|
||||||
|
@ -142,6 +142,12 @@ struct dummy_fixture {};
|
|||||||
#define CHECK_XPATH_FAIL(query) CHECK_XPATH_FAIL_VAR(query, 0)
|
#define CHECK_XPATH_FAIL(query) CHECK_XPATH_FAIL_VAR(query, 0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef PUGIXML_NO_EXCEPTIONS
|
||||||
|
#define CHECK_ALLOC_FAIL(code) CHECK(!test_runner::_memory_fail_triggered); code; CHECK(test_runner::_memory_fail_triggered); test_runner::_memory_fail_triggered = false
|
||||||
|
#else
|
||||||
|
#define CHECK_ALLOC_FAIL(code) CHECK(!test_runner::_memory_fail_triggered); try { code; } catch (std::bad_alloc&) {} CHECK(test_runner::_memory_fail_triggered); test_runner::_memory_fail_triggered = false
|
||||||
|
#endif
|
||||||
|
|
||||||
#define STR(text) PUGIXML_TEXT(text)
|
#define STR(text) PUGIXML_TEXT(text)
|
||||||
|
|
||||||
#ifdef __DMC__
|
#ifdef __DMC__
|
||||||
|
@ -32,9 +32,11 @@ static bool load_file_in_memory(const char* path, char*& data, size_t& size)
|
|||||||
if (!file) return false;
|
if (!file) return false;
|
||||||
|
|
||||||
fseek(file, 0, SEEK_END);
|
fseek(file, 0, SEEK_END);
|
||||||
size = static_cast<size_t>(ftell(file));
|
long length = ftell(file);
|
||||||
fseek(file, 0, SEEK_SET);
|
fseek(file, 0, SEEK_SET);
|
||||||
|
|
||||||
|
CHECK(length >= 0);
|
||||||
|
size = static_cast<size_t>(length);
|
||||||
data = new char[size];
|
data = new char[size];
|
||||||
|
|
||||||
CHECK(fread(data, 1, size, file) == size);
|
CHECK(fread(data, 1, size, file) == size);
|
||||||
@ -110,7 +112,7 @@ TEST(document_load_stream_error)
|
|||||||
|
|
||||||
std::istringstream iss("<node/>");
|
std::istringstream iss("<node/>");
|
||||||
test_runner::_memory_fail_threshold = 1;
|
test_runner::_memory_fail_threshold = 1;
|
||||||
CHECK(doc.load(iss).status == status_out_of_memory);
|
CHECK_ALLOC_FAIL(CHECK(doc.load(iss).status == status_out_of_memory));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(document_load_stream_empty)
|
TEST(document_load_stream_empty)
|
||||||
@ -237,7 +239,7 @@ TEST(document_load_stream_nonseekable_out_of_memory)
|
|||||||
test_runner::_memory_fail_threshold = 1;
|
test_runner::_memory_fail_threshold = 1;
|
||||||
|
|
||||||
pugi::xml_document doc;
|
pugi::xml_document doc;
|
||||||
CHECK(doc.load(in).status == status_out_of_memory);
|
CHECK_ALLOC_FAIL(CHECK(doc.load(in).status == status_out_of_memory));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(document_load_stream_nonseekable_out_of_memory_large)
|
TEST(document_load_stream_nonseekable_out_of_memory_large)
|
||||||
@ -253,7 +255,7 @@ TEST(document_load_stream_nonseekable_out_of_memory_large)
|
|||||||
test_runner::_memory_fail_threshold = 10000 * 8 * 3 / 2;
|
test_runner::_memory_fail_threshold = 10000 * 8 * 3 / 2;
|
||||||
|
|
||||||
pugi::xml_document doc;
|
pugi::xml_document doc;
|
||||||
CHECK(doc.load(in).status == status_out_of_memory);
|
CHECK_ALLOC_FAIL(CHECK(doc.load(in).status == status_out_of_memory));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -300,9 +302,31 @@ TEST(document_load_file_error)
|
|||||||
pugi::xml_document doc;
|
pugi::xml_document doc;
|
||||||
|
|
||||||
CHECK(doc.load_file("filedoesnotexist").status == status_file_not_found);
|
CHECK(doc.load_file("filedoesnotexist").status == status_file_not_found);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(document_load_file_out_of_memory)
|
||||||
|
{
|
||||||
test_runner::_memory_fail_threshold = 1;
|
test_runner::_memory_fail_threshold = 1;
|
||||||
CHECK(doc.load_file("tests/data/small.xml").status == status_out_of_memory);
|
|
||||||
|
pugi::xml_document doc;
|
||||||
|
CHECK_ALLOC_FAIL(CHECK(doc.load_file("tests/data/small.xml").status == status_out_of_memory));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(document_load_file_out_of_memory_file_leak)
|
||||||
|
{
|
||||||
|
test_runner::_memory_fail_threshold = 1;
|
||||||
|
|
||||||
|
pugi::xml_document doc;
|
||||||
|
|
||||||
|
for (int i = 0; i < 256; ++i)
|
||||||
|
{
|
||||||
|
CHECK_ALLOC_FAIL(CHECK(doc.load_file("tests/data/small.xml").status == status_out_of_memory));
|
||||||
|
}
|
||||||
|
|
||||||
|
test_runner::_memory_fail_threshold = 0;
|
||||||
|
|
||||||
|
CHECK(doc.load_file("tests/data/small.xml"));
|
||||||
|
CHECK_NODE(doc, STR("<node />"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(document_load_file_error_previous)
|
TEST(document_load_file_error_previous)
|
||||||
@ -339,7 +363,9 @@ TEST(document_load_file_wide_out_of_memory)
|
|||||||
|
|
||||||
pugi::xml_document doc;
|
pugi::xml_document doc;
|
||||||
|
|
||||||
pugi::xml_parse_result result = doc.load_file(L"tests/data/small.xml");
|
pugi::xml_parse_result result;
|
||||||
|
result.status = status_out_of_memory;
|
||||||
|
CHECK_ALLOC_FAIL(result = doc.load_file(L"tests/data/small.xml"));
|
||||||
|
|
||||||
CHECK(result.status == status_out_of_memory || result.status == status_file_not_found);
|
CHECK(result.status == status_out_of_memory || result.status == status_file_not_found);
|
||||||
}
|
}
|
||||||
@ -1320,7 +1346,7 @@ TEST(document_convert_out_of_memory)
|
|||||||
for (unsigned int src = 0; src < sizeof(files) / sizeof(files[0]); ++src)
|
for (unsigned int src = 0; src < sizeof(files) / sizeof(files[0]); ++src)
|
||||||
{
|
{
|
||||||
xml_document doc;
|
xml_document doc;
|
||||||
CHECK(doc.load_buffer(files[src].data, files[src].size, parse_default, files[src].encoding).status == status_out_of_memory);
|
CHECK_ALLOC_FAIL(CHECK(doc.load_buffer(files[src].data, files[src].size, parse_default, files[src].encoding).status == status_out_of_memory));
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
|
@ -644,7 +644,7 @@ TEST_XML(dom_node_remove_child, "<node><n1/><n2/><n3/><child><n4/></child></node
|
|||||||
|
|
||||||
TEST_XML(dom_node_remove_child_complex, "<node id='1'><n1 id1='1' id2='2'/><n2/><n3/><child><n4/></child></node>")
|
TEST_XML(dom_node_remove_child_complex, "<node id='1'><n1 id1='1' id2='2'/><n2/><n3/><child><n4/></child></node>")
|
||||||
{
|
{
|
||||||
doc.child(STR("node")).remove_child(STR("n1"));
|
CHECK(doc.child(STR("node")).remove_child(STR("n1")));
|
||||||
|
|
||||||
CHECK_NODE(doc, STR("<node id=\"1\"><n2 /><n3 /><child><n4 /></child></node>"));
|
CHECK_NODE(doc, STR("<node id=\"1\"><n2 /><n3 /><child><n4 /></child></node>"));
|
||||||
|
|
||||||
@ -771,6 +771,14 @@ TEST_XML(dom_node_copy_crossdoc, "<node/>")
|
|||||||
CHECK_NODE(newdoc, STR("<node />"));
|
CHECK_NODE(newdoc, STR("<node />"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_XML(dom_node_copy_crossdoc_attribute, "<node attr='value'/>")
|
||||||
|
{
|
||||||
|
xml_document newdoc;
|
||||||
|
newdoc.append_child(STR("copy")).append_copy(doc.child(STR("node")).attribute(STR("attr")));
|
||||||
|
CHECK_NODE(doc, STR("<node attr=\"value\" />"));
|
||||||
|
CHECK_NODE(newdoc, STR("<copy attr=\"value\" />"));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_XML_FLAGS(dom_node_copy_types, "<?xml version='1.0'?><!DOCTYPE id><root><?pi value?><!--comment--><node id='1'>pcdata<![CDATA[cdata]]></node></root>", parse_full)
|
TEST_XML_FLAGS(dom_node_copy_types, "<?xml version='1.0'?><!DOCTYPE id><root><?pi value?><!--comment--><node id='1'>pcdata<![CDATA[cdata]]></node></root>", parse_full)
|
||||||
{
|
{
|
||||||
doc.append_copy(doc.child(STR("root")));
|
doc.append_copy(doc.child(STR("root")));
|
||||||
@ -858,10 +866,10 @@ TEST(dom_string_out_of_memory)
|
|||||||
// no value => long value
|
// no value => long value
|
||||||
test_runner::_memory_fail_threshold = 32;
|
test_runner::_memory_fail_threshold = 32;
|
||||||
|
|
||||||
CHECK(!node.set_name(string));
|
CHECK_ALLOC_FAIL(CHECK(!node.set_name(string)));
|
||||||
CHECK(!text.set_value(string));
|
CHECK_ALLOC_FAIL(CHECK(!text.set_value(string)));
|
||||||
CHECK(!attr.set_name(string));
|
CHECK_ALLOC_FAIL(CHECK(!attr.set_name(string)));
|
||||||
CHECK(!attr.set_value(string));
|
CHECK_ALLOC_FAIL(CHECK(!attr.set_value(string)));
|
||||||
|
|
||||||
// set some names/values
|
// set some names/values
|
||||||
test_runner::_memory_fail_threshold = 0;
|
test_runner::_memory_fail_threshold = 0;
|
||||||
@ -873,10 +881,10 @@ TEST(dom_string_out_of_memory)
|
|||||||
// some value => long value
|
// some value => long value
|
||||||
test_runner::_memory_fail_threshold = 32;
|
test_runner::_memory_fail_threshold = 32;
|
||||||
|
|
||||||
CHECK(!node.set_name(string));
|
CHECK_ALLOC_FAIL(CHECK(!node.set_name(string)));
|
||||||
CHECK(!text.set_value(string));
|
CHECK_ALLOC_FAIL(CHECK(!text.set_value(string)));
|
||||||
CHECK(!attr.set_name(string));
|
CHECK_ALLOC_FAIL(CHECK(!attr.set_name(string)));
|
||||||
CHECK(!attr.set_value(string));
|
CHECK_ALLOC_FAIL(CHECK(!attr.set_value(string)));
|
||||||
|
|
||||||
// check that original state was preserved
|
// check that original state was preserved
|
||||||
test_runner::_memory_fail_threshold = 0;
|
test_runner::_memory_fail_threshold = 0;
|
||||||
@ -897,30 +905,27 @@ TEST(dom_node_out_of_memory)
|
|||||||
xml_attribute a = n.append_attribute(STR("a"));
|
xml_attribute a = n.append_attribute(STR("a"));
|
||||||
CHECK(a);
|
CHECK(a);
|
||||||
|
|
||||||
while (n.append_child(node_comment) || n.append_attribute(STR("b")))
|
CHECK_ALLOC_FAIL(while (n.append_child(node_comment) || n.append_attribute(STR("b"))) { /* nop */ });
|
||||||
{
|
|
||||||
// nop
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify all node modification operations
|
// verify all node modification operations
|
||||||
CHECK(!n.append_child());
|
CHECK_ALLOC_FAIL(CHECK(!n.append_child()));
|
||||||
CHECK(!n.prepend_child());
|
CHECK_ALLOC_FAIL(CHECK(!n.prepend_child()));
|
||||||
CHECK(!n.insert_child_after(node_element, n.first_child()));
|
CHECK_ALLOC_FAIL(CHECK(!n.insert_child_after(node_element, n.first_child())));
|
||||||
CHECK(!n.insert_child_before(node_element, n.first_child()));
|
CHECK_ALLOC_FAIL(CHECK(!n.insert_child_before(node_element, n.first_child())));
|
||||||
CHECK(!n.append_attribute(STR("")));
|
CHECK_ALLOC_FAIL(CHECK(!n.append_attribute(STR(""))));
|
||||||
CHECK(!n.prepend_attribute(STR("")));
|
CHECK_ALLOC_FAIL(CHECK(!n.prepend_attribute(STR(""))));
|
||||||
CHECK(!n.insert_attribute_after(STR(""), a));
|
CHECK_ALLOC_FAIL(CHECK(!n.insert_attribute_after(STR(""), a)));
|
||||||
CHECK(!n.insert_attribute_before(STR(""), a));
|
CHECK_ALLOC_FAIL(CHECK(!n.insert_attribute_before(STR(""), a)));
|
||||||
|
|
||||||
// verify node copy operations
|
// verify node copy operations
|
||||||
CHECK(!n.append_copy(n.first_child()));
|
CHECK_ALLOC_FAIL(CHECK(!n.append_copy(n.first_child())));
|
||||||
CHECK(!n.prepend_copy(n.first_child()));
|
CHECK_ALLOC_FAIL(CHECK(!n.prepend_copy(n.first_child())));
|
||||||
CHECK(!n.insert_copy_after(n.first_child(), n.first_child()));
|
CHECK_ALLOC_FAIL(CHECK(!n.insert_copy_after(n.first_child(), n.first_child())));
|
||||||
CHECK(!n.insert_copy_before(n.first_child(), n.first_child()));
|
CHECK_ALLOC_FAIL(CHECK(!n.insert_copy_before(n.first_child(), n.first_child())));
|
||||||
CHECK(!n.append_copy(a));
|
CHECK_ALLOC_FAIL(CHECK(!n.append_copy(a)));
|
||||||
CHECK(!n.prepend_copy(a));
|
CHECK_ALLOC_FAIL(CHECK(!n.prepend_copy(a)));
|
||||||
CHECK(!n.insert_copy_after(a, a));
|
CHECK_ALLOC_FAIL(CHECK(!n.insert_copy_after(a, a)));
|
||||||
CHECK(!n.insert_copy_before(a, a));
|
CHECK_ALLOC_FAIL(CHECK(!n.insert_copy_before(a, a)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(dom_node_memory_limit)
|
TEST(dom_node_memory_limit)
|
||||||
@ -1043,7 +1048,7 @@ TEST_XML(dom_node_append_buffer_remove, "<node>test</node>")
|
|||||||
|
|
||||||
CHECK_NODE(doc, STR("<node>test</node>"));
|
CHECK_NODE(doc, STR("<node>test</node>"));
|
||||||
|
|
||||||
doc.remove_child(STR("node"));
|
CHECK(doc.remove_child(STR("node")));
|
||||||
|
|
||||||
CHECK(!doc.first_child());
|
CHECK(!doc.first_child());
|
||||||
}
|
}
|
||||||
@ -1085,7 +1090,7 @@ TEST(dom_node_append_buffer_out_of_memory_extra)
|
|||||||
test_runner::_memory_fail_threshold = 1;
|
test_runner::_memory_fail_threshold = 1;
|
||||||
|
|
||||||
xml_document doc;
|
xml_document doc;
|
||||||
CHECK(doc.append_buffer("<n/>", 4).status == status_out_of_memory);
|
CHECK_ALLOC_FAIL(CHECK(doc.append_buffer("<n/>", 4).status == status_out_of_memory));
|
||||||
CHECK(!doc.first_child());
|
CHECK(!doc.first_child());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1096,10 +1101,46 @@ TEST(dom_node_append_buffer_out_of_memory_buffer)
|
|||||||
char data[128] = {0};
|
char data[128] = {0};
|
||||||
|
|
||||||
xml_document doc;
|
xml_document doc;
|
||||||
CHECK(doc.append_buffer(data, sizeof(data)).status == status_out_of_memory);
|
CHECK_ALLOC_FAIL(CHECK(doc.append_buffer(data, sizeof(data)).status == status_out_of_memory));
|
||||||
CHECK(!doc.first_child());
|
CHECK(!doc.first_child());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(dom_node_append_buffer_out_of_memory_nodes)
|
||||||
|
{
|
||||||
|
unsigned int count = 4000;
|
||||||
|
std::basic_string<char_t> data;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < count; ++i)
|
||||||
|
data += STR("<a/>");
|
||||||
|
|
||||||
|
test_runner::_memory_fail_threshold = 32768 + 128 + data.length() * sizeof(char_t) + 32;
|
||||||
|
|
||||||
|
xml_document doc;
|
||||||
|
CHECK_ALLOC_FAIL(CHECK(doc.append_buffer(data.c_str(), data.length() * sizeof(char_t), parse_fragment).status == status_out_of_memory));
|
||||||
|
|
||||||
|
unsigned int valid = 0;
|
||||||
|
|
||||||
|
for (xml_node n = doc.first_child(); n; n = n.next_sibling())
|
||||||
|
{
|
||||||
|
CHECK_STRING(n.name(), STR("a"));
|
||||||
|
valid++;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(valid > 0 && valid < count);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(dom_node_append_buffer_out_of_memory_name)
|
||||||
|
{
|
||||||
|
test_runner::_memory_fail_threshold = 32768 + 128;
|
||||||
|
|
||||||
|
char data[128] = {0};
|
||||||
|
|
||||||
|
xml_document doc;
|
||||||
|
CHECK(doc.append_child(STR("root")));
|
||||||
|
CHECK_ALLOC_FAIL(CHECK(doc.first_child().append_buffer(data, sizeof(data)).status == status_out_of_memory));
|
||||||
|
CHECK_STRING(doc.first_child().name(), STR("root"));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_XML(dom_node_append_buffer_fragment, "<node />")
|
TEST_XML(dom_node_append_buffer_fragment, "<node />")
|
||||||
{
|
{
|
||||||
xml_node node = doc.child(STR("node"));
|
xml_node node = doc.child(STR("node"));
|
||||||
@ -1381,7 +1422,7 @@ TEST(dom_node_copy_copyless_mix)
|
|||||||
CHECK_NODE(copy2, dataxml.c_str());
|
CHECK_NODE(copy2, dataxml.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_XML(dom_node_copyless_taint, "<node attr=\"value\" />")
|
TEST_XML(dom_node_copy_copyless_taint, "<node attr=\"value\" />")
|
||||||
{
|
{
|
||||||
xml_node node = doc.child(STR("node"));
|
xml_node node = doc.child(STR("node"));
|
||||||
xml_node copy = doc.append_copy(node);
|
xml_node copy = doc.append_copy(node);
|
||||||
@ -1405,13 +1446,65 @@ TEST_XML(dom_node_copyless_taint, "<node attr=\"value\" />")
|
|||||||
CHECK_NODE(doc, STR("<nod1 attr=\"value\" /><node attr=\"valu2\" /><node att3=\"value\" />"));
|
CHECK_NODE(doc, STR("<nod1 attr=\"value\" /><node attr=\"valu2\" /><node att3=\"value\" />"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(dom_node_copy_attribute_copyless)
|
||||||
|
{
|
||||||
|
std::basic_string<char_t> data;
|
||||||
|
data += STR("<node attr=\"");
|
||||||
|
for (int i = 0; i < 10000; ++i)
|
||||||
|
data += STR("data");
|
||||||
|
data += STR("\" />");
|
||||||
|
|
||||||
|
std::basic_string<char_t> datacopy = data;
|
||||||
|
|
||||||
|
// the document is parsed in-place so there should only be 1 page worth of allocations
|
||||||
|
test_runner::_memory_fail_threshold = 32768 + 128;
|
||||||
|
|
||||||
|
xml_document doc;
|
||||||
|
CHECK(doc.load_buffer_inplace(&datacopy[0], datacopy.size() * sizeof(char_t), parse_full));
|
||||||
|
|
||||||
|
// this copy should share all string storage; since there are not a lot of nodes we should not have *any* allocations here (everything will fit in the same page in the document)
|
||||||
|
xml_node copy1 = doc.append_child(STR("node"));
|
||||||
|
copy1.append_copy(doc.first_child().first_attribute());
|
||||||
|
|
||||||
|
xml_node copy2 = doc.append_child(STR("node"));
|
||||||
|
copy2.append_copy(copy1.first_attribute());
|
||||||
|
|
||||||
|
CHECK_NODE(copy1, data.c_str());
|
||||||
|
CHECK_NODE(copy2, data.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_XML(dom_node_copy_attribute_copyless_taint, "<node attr=\"value\" />")
|
||||||
|
{
|
||||||
|
xml_node node = doc.child(STR("node"));
|
||||||
|
xml_attribute attr = node.first_attribute();
|
||||||
|
|
||||||
|
xml_node copy1 = doc.append_child(STR("copy1"));
|
||||||
|
xml_node copy2 = doc.append_child(STR("copy2"));
|
||||||
|
xml_node copy3 = doc.append_child(STR("copy3"));
|
||||||
|
|
||||||
|
CHECK_NODE(doc, STR("<node attr=\"value\" /><copy1 /><copy2 /><copy3 />"));
|
||||||
|
|
||||||
|
copy1.append_copy(attr);
|
||||||
|
|
||||||
|
CHECK_NODE(doc, STR("<node attr=\"value\" /><copy1 attr=\"value\" /><copy2 /><copy3 />"));
|
||||||
|
|
||||||
|
attr.set_name(STR("att1"));
|
||||||
|
copy2.append_copy(attr);
|
||||||
|
|
||||||
|
CHECK_NODE(doc, STR("<node att1=\"value\" /><copy1 attr=\"value\" /><copy2 att1=\"value\" /><copy3 />"));
|
||||||
|
|
||||||
|
copy1.first_attribute().set_value(STR("valu2"));
|
||||||
|
copy3.append_copy(copy1.first_attribute());
|
||||||
|
|
||||||
|
CHECK_NODE(doc, STR("<node att1=\"value\" /><copy1 attr=\"valu2\" /><copy2 att1=\"value\" /><copy3 attr=\"valu2\" />"));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_XML(dom_node_copy_out_of_memory_node, "<node><child1 /><child2 /><child3>text1<child4 />text2</child3></node>")
|
TEST_XML(dom_node_copy_out_of_memory_node, "<node><child1 /><child2 /><child3>text1<child4 />text2</child3></node>")
|
||||||
{
|
{
|
||||||
test_runner::_memory_fail_threshold = 32768 * 2 + 4096;
|
test_runner::_memory_fail_threshold = 32768 * 2 + 4096;
|
||||||
|
|
||||||
xml_document copy;
|
xml_document copy;
|
||||||
for (int i = 0; i < 1000; ++i)
|
CHECK_ALLOC_FAIL(for (int i = 0; i < 1000; ++i) copy.append_copy(doc.first_child()));
|
||||||
copy.append_copy(doc.first_child());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_XML(dom_node_copy_out_of_memory_attr, "<node attr1='' attr2='' attr3='' attr4='' attr5='' attr6='' attr7='' attr8='' attr9='' attr10='' attr11='' attr12='' attr13='' attr14='' attr15='' />")
|
TEST_XML(dom_node_copy_out_of_memory_attr, "<node attr1='' attr2='' attr3='' attr4='' attr5='' attr6='' attr7='' attr8='' attr9='' attr10='' attr11='' attr12='' attr13='' attr14='' attr15='' />")
|
||||||
@ -1419,8 +1512,7 @@ TEST_XML(dom_node_copy_out_of_memory_attr, "<node attr1='' attr2='' attr3='' att
|
|||||||
test_runner::_memory_fail_threshold = 32768 * 2 + 4096;
|
test_runner::_memory_fail_threshold = 32768 * 2 + 4096;
|
||||||
|
|
||||||
xml_document copy;
|
xml_document copy;
|
||||||
for (int i = 0; i < 1000; ++i)
|
CHECK_ALLOC_FAIL(for (int i = 0; i < 1000; ++i) copy.append_copy(doc.first_child()));
|
||||||
copy.append_copy(doc.first_child());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_XML(dom_node_remove_deallocate, "<node attr='value'>text</node>")
|
TEST_XML(dom_node_remove_deallocate, "<node attr='value'>text</node>")
|
||||||
|
@ -1085,14 +1085,24 @@ TEST_XML(dom_unspecified_bool_coverage, "<node attr='value'>text</node>")
|
|||||||
{
|
{
|
||||||
xml_node node = doc.first_child();
|
xml_node node = doc.first_child();
|
||||||
|
|
||||||
|
CHECK(node);
|
||||||
static_cast<void (*)(xml_node***)>(node)(0);
|
static_cast<void (*)(xml_node***)>(node)(0);
|
||||||
|
|
||||||
|
CHECK(node.first_attribute());
|
||||||
static_cast<void (*)(xml_attribute***)>(node.first_attribute())(0);
|
static_cast<void (*)(xml_attribute***)>(node.first_attribute())(0);
|
||||||
|
|
||||||
|
CHECK(node.text());
|
||||||
static_cast<void (*)(xml_text***)>(node.text())(0);
|
static_cast<void (*)(xml_text***)>(node.text())(0);
|
||||||
|
|
||||||
#ifndef PUGIXML_NO_XPATH
|
#ifndef PUGIXML_NO_XPATH
|
||||||
xpath_query q(STR("/node"));
|
xpath_query q(STR("/node"));
|
||||||
|
|
||||||
|
CHECK(q);
|
||||||
static_cast<void (*)(xpath_query***)>(q)(0);
|
static_cast<void (*)(xpath_query***)>(q)(0);
|
||||||
static_cast<void (*)(xpath_node***)>(q.evaluate_node(doc))(0);
|
|
||||||
|
xpath_node qn = q.evaluate_node(doc);
|
||||||
|
|
||||||
|
CHECK(qn);
|
||||||
|
static_cast<void (*)(xpath_node***)>(qn)(0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -873,7 +873,7 @@ TEST(parse_out_of_memory)
|
|||||||
test_runner::_memory_fail_threshold = 256;
|
test_runner::_memory_fail_threshold = 256;
|
||||||
|
|
||||||
xml_document doc;
|
xml_document doc;
|
||||||
CHECK(doc.load_string(STR("<foo a='1'/>")).status == status_out_of_memory);
|
CHECK_ALLOC_FAIL(CHECK(doc.load_string(STR("<foo a='1'/>")).status == status_out_of_memory));
|
||||||
CHECK(!doc.first_child());
|
CHECK(!doc.first_child());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -893,7 +893,7 @@ TEST(parse_out_of_memory_halfway_node)
|
|||||||
test_runner::_memory_fail_threshold = 65536;
|
test_runner::_memory_fail_threshold = 65536;
|
||||||
|
|
||||||
xml_document doc;
|
xml_document doc;
|
||||||
CHECK(doc.load_buffer_inplace(text, count * 4).status == status_out_of_memory);
|
CHECK_ALLOC_FAIL(CHECK(doc.load_buffer_inplace(text, count * 4).status == status_out_of_memory));
|
||||||
CHECK_NODE(doc.first_child(), STR("<n />"));
|
CHECK_NODE(doc.first_child(), STR("<n />"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -920,12 +920,21 @@ TEST(parse_out_of_memory_halfway_attr)
|
|||||||
test_runner::_memory_fail_threshold = 65536;
|
test_runner::_memory_fail_threshold = 65536;
|
||||||
|
|
||||||
xml_document doc;
|
xml_document doc;
|
||||||
CHECK(doc.load_buffer_inplace(text, count * 5 + 4).status == status_out_of_memory);
|
CHECK_ALLOC_FAIL(CHECK(doc.load_buffer_inplace(text, count * 5 + 4).status == status_out_of_memory));
|
||||||
CHECK_STRING(doc.first_child().name(), STR("n"));
|
CHECK_STRING(doc.first_child().name(), STR("n"));
|
||||||
CHECK_STRING(doc.first_child().first_attribute().name(), STR("a"));
|
CHECK_STRING(doc.first_child().first_attribute().name(), STR("a"));
|
||||||
CHECK_STRING(doc.first_child().last_attribute().name(), STR("a"));
|
CHECK_STRING(doc.first_child().last_attribute().name(), STR("a"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(parse_out_of_memory_conversion)
|
||||||
|
{
|
||||||
|
test_runner::_memory_fail_threshold = 256;
|
||||||
|
|
||||||
|
xml_document doc;
|
||||||
|
CHECK_ALLOC_FAIL(CHECK(doc.load_buffer("<foo\x90/>", 7, parse_default, encoding_latin1).status == status_out_of_memory));
|
||||||
|
CHECK(!doc.first_child());
|
||||||
|
}
|
||||||
|
|
||||||
static bool test_offset(const char_t* contents, unsigned int options, pugi::xml_parse_status status, ptrdiff_t offset)
|
static bool test_offset(const char_t* contents, unsigned int options, pugi::xml_parse_status status, ptrdiff_t offset)
|
||||||
{
|
{
|
||||||
xml_document doc;
|
xml_document doc;
|
||||||
@ -941,7 +950,7 @@ TEST(parse_error_offset)
|
|||||||
CHECK_OFFSET("<node/>", parse_default, status_ok, 0);
|
CHECK_OFFSET("<node/>", parse_default, status_ok, 0);
|
||||||
|
|
||||||
test_runner::_memory_fail_threshold = 1;
|
test_runner::_memory_fail_threshold = 1;
|
||||||
CHECK_OFFSET("<node/>", parse_default, status_out_of_memory, 0);
|
CHECK_ALLOC_FAIL(CHECK_OFFSET("<node/>", parse_default, status_out_of_memory, 0));
|
||||||
test_runner::_memory_fail_threshold = 0;
|
test_runner::_memory_fail_threshold = 0;
|
||||||
|
|
||||||
CHECK_OFFSET("<3d/>", parse_default, status_unrecognized_tag, 1);
|
CHECK_OFFSET("<3d/>", parse_default, status_unrecognized_tag, 1);
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
TEST_XML(write_simple, "<node attr='1'><child>text</child></node>")
|
TEST_XML(write_simple, "<node attr='1'><child>text</child></node>")
|
||||||
{
|
{
|
||||||
@ -574,3 +575,41 @@ TEST_XML_FLAGS(write_mixed, "<node><child1/><child2>pre<![CDATA[data]]>mid<!--co
|
|||||||
CHECK_NODE_EX(doc, STR("<node>\n<child1 />\n<child2>pre<![CDATA[data]]>mid<!--comment-->\n<test />post<?pi value?>fin</child2>\n<child3 />\n</node>\n"), STR("\t"), 0);
|
CHECK_NODE_EX(doc, STR("<node>\n<child1 />\n<child2>pre<![CDATA[data]]>mid<!--comment-->\n<test />post<?pi value?>fin</child2>\n<child3 />\n</node>\n"), STR("\t"), 0);
|
||||||
CHECK_NODE_EX(doc, STR("<node>\n\t<child1 />\n\t<child2>pre<![CDATA[data]]>mid<!--comment-->\n\t\t<test />post<?pi value?>fin</child2>\n\t<child3 />\n</node>\n"), STR("\t"), format_indent);
|
CHECK_NODE_EX(doc, STR("<node>\n\t<child1 />\n\t<child2>pre<![CDATA[data]]>mid<!--comment-->\n\t\t<test />post<?pi value?>fin</child2>\n\t<child3 />\n</node>\n"), STR("\t"), format_indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef PUGIXML_NO_EXCEPTIONS
|
||||||
|
struct throwing_writer: pugi::xml_writer
|
||||||
|
{
|
||||||
|
virtual void write(const void*, size_t)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("write failed");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_XML(write_throw_simple, "<node><child/></node>")
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throwing_writer w;
|
||||||
|
doc.print(w);
|
||||||
|
|
||||||
|
CHECK_FORCE_FAIL("Expected exception");
|
||||||
|
}
|
||||||
|
catch (std::runtime_error&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_XML(write_throw_encoding, "<node><child/></node>")
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throwing_writer w;
|
||||||
|
doc.print(w, STR("\t"), format_default, encoding_utf32_be);
|
||||||
|
|
||||||
|
CHECK_FORCE_FAIL("Expected exception");
|
||||||
|
}
|
||||||
|
catch (std::runtime_error&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@ -378,19 +378,7 @@ TEST(xpath_out_of_memory_evaluate_concat)
|
|||||||
|
|
||||||
pugi::xpath_query q(query.c_str());
|
pugi::xpath_query q(query.c_str());
|
||||||
|
|
||||||
#ifdef PUGIXML_NO_EXCEPTIONS
|
CHECK_ALLOC_FAIL(CHECK(q.evaluate_string(0, 0, xml_node()) == 1));
|
||||||
CHECK(q.evaluate_string(0, 0, xml_node()) == 1);
|
|
||||||
#else
|
|
||||||
try
|
|
||||||
{
|
|
||||||
q.evaluate_string(0, 0, xml_node());
|
|
||||||
|
|
||||||
CHECK_FORCE_FAIL("Expected out of memory exception");
|
|
||||||
}
|
|
||||||
catch (const std::bad_alloc&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(xpath_out_of_memory_evaluate_substring)
|
TEST(xpath_out_of_memory_evaluate_substring)
|
||||||
@ -404,19 +392,7 @@ TEST(xpath_out_of_memory_evaluate_substring)
|
|||||||
|
|
||||||
pugi::xpath_query q(query.c_str());
|
pugi::xpath_query q(query.c_str());
|
||||||
|
|
||||||
#ifdef PUGIXML_NO_EXCEPTIONS
|
CHECK_ALLOC_FAIL(CHECK(q.evaluate_string(0, 0, xml_node()) == 1));
|
||||||
CHECK(q.evaluate_string(0, 0, xml_node()) == 1);
|
|
||||||
#else
|
|
||||||
try
|
|
||||||
{
|
|
||||||
q.evaluate_string(0, 0, xml_node());
|
|
||||||
|
|
||||||
CHECK_FORCE_FAIL("Expected out of memory exception");
|
|
||||||
}
|
|
||||||
catch (const std::bad_alloc&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_XML(xpath_out_of_memory_evaluate_union, "<node><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/></node>")
|
TEST_XML(xpath_out_of_memory_evaluate_union, "<node><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/></node>")
|
||||||
@ -425,19 +401,7 @@ TEST_XML(xpath_out_of_memory_evaluate_union, "<node><a/><a/><a/><a/><a/><a/><a/>
|
|||||||
|
|
||||||
pugi::xpath_query q(STR("a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|a)))))))))))))))))))"));
|
pugi::xpath_query q(STR("a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|a)))))))))))))))))))"));
|
||||||
|
|
||||||
#ifdef PUGIXML_NO_EXCEPTIONS
|
CHECK_ALLOC_FAIL(CHECK(q.evaluate_node_set(doc.child(STR("node"))).empty()));
|
||||||
CHECK(q.evaluate_node_set(doc.child(STR("node"))).empty());
|
|
||||||
#else
|
|
||||||
try
|
|
||||||
{
|
|
||||||
q.evaluate_node_set(doc.child(STR("node")));
|
|
||||||
|
|
||||||
CHECK_FORCE_FAIL("Expected out of memory exception");
|
|
||||||
}
|
|
||||||
catch (const std::bad_alloc&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_XML(xpath_out_of_memory_evaluate_predicate, "<node><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/></node>")
|
TEST_XML(xpath_out_of_memory_evaluate_predicate, "<node><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/></node>")
|
||||||
@ -446,19 +410,7 @@ TEST_XML(xpath_out_of_memory_evaluate_predicate, "<node><a/><a/><a/><a/><a/><a/>
|
|||||||
|
|
||||||
pugi::xpath_query q(STR("//a[//a[//a[//a[//a[//a[//a[//a[//a[//a[//a[//a[//a[//a[true()]]]]]]]]]]]]]]"));
|
pugi::xpath_query q(STR("//a[//a[//a[//a[//a[//a[//a[//a[//a[//a[//a[//a[//a[//a[true()]]]]]]]]]]]]]]"));
|
||||||
|
|
||||||
#ifdef PUGIXML_NO_EXCEPTIONS
|
CHECK_ALLOC_FAIL(CHECK(q.evaluate_node_set(doc).empty()));
|
||||||
CHECK(q.evaluate_node_set(doc).empty());
|
|
||||||
#else
|
|
||||||
try
|
|
||||||
{
|
|
||||||
q.evaluate_node_set(doc);
|
|
||||||
|
|
||||||
CHECK_FORCE_FAIL("Expected out of memory exception");
|
|
||||||
}
|
|
||||||
catch (const std::bad_alloc&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(xpath_memory_concat_massive)
|
TEST(xpath_memory_concat_massive)
|
||||||
@ -634,20 +586,8 @@ TEST(xpath_allocate_string_out_of_memory)
|
|||||||
|
|
||||||
test_runner::_memory_fail_threshold = 8*1024;
|
test_runner::_memory_fail_threshold = 8*1024;
|
||||||
|
|
||||||
#ifdef PUGIXML_NO_EXCEPTIONS
|
#ifndef __DMC__ // DigitalMars exception handling crashes instead of catching the exception...
|
||||||
CHECK(!xpath_query(query.c_str()));
|
CHECK_ALLOC_FAIL(CHECK(!xpath_query(query.c_str())));
|
||||||
#else
|
|
||||||
try
|
|
||||||
{
|
|
||||||
#ifndef __DMC__ // DigitalMars exception handling crashes instead of catching the exception...
|
|
||||||
xpath_query q(query.c_str());
|
|
||||||
|
|
||||||
CHECK_FORCE_FAIL("Expected out of memory exception");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
catch (const std::bad_alloc&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,6 +356,7 @@ TEST(xpath_api_exception_what)
|
|||||||
CHECK(e.what()[0] != 0);
|
CHECK(e.what()[0] != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST(xpath_api_node_set_ctor_out_of_memory)
|
TEST(xpath_api_node_set_ctor_out_of_memory)
|
||||||
{
|
{
|
||||||
@ -363,15 +364,7 @@ TEST(xpath_api_node_set_ctor_out_of_memory)
|
|||||||
|
|
||||||
xpath_node data[2];
|
xpath_node data[2];
|
||||||
|
|
||||||
try
|
CHECK_ALLOC_FAIL(xpath_node_set ns(data, data + 2));
|
||||||
{
|
|
||||||
xpath_node_set ns(data, data + 2);
|
|
||||||
|
|
||||||
CHECK_FORCE_FAIL("Expected out of memory exception");
|
|
||||||
}
|
|
||||||
catch (const std::bad_alloc&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(xpath_api_node_set_copy_ctor_out_of_memory)
|
TEST(xpath_api_node_set_copy_ctor_out_of_memory)
|
||||||
@ -381,15 +374,7 @@ TEST(xpath_api_node_set_copy_ctor_out_of_memory)
|
|||||||
|
|
||||||
test_runner::_memory_fail_threshold = 1;
|
test_runner::_memory_fail_threshold = 1;
|
||||||
|
|
||||||
try
|
CHECK_ALLOC_FAIL(xpath_node_set copy = ns);
|
||||||
{
|
|
||||||
xpath_node_set copy = ns;
|
|
||||||
|
|
||||||
CHECK_FORCE_FAIL("Expected out of memory exception");
|
|
||||||
}
|
|
||||||
catch (const std::bad_alloc&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_XML(xpath_api_node_set_assign_out_of_memory_preserve, "<node><a/><b/></node>")
|
TEST_XML(xpath_api_node_set_assign_out_of_memory_preserve, "<node><a/><b/></node>")
|
||||||
@ -402,19 +387,10 @@ TEST_XML(xpath_api_node_set_assign_out_of_memory_preserve, "<node><a/><b/></node
|
|||||||
|
|
||||||
test_runner::_memory_fail_threshold = 1;
|
test_runner::_memory_fail_threshold = 1;
|
||||||
|
|
||||||
try
|
CHECK_ALLOC_FAIL(ns = nsall);
|
||||||
{
|
|
||||||
ns = nsall;
|
|
||||||
|
|
||||||
CHECK_FORCE_FAIL("Expected out of memory exception");
|
|
||||||
}
|
|
||||||
catch (const std::bad_alloc&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CHECK(ns.size() == 2 && ns[0] == doc.child(STR("node")).child(STR("a")) && ns[1] == doc.child(STR("node")).child(STR("b")));
|
CHECK(ns.size() == 2 && ns[0] == doc.child(STR("node")).child(STR("a")) && ns[1] == doc.child(STR("node")).child(STR("b")));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
TEST_XML(xpath_api_deprecated_select_single_node, "<node><head/><foo id='1'/><foo/><tail/></node>")
|
TEST_XML(xpath_api_deprecated_select_single_node, "<node><head/><foo id='1'/><foo/><tail/></node>")
|
||||||
{
|
{
|
||||||
|
@ -272,44 +272,25 @@ TEST_XML(xpath_parse_absolute, "<div><s/></div>")
|
|||||||
CHECK_XPATH_NODESET(doc, STR("/*[/]")) % 2;
|
CHECK_XPATH_NODESET(doc, STR("/*[/]")) % 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PUGIXML_NO_EXCEPTIONS
|
|
||||||
# define CHECK_XPATH_FAIL_OOM(query) CHECK_XPATH_FAIL(query)
|
|
||||||
#else
|
|
||||||
static void test_xpath_fail_oom(const char_t* query)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
pugi::xpath_query q(query);
|
|
||||||
|
|
||||||
CHECK_FORCE_FAIL("Expected out of memory exception");
|
|
||||||
}
|
|
||||||
catch (const std::bad_alloc&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# define CHECK_XPATH_FAIL_OOM(query) test_xpath_fail_oom(query)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
TEST(xpath_parse_out_of_memory_first_page)
|
TEST(xpath_parse_out_of_memory_first_page)
|
||||||
{
|
{
|
||||||
test_runner::_memory_fail_threshold = 1;
|
test_runner::_memory_fail_threshold = 1;
|
||||||
|
|
||||||
CHECK_XPATH_FAIL_OOM(STR("1"));
|
CHECK_ALLOC_FAIL(CHECK_XPATH_FAIL(STR("1")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(xpath_parse_out_of_memory_second_page_node)
|
TEST(xpath_parse_out_of_memory_second_page_node)
|
||||||
{
|
{
|
||||||
test_runner::_memory_fail_threshold = 8192;
|
test_runner::_memory_fail_threshold = 8192;
|
||||||
|
|
||||||
CHECK_XPATH_FAIL_OOM(STR("1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1"));
|
CHECK_ALLOC_FAIL(CHECK_XPATH_FAIL(STR("1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(xpath_parse_out_of_memory_string_to_number)
|
TEST(xpath_parse_out_of_memory_string_to_number)
|
||||||
{
|
{
|
||||||
test_runner::_memory_fail_threshold = 4096 + 128;
|
test_runner::_memory_fail_threshold = 4096 + 128;
|
||||||
|
|
||||||
CHECK_XPATH_FAIL_OOM(STR("0.11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"));
|
CHECK_ALLOC_FAIL(CHECK_XPATH_FAIL(STR("0.11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(xpath_parse_qname_error)
|
TEST(xpath_parse_qname_error)
|
||||||
|
@ -177,7 +177,8 @@ TEST(xpath_variables_set_out_of_memory)
|
|||||||
|
|
||||||
xpath_variable_set set;
|
xpath_variable_set set;
|
||||||
|
|
||||||
xpath_variable* var = set.add(STR("target"), xpath_type_number);
|
xpath_variable* var = 0;
|
||||||
|
CHECK_ALLOC_FAIL(var = set.add(STR("target"), xpath_type_number));
|
||||||
CHECK(!var);
|
CHECK(!var);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +191,7 @@ TEST(xpath_variables_out_of_memory)
|
|||||||
xpath_variable* var = set.add(STR("target"), xpath_type_string);
|
xpath_variable* var = set.add(STR("target"), xpath_type_string);
|
||||||
CHECK(var);
|
CHECK(var);
|
||||||
|
|
||||||
CHECK(!var->set(STR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")));
|
CHECK_ALLOC_FAIL(CHECK(!var->set(STR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_XML(xpath_variables_evaluate, "<node/>")
|
TEST_XML(xpath_variables_evaluate, "<node/>")
|
||||||
@ -283,20 +284,7 @@ TEST(xpath_variables_long_name_out_of_memory)
|
|||||||
|
|
||||||
test_runner::_memory_fail_threshold = 4096 + 64 + 52 * sizeof(char_t);
|
test_runner::_memory_fail_threshold = 4096 + 64 + 52 * sizeof(char_t);
|
||||||
|
|
||||||
#ifdef PUGIXML_NO_EXCEPTIONS
|
CHECK_ALLOC_FAIL(CHECK(!xpath_query(STR("$abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), &set)));
|
||||||
xpath_query q(STR("$abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), &set);
|
|
||||||
CHECK(!q);
|
|
||||||
#else
|
|
||||||
try
|
|
||||||
{
|
|
||||||
xpath_query q(STR("$abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), &set);
|
|
||||||
|
|
||||||
CHECK_FORCE_FAIL("Expected exception");
|
|
||||||
}
|
|
||||||
catch (const xpath_exception&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_XML(xpath_variables_select, "<node attr='1'/><node attr='2'/>")
|
TEST_XML(xpath_variables_select, "<node attr='1'/><node attr='2'/>")
|
||||||
|
Loading…
Reference in New Issue
Block a user