Pugixml XML parser

Update to upstream master
This commit is contained in:
Laurent Trinques
2020-07-26 16:14:31 +02:00
parent a2eb92803a
commit 9cdc023f31
3 changed files with 115 additions and 89 deletions

View File

@@ -378,7 +378,7 @@ PUGI__NS_BEGIN
static PUGI__UNSIGNED_OVERFLOW unsigned int hash(const void* key)
{
unsigned int h = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(key));
unsigned int h = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(key) & 0xffffffff);
// MurmurHash3 32-bit finalizer
h ^= h >> 16;
@@ -4435,6 +4435,9 @@ PUGI__NS_BEGIN
while (sit && sit != sn)
{
// loop invariant: dit is inside the subtree rooted at dn
assert(dit);
// when a tree is copied into one of the descendants, we need to skip that subtree to avoid an infinite loop
if (sit != dn)
{
@@ -4464,9 +4467,14 @@ PUGI__NS_BEGIN
sit = sit->parent;
dit = dit->parent;
// loop invariant: dit is inside the subtree rooted at dn while sit is inside sn
assert(sit == sn || dit);
}
while (sit != sn);
}
assert(!sit || dit == dn->parent);
}
PUGI__FN void node_copy_attribute(xml_attribute_struct* da, xml_attribute_struct* sa)
@@ -6949,8 +6957,7 @@ namespace pugi
{
reset();
for (xml_node cur = proto.first_child(); cur; cur = cur.next_sibling())
append_copy(cur);
impl::node_copy_tree(_root, proto._root);
}
PUGI__FN void xml_document::_create()
@@ -10414,35 +10421,38 @@ PUGI__NS_BEGIN
if (_rettype == xpath_type_boolean)
return _data.variable->get_boolean();
// variable needs to be converted to the correct type, this is handled by the fallthrough block below
break;
}
// fallthrough
default:
{
switch (_rettype)
{
case xpath_type_number:
return convert_number_to_boolean(eval_number(c, stack));
case xpath_type_string:
{
xpath_allocator_capture cr(stack.result);
return !eval_string(c, stack).empty();
}
case xpath_type_node_set:
{
xpath_allocator_capture cr(stack.result);
return !eval_node_set(c, stack, nodeset_eval_any).empty();
}
default:
assert(false && "Wrong expression for return type boolean"); // unreachable
return false;
}
;
}
// none of the ast types that return the value directly matched, we need to perform type conversion
switch (_rettype)
{
case xpath_type_number:
return convert_number_to_boolean(eval_number(c, stack));
case xpath_type_string:
{
xpath_allocator_capture cr(stack.result);
return !eval_string(c, stack).empty();
}
case xpath_type_node_set:
{
xpath_allocator_capture cr(stack.result);
return !eval_node_set(c, stack, nodeset_eval_any).empty();
}
default:
assert(false && "Wrong expression for return type boolean"); // unreachable
return false;
}
}
@@ -10549,36 +10559,38 @@ PUGI__NS_BEGIN
if (_rettype == xpath_type_number)
return _data.variable->get_number();
// variable needs to be converted to the correct type, this is handled by the fallthrough block below
break;
}
// fallthrough
default:
{
switch (_rettype)
{
case xpath_type_boolean:
return eval_boolean(c, stack) ? 1 : 0;
case xpath_type_string:
{
xpath_allocator_capture cr(stack.result);
return convert_string_to_number(eval_string(c, stack).c_str());
}
case xpath_type_node_set:
{
xpath_allocator_capture cr(stack.result);
return convert_string_to_number(eval_string(c, stack).c_str());
}
default:
assert(false && "Wrong expression for return type number"); // unreachable
return 0;
}
;
}
// none of the ast types that return the value directly matched, we need to perform type conversion
switch (_rettype)
{
case xpath_type_boolean:
return eval_boolean(c, stack) ? 1 : 0;
case xpath_type_string:
{
xpath_allocator_capture cr(stack.result);
return convert_string_to_number(eval_string(c, stack).c_str());
}
case xpath_type_node_set:
{
xpath_allocator_capture cr(stack.result);
return convert_string_to_number(eval_string(c, stack).c_str());
}
default:
assert(false && "Wrong expression for return type number"); // unreachable
return 0;
}
}
@@ -10833,34 +10845,37 @@ PUGI__NS_BEGIN
if (_rettype == xpath_type_string)
return xpath_string::from_const(_data.variable->get_string());
// variable needs to be converted to the correct type, this is handled by the fallthrough block below
break;
}
// fallthrough
default:
{
switch (_rettype)
{
case xpath_type_boolean:
return xpath_string::from_const(eval_boolean(c, stack) ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false"));
case xpath_type_number:
return convert_number_to_string(eval_number(c, stack), stack.result);
case xpath_type_node_set:
{
xpath_allocator_capture cr(stack.temp);
xpath_stack swapped_stack = {stack.temp, stack.result};
xpath_node_set_raw ns = eval_node_set(c, swapped_stack, nodeset_eval_first);
return ns.empty() ? xpath_string() : string_value(ns.first(), stack.result);
}
default:
assert(false && "Wrong expression for return type string"); // unreachable
return xpath_string();
}
;
}
// none of the ast types that return the value directly matched, we need to perform type conversion
switch (_rettype)
{
case xpath_type_boolean:
return xpath_string::from_const(eval_boolean(c, stack) ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false"));
case xpath_type_number:
return convert_number_to_string(eval_number(c, stack), stack.result);
case xpath_type_node_set:
{
xpath_allocator_capture cr(stack.temp);
xpath_stack swapped_stack = {stack.temp, stack.result};
xpath_node_set_raw ns = eval_node_set(c, swapped_stack, nodeset_eval_first);
return ns.empty() ? xpath_string() : string_value(ns.first(), stack.result);
}
default:
assert(false && "Wrong expression for return type string"); // unreachable
return xpath_string();
}
}
@@ -10982,13 +10997,18 @@ PUGI__NS_BEGIN
return ns;
}
// variable needs to be converted to the correct type, this is handled by the fallthrough block below
break;
}
// fallthrough
default:
assert(false && "Wrong expression for return type node set"); // unreachable
return xpath_node_set_raw();
;
}
// none of the ast types that return the value directly matched, but conversions to node set are invalid
assert(false && "Wrong expression for return type node set"); // unreachable
return xpath_node_set_raw();
}
void optimize(xpath_allocator* alloc)
@@ -11063,7 +11083,7 @@ PUGI__NS_BEGIN
// Use optimized path for @attr = 'value' or @attr = $value
if (_type == ast_op_equal &&
_left && _right && // workaround for clang static analyzer and Coverity (_left and _right are never null for ast_op_equal)
// coverity[mixed_enums]
// coverity[mixed_enums]
_left->_type == ast_step && _left->_axis == axis_attribute && _left->_test == nodetest_name && !_left->_left && !_left->_right &&
(_right->_type == ast_string_constant || (_right->_type == ast_variable && _right->_rettype == xpath_type_string)))
{
@@ -12926,4 +12946,3 @@ namespace pugi
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/