diff options
| author | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2017-01-30 08:52:32 -0800 | 
|---|---|---|
| committer | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2017-01-30 11:51:07 -0800 | 
| commit | bc1e444694427d599710107d3e6b62165380b0b6 (patch) | |
| tree | 7676f5aa9ff7b4b77d48f281b569710b46865e00 /src | |
| parent | 298996df11381fcd3b87ddd02d7b4fef2a62b86e (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.cpp | 28 | 
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 | 
