summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorArseny Kapoulkine <arseny.kapoulkine@gmail.com>2017-01-30 08:52:32 -0800
committerArseny Kapoulkine <arseny.kapoulkine@gmail.com>2017-01-30 11:51:07 -0800
commitbc1e444694427d599710107d3e6b62165380b0b6 (patch)
tree7676f5aa9ff7b4b77d48f281b569710b46865e00 /src
parent298996df11381fcd3b87ddd02d7b4fef2a62b86e (diff)
XPath: Track allocation errors more explicitly
Any time an allocation fails xpath_allocator can set an externally provided bool. The plan is to keep this bool up until evaluation ends, so that we can use it to discard the potentially malformed result.
Diffstat (limited to 'src')
-rw-r--r--src/pugixml.cpp28
1 files changed, 20 insertions, 8 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index 6b9fc89..396061a 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -7396,13 +7396,14 @@ PUGI__NS_BEGIN
{
xpath_memory_block* _root;
size_t _root_size;
+ bool* _error;
public:
#ifdef PUGIXML_NO_EXCEPTIONS
jmp_buf* error_handler;
#endif
- xpath_allocator(xpath_memory_block* root, size_t root_size = 0): _root(root), _root_size(root_size)
+ xpath_allocator(xpath_memory_block* root, bool* error = 0): _root(root), _root_size(0), _error(error)
{
#ifdef PUGIXML_NO_EXCEPTIONS
error_handler = 0;
@@ -7430,7 +7431,11 @@ PUGI__NS_BEGIN
size_t block_size = block_capacity + offsetof(xpath_memory_block, data);
xpath_memory_block* block = static_cast<xpath_memory_block*>(xml_memory::allocate(block_size));
- if (!block) return 0;
+ if (!block)
+ {
+ if (_error) *_error = true;
+ return 0;
+ }
block->next = _root;
block->capacity = block_capacity;
@@ -7579,6 +7584,7 @@ PUGI__NS_BEGIN
struct xpath_stack_data
{
+ bool error;
xpath_memory_block blocks[2];
xpath_allocator result;
xpath_allocator temp;
@@ -7588,7 +7594,7 @@ PUGI__NS_BEGIN
jmp_buf error_handler;
#endif
- xpath_stack_data(): result(blocks + 0), temp(blocks + 1)
+ xpath_stack_data(): error(false), result(blocks + 0, &error), temp(blocks + 1, &error)
{
blocks[0].next = blocks[1].next = 0;
blocks[0].capacity = blocks[1].capacity = sizeof(blocks[0].data);
@@ -11856,7 +11862,9 @@ PUGI__NS_BEGIN
xpath_context c(n, 1, 1);
- return impl->root->eval_string(c, sd.stack);
+ xpath_string r = impl->root->eval_string(c, sd.stack);
+
+ return sd.error ? xpath_string() : r;
}
PUGI__FN impl::xpath_ast_node* evaluate_node_set_prepare(xpath_query_impl* impl)
@@ -12494,7 +12502,9 @@ namespace pugi
if (setjmp(sd.error_handler)) return false;
#endif
- return static_cast<impl::xpath_query_impl*>(_impl)->root->eval_boolean(c, sd.stack);
+ bool r = static_cast<impl::xpath_query_impl*>(_impl)->root->eval_boolean(c, sd.stack);
+
+ return sd.error ? false : r;
}
PUGI__FN double xpath_query::evaluate_number(const xpath_node& n) const
@@ -12508,7 +12518,9 @@ namespace pugi
if (setjmp(sd.error_handler)) return impl::gen_nan();
#endif
- return static_cast<impl::xpath_query_impl*>(_impl)->root->eval_number(c, sd.stack);
+ double r = static_cast<impl::xpath_query_impl*>(_impl)->root->eval_number(c, sd.stack);
+
+ return sd.error ? impl::gen_nan() : r;
}
#ifndef PUGIXML_NO_STL
@@ -12556,7 +12568,7 @@ namespace pugi
impl::xpath_node_set_raw r = root->eval_node_set(c, sd.stack, impl::nodeset_eval_all);
- return xpath_node_set(r.begin(), r.end(), r.type());
+ return sd.error ? xpath_node_set() : xpath_node_set(r.begin(), r.end(), r.type());
}
PUGI__FN xpath_node xpath_query::evaluate_node(const xpath_node& n) const
@@ -12573,7 +12585,7 @@ namespace pugi
impl::xpath_node_set_raw r = root->eval_node_set(c, sd.stack, impl::nodeset_eval_first);
- return r.first();
+ return sd.error ? xpath_node() : r.first();
}
PUGI__FN const xpath_parse_result& xpath_query::result() const