mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-11 08:03:55 +00:00
Fix past-the-end dereference in values_and_holders
The value and holder iterator code had a past-the-end iterator dereference. While of course invalid, the dereference didn't actually cause any problems (which is why it wasn't caught before) because the dereferenced value is never actually used and `vector` implementations appear to allow dereferencing the past-the-end iterator. Under a MSVC debug build, however, it fails a debug assertion and aborts. This amends the iterator to just store and use a pointer to the vector (rather than adding a second past-the-end iterator member), checking the type index against the type vector size.
This commit is contained in:
parent
fd47779f40
commit
a403d0e675
@ -311,14 +311,13 @@ public:
|
||||
struct iterator {
|
||||
private:
|
||||
instance *inst;
|
||||
using vec_iter = std::vector<detail::type_info *>::const_iterator;
|
||||
vec_iter typeit;
|
||||
const type_vec *types;
|
||||
value_and_holder curr;
|
||||
friend struct values_and_holders;
|
||||
iterator(instance *inst, const type_vec &tinfo)
|
||||
: inst{inst}, typeit{tinfo.begin()},
|
||||
iterator(instance *inst, const type_vec *tinfo)
|
||||
: inst{inst}, types{tinfo},
|
||||
curr(inst /* instance */,
|
||||
tinfo.size() > 0 ? *typeit : nullptr /* type info */,
|
||||
types->empty() ? nullptr : (*types)[0] /* type info */,
|
||||
0, /* vpos: (non-simple types only): the first vptr comes first */
|
||||
0 /* index */)
|
||||
{}
|
||||
@ -328,18 +327,17 @@ public:
|
||||
bool operator==(const iterator &other) { return curr.index == other.curr.index; }
|
||||
bool operator!=(const iterator &other) { return curr.index != other.curr.index; }
|
||||
iterator &operator++() {
|
||||
if (!inst->simple_layout) {
|
||||
curr.vh += 1 + (*typeit)->holder_size_in_ptrs;
|
||||
curr.type = *(++typeit);
|
||||
}
|
||||
if (!inst->simple_layout)
|
||||
curr.vh += 1 + (*types)[curr.index]->holder_size_in_ptrs;
|
||||
++curr.index;
|
||||
curr.type = curr.index < types->size() ? (*types)[curr.index] : nullptr;
|
||||
return *this;
|
||||
}
|
||||
value_and_holder &operator*() { return curr; }
|
||||
value_and_holder *operator->() { return &curr; }
|
||||
};
|
||||
|
||||
iterator begin() { return iterator(inst, tinfo); }
|
||||
iterator begin() { return iterator(inst, &tinfo); }
|
||||
iterator end() { return iterator(tinfo.size()); }
|
||||
|
||||
iterator find(const type_info *find_type) {
|
||||
|
Loading…
Reference in New Issue
Block a user