boostorg / move

Boost.org move module
http://boost.org/libs/move
Boost Software License 1.0
19 stars 55 forks source link

inserting into default-constructed flat_set creates null references #32

Closed sxeraverx closed 3 years ago

sxeraverx commented 4 years ago

The start of the underlying vector of a default-constructed flat_set points to null.

Merging into the flat_set involves converting the iterators to pointers as an optimization for contiguous containers (https://github.com/boostorg/container/blob/develop/include/boost/container/detail/flat_tree.hpp#L130)

However, for a default-constructed flat-set, the pointer underlying begin() iterator points to null.

The iterator-to-pointer conversion is done by taking the address of the result of dereferencing the pointer. (https://github.com/boostorg/move/blob/develop/include/boost/move/detail/iterator_to_raw_pointer.hpp#L36-L53)

As an intermediate step, this ends up creating a null reference, which is undefined behavior.

This should probably be fixed by comparing the iterator to a default-constructed iterator and returning nullptr if they compare equal, before attempting to dereference the iterator.

sxeraverx commented 4 years ago

One more thought--using iterator_to_raw_pointer as an optimization for coming up with the end() pointer for a contiguous datastructure also seems broken because it dereferences a one-past-the-end pointer in the process.

igaztanaga commented 3 years ago

Revising the code, iterator_to_raw_pointer returns the internal pointer via i.operator->(); at least for boost::container::vector, which is the default container. Where is the null reference created?

igaztanaga commented 3 years ago

Closing as the report misses information and I can't reproduce it (maybe I'm not understanding something important?). Please reopen in case the problem persists.