summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorArseny Kapoulkine <arseny.kapoulkine@gmail.com>2015-04-14 19:19:13 -0700
committerArseny Kapoulkine <arseny.kapoulkine@gmail.com>2015-04-14 19:23:36 -0700
commit5158ee903be463c189a80715f92235ceb04871a7 (patch)
tree7819105030100ead1763c6936f3cd946ad24cb50 /src
parent2badcbb6743ff803c9cd82db77a1d8a50802058f (diff)
Fix xpath_node_set assignment to provide strong exception guarantee
Since the type of the set was updated before assignment, assigning in out-of-memory condition could change the type to not match the content.
Diffstat (limited to 'src')
-rw-r--r--src/pugixml.cpp17
-rw-r--r--src/pugixml.hpp2
2 files changed, 10 insertions, 9 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index 1c1b539..fbe13f6 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -11025,7 +11025,7 @@ namespace pugi
}
#endif
- PUGI__FN void xpath_node_set::_assign(const_iterator begin_, const_iterator end_)
+ PUGI__FN void xpath_node_set::_assign(const_iterator begin_, const_iterator end_, type_t type_)
{
assert(begin_ <= end_);
@@ -11041,6 +11041,7 @@ namespace pugi
_begin = &_storage;
_end = &_storage + size_;
+ _type = type_;
}
else
{
@@ -11064,6 +11065,7 @@ namespace pugi
// finalize
_begin = storage;
_end = storage + size_;
+ _type = type_;
}
}
@@ -11071,9 +11073,9 @@ namespace pugi
{
}
- PUGI__FN xpath_node_set::xpath_node_set(const_iterator begin_, const_iterator end_, type_t type_): _type(type_), _begin(&_storage), _end(&_storage)
+ PUGI__FN xpath_node_set::xpath_node_set(const_iterator begin_, const_iterator end_, type_t type_): _type(type_unsorted), _begin(&_storage), _end(&_storage)
{
- _assign(begin_, end_);
+ _assign(begin_, end_, type_);
}
PUGI__FN xpath_node_set::~xpath_node_set()
@@ -11081,17 +11083,16 @@ namespace pugi
if (_begin != &_storage) impl::xml_memory::deallocate(_begin);
}
- PUGI__FN xpath_node_set::xpath_node_set(const xpath_node_set& ns): _type(ns._type), _begin(&_storage), _end(&_storage)
+ PUGI__FN xpath_node_set::xpath_node_set(const xpath_node_set& ns): _type(type_unsorted), _begin(&_storage), _end(&_storage)
{
- _assign(ns._begin, ns._end);
+ _assign(ns._begin, ns._end, ns._type);
}
PUGI__FN xpath_node_set& xpath_node_set::operator=(const xpath_node_set& ns)
{
if (this == &ns) return *this;
-
- _type = ns._type;
- _assign(ns._begin, ns._end);
+
+ _assign(ns._begin, ns._end, ns._type);
return *this;
}
diff --git a/src/pugixml.hpp b/src/pugixml.hpp
index 02ca86b..b56f66a 100644
--- a/src/pugixml.hpp
+++ b/src/pugixml.hpp
@@ -1286,7 +1286,7 @@ namespace pugi
xpath_node* _begin;
xpath_node* _end;
- void _assign(const_iterator begin, const_iterator end);
+ void _assign(const_iterator begin, const_iterator end, type_t type);
};
#endif