[Boost-bugs] [Boost C++ Libraries] #13635: circular_buffer does not always initialize elements

Subject: [Boost-bugs] [Boost C++ Libraries] #13635: circular_buffer does not always initialize elements
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2018-07-17 08:41:42


#13635: circular_buffer does not always initialize elements
-------------------------------------------+-----------------------------
 Reporter: Niklas Fejes <niklas.fejes@…> | Owner: Jan Gaspar
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: circular_buffer
  Version: Boost Development Trunk | Severity: Problem
 Keywords: |
-------------------------------------------+-----------------------------
 The circular_buffer erroneously mark some sections of the buffer as
 initialized, which can lead to use of uninitialized memory for non-trivial
 classes in the {{{insert}}} function. The problem appears to come from the
 {{{is_uninitialized}}} function, which does not properly handle the buffer
 state when {{{m_buff < m_first < m_last}}}.
 {{{#!c++
 bool is_uninitialized(const_pointer p) const BOOST_NOEXCEPT {
     return p >= m_last && (m_first < m_last || p < m_first);
 }
 }}}
 In this case, e.g. {{{p = m_buff}}} will be flagged as initialized since
 {{{p >= m_last}}} is {{{false}}}.

 A proper check would be:
 {{{#!c++
 bool is_uninitialized(const_pointer p) const BOOST_NOEXCEPT {
     if (m_first < m_last)
         return p >= m_last || p < m_first;
     return p >= m_last && p < m_first;
 }
 }}}
 Minimal reproducing program:
 {{{#!c++
 #include <vector>
 #include <boost/circular_buffer.hpp>
 /*
 $ g++ --version | head -n1
 g++ (GCC) 8.1.1 20180531
 $ g++ example.cpp -o example && valgrind --tool=memcheck ./example 2>&1 |
 grep Invalid
 ==19349== Invalid write of size 8
 ==19349== Invalid write of size 2
 ==19349== Invalid free() / delete / delete[] / realloc()
 */
 int main()
 {
     std::vector<int> x(7), y(8); // has non-trivial move/copy
     boost::circular_buffer< std::vector<int> > buffer(3);
     buffer.push_back(x); // [x| | ]
     buffer.push_back(x); // [x|x| ]
     buffer.pop_front(); // [ |x| ]
     buffer.insert(buffer.begin(), 2, y);
     // is_uninitialized(i) -> [0,0,1] (should be [1,0,1])
     // [copy 1 -> 0] : [x|x| ] bad copy to uninitialized element
     // [copy y -> 1] : [x|y| ] ok
     // [construct y -> 2] : [x|y|y] ok
     return 0; // tries to destruct uninitialized entry
 }
 }}}

-- 
Ticket URL: <https://svn.boost.org/trac10/ticket/13635>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2018-07-17 08:48:08 UTC