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