diff options
| -rw-r--r-- | src/pugixml.cpp | 35 | 
1 files changed, 13 insertions, 22 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp index d66f9f9..67591a3 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -8536,6 +8536,7 @@ PUGI__NS_BEGIN  		static void apply_predicate_const(xpath_node_set_raw& ns, size_t first, xpath_ast_node* expr, const xpath_stack& stack)  		{  			assert(ns.size() >= first); +			assert(expr->rettype() == xpath_type_number);  			size_t size = ns.size() - first; @@ -8543,27 +8544,17 @@ PUGI__NS_BEGIN  			xpath_context c(xpath_node(), 1, size); -			if (expr->rettype() == xpath_type_number) +			double er = expr->eval_number(c, stack); + +			if (er >= 1.0 && er <= size)  			{ -				double er = expr->eval_number(c, stack); +				size_t eri = static_cast<size_t>(er); -				if (er >= 1.0 && er <= size) +				if (er == eri)  				{ -					size_t eri = static_cast<size_t>(er); - -					if (er == eri) -					{ -						xpath_node r = last[eri - 1]; +					xpath_node r = last[eri - 1]; -						*last++ = r; -					} -				} -			} -			else -			{ -				if (expr->eval_boolean(c, stack)) -				{ -					last += size; +					*last++ = r;  				}  			} @@ -9781,16 +9772,16 @@ PUGI__NS_BEGIN  				if (_right->_type == ast_number_constant && _right->_data.number == 1.0)  					_test = predicate_constant_one; -				else if (_right->_type == ast_number_constant || _right->_type == ast_variable) +				else if (_right->_rettype == xpath_type_number && (_right->_type == ast_number_constant || _right->_type == ast_variable))  					_test = predicate_constant;  				else if (_right->_rettype != xpath_type_number && _right->is_posinv_expr())  					_test = predicate_posinv;  			} -			// Replace descendant-or-self::node()/child::foo with descendant::foo +			// Rewrite descendant-or-self::node()/child::foo with descendant::foo  			// The former is a full form of //foo, the latter is much faster since it executes the node test immediately -			// Do a similar kind of replacement for self/descendant/descendant-or-self axes -			// Note that we only replace positionally invariant steps (//foo[1] != /descendant::foo[1]) +			// Do a similar kind of rewrite for self/descendant/descendant-or-self axes +			// Note that we only rewrite positionally invariant steps (//foo[1] != /descendant::foo[1])  			if (_type == ast_step && (_axis == axis_child || _axis == axis_self || _axis == axis_descendant || _axis == axis_descendant_or_self) && _left &&  				_left->_type == ast_step && _left->_axis == axis_descendant_or_self && _left->_test == nodetest_type_node && !_left->_right &&  				is_posinv_step()) @@ -9803,7 +9794,7 @@ PUGI__NS_BEGIN  				_left = _left->_left;  			} -			// Replace translate() with constant arguments with a table +			// Use optimized lookup table implementation for translate() with constant arguments  			if (_type == ast_func_translate && _right->_type == ast_string_constant && _right->_next->_type == ast_string_constant)  			{  				unsigned char* table = translate_table_generate(alloc, _right->_data.string, _right->_next->_data.string);  | 
