mirror of
https://github.com/pybind/pybind11.git
synced 2025-01-19 09:25:51 +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 {
|
struct iterator {
|
||||||
private:
|
private:
|
||||||
instance *inst;
|
instance *inst;
|
||||||
using vec_iter = std::vector<detail::type_info *>::const_iterator;
|
const type_vec *types;
|
||||||
vec_iter typeit;
|
|
||||||
value_and_holder curr;
|
value_and_holder curr;
|
||||||
friend struct values_and_holders;
|
friend struct values_and_holders;
|
||||||
iterator(instance *inst, const type_vec &tinfo)
|
iterator(instance *inst, const type_vec *tinfo)
|
||||||
: inst{inst}, typeit{tinfo.begin()},
|
: inst{inst}, types{tinfo},
|
||||||
curr(inst /* instance */,
|
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, /* vpos: (non-simple types only): the first vptr comes first */
|
||||||
0 /* index */)
|
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; }
|
||||||
bool operator!=(const iterator &other) { return curr.index != other.curr.index; }
|
bool operator!=(const iterator &other) { return curr.index != other.curr.index; }
|
||||||
iterator &operator++() {
|
iterator &operator++() {
|
||||||
if (!inst->simple_layout) {
|
if (!inst->simple_layout)
|
||||||
curr.vh += 1 + (*typeit)->holder_size_in_ptrs;
|
curr.vh += 1 + (*types)[curr.index]->holder_size_in_ptrs;
|
||||||
curr.type = *(++typeit);
|
|
||||||
}
|
|
||||||
++curr.index;
|
++curr.index;
|
||||||
|
curr.type = curr.index < types->size() ? (*types)[curr.index] : nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
value_and_holder &operator*() { return curr; }
|
value_and_holder &operator*() { return curr; }
|
||||||
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 end() { return iterator(tinfo.size()); }
|
||||||
|
|
||||||
iterator find(const type_info *find_type) {
|
iterator find(const type_info *find_type) {
|
||||||
|
Loading…
Reference in New Issue
Block a user