From ed9880c1612840cee487eb0fb38e119e6f95e8ee Mon Sep 17 00:00:00 2001 From: Kohei Takahashi Date: Sun, 30 Nov 2014 03:58:20 +0900 Subject: [PATCH] Fix out of bounds access within {front|back}_extended_deque with empty deque. The insertion point is not correct with empty deque since the range {next_down, next_up} is not half-open range. --- .../boost/fusion/container/deque/deque.hpp | 4 +- .../container/deque/detail/begin_impl.hpp | 11 +----- .../container/deque/detail/cpp03/deque.hpp | 5 +-- .../container/deque/detail/end_impl.hpp | 11 +----- test/sequence/back_extended_deque.cpp | 39 +++++++++++++++++++ test/sequence/front_extended_deque.cpp | 39 +++++++++++++++++++ 6 files changed, 86 insertions(+), 23 deletions(-) diff --git a/include/boost/fusion/container/deque/deque.hpp b/include/boost/fusion/container/deque/deque.hpp index 06fca37b..fdcc73ae 100644 --- a/include/boost/fusion/container/deque/deque.hpp +++ b/include/boost/fusion/container/deque/deque.hpp @@ -50,7 +50,7 @@ namespace boost { namespace fusion typedef bidirectional_traversal_tag category; typedef mpl::int_<0> size; typedef mpl::int_<0> next_up; - typedef mpl::int_<0> next_down; + typedef mpl::int_<-1> next_down; typedef mpl::false_ is_view; template @@ -76,7 +76,7 @@ namespace boost { namespace fusion typedef typename detail::deque_keyed_values::type base; typedef mpl::int_<(sizeof ...(Tail) + 1)> size; typedef mpl::int_ next_up; - typedef mpl::int_<((size::value == 0) ? 0 : -1)> next_down; + typedef mpl::int_<-1> next_down; typedef mpl::false_ is_view; BOOST_FUSION_GPU_ENABLED diff --git a/include/boost/fusion/container/deque/detail/begin_impl.hpp b/include/boost/fusion/container/deque/detail/begin_impl.hpp index 8e7f2633..c4eed54f 100644 --- a/include/boost/fusion/container/deque/detail/begin_impl.hpp +++ b/include/boost/fusion/container/deque/detail/begin_impl.hpp @@ -11,9 +11,6 @@ #include #include -#include -#include - namespace boost { namespace fusion { struct deque_tag; @@ -29,12 +26,8 @@ namespace boost { namespace fusion template struct apply { - typedef typename - mpl::if_c< - (Sequence::next_down::value == Sequence::next_up::value) - , deque_iterator - , deque_iterator - >::type + typedef + deque_iterator type; BOOST_FUSION_GPU_ENABLED diff --git a/include/boost/fusion/container/deque/detail/cpp03/deque.hpp b/include/boost/fusion/container/deque/detail/cpp03/deque.hpp index 967d8f48..1b92ceaf 100644 --- a/include/boost/fusion/container/deque/detail/cpp03/deque.hpp +++ b/include/boost/fusion/container/deque/detail/cpp03/deque.hpp @@ -74,8 +74,7 @@ namespace boost { namespace fusion { typedef typename detail::deque_keyed_values::type base; typedef typename detail::deque_initial_size::type size; typedef mpl::int_ next_up; - typedef mpl::int_< - mpl::if_ >, mpl::int_<0>, mpl::int_<-1> >::type::value> next_down; + typedef mpl::int_<-1> next_down; typedef mpl::false_ is_view; #include @@ -167,7 +166,7 @@ FUSION_HASH endif typedef bidirectional_traversal_tag category; typedef mpl::int_<0> size; typedef mpl::int_<0> next_up; - typedef mpl::int_<0> next_down; + typedef mpl::int_<-1> next_down; typedef mpl::false_ is_view; template diff --git a/include/boost/fusion/container/deque/detail/end_impl.hpp b/include/boost/fusion/container/deque/detail/end_impl.hpp index 73ef85ff..4ea344a9 100644 --- a/include/boost/fusion/container/deque/detail/end_impl.hpp +++ b/include/boost/fusion/container/deque/detail/end_impl.hpp @@ -11,9 +11,6 @@ #include #include -#include -#include - namespace boost { namespace fusion { struct deque_tag; @@ -29,12 +26,8 @@ namespace boost { namespace fusion template struct apply { - typedef typename - mpl::if_c< - (Sequence::next_down::value == Sequence::next_up::value) - , deque_iterator - , deque_iterator - >::type + typedef + deque_iterator type; BOOST_FUSION_GPU_ENABLED diff --git a/test/sequence/back_extended_deque.cpp b/test/sequence/back_extended_deque.cpp index edae9276..368ec0c2 100644 --- a/test/sequence/back_extended_deque.cpp +++ b/test/sequence/back_extended_deque.cpp @@ -23,6 +23,45 @@ int main() { using namespace boost::fusion; + { + typedef deque<> initial_deque_type; + initial_deque_type initial_deque; + typedef back_extended_deque extended_type; + extended_type extended(initial_deque, 101L); + + BOOST_TEST(size(extended) == 1); + BOOST_TEST(extended == make_vector(101L)); + BOOST_TEST(*begin(extended) == 101L); + BOOST_TEST(*prior(end(extended)) == 101L); + BOOST_TEST(distance(begin(extended), end(extended)) == 1); + } + { + namespace mpl = boost::mpl; + typedef deque<> initial_deque_type; + typedef back_extended_deque extended_type; + + BOOST_MPL_ASSERT((boost::is_same::type, long>)); + BOOST_MPL_ASSERT((boost::is_same::type>::type, long>)); + BOOST_MPL_ASSERT((mpl::equal_to::type, mpl::int_<1> >)); + } + { + long l(101L); + typedef deque<> initial_deque_type; + initial_deque_type initial_deque; + typedef back_extended_deque extended_type; + extended_type extended(initial_deque, l); + BOOST_TEST(extended == make_vector(101L)); + + long l2(202L); + extended_type extended2(initial_deque_type(), l2); + + extended = extended2; + + BOOST_TEST(extended == make_vector(202L)); + + BOOST_TEST(l == l2); + } + { typedef deque initial_deque_type; initial_deque_type initial_deque(1, 'a'); diff --git a/test/sequence/front_extended_deque.cpp b/test/sequence/front_extended_deque.cpp index d1c90343..cdbedeb3 100644 --- a/test/sequence/front_extended_deque.cpp +++ b/test/sequence/front_extended_deque.cpp @@ -23,6 +23,45 @@ int main() { using namespace boost::fusion; + { + typedef deque<> initial_deque_type; + initial_deque_type initial_deque; + typedef front_extended_deque extended_type; + extended_type extended(initial_deque, 1); + + BOOST_TEST(size(extended) == 1); + BOOST_TEST(extended == make_vector(1)); + BOOST_TEST(*begin(extended) == 1); + BOOST_TEST(*prior(end(extended)) == 1); + BOOST_TEST(distance(begin(extended), end(extended)) == 1); + } + { + namespace mpl = boost::mpl; + typedef deque<> initial_deque_type; + typedef front_extended_deque extended_type; + + BOOST_MPL_ASSERT((boost::is_same::type, int>)); + BOOST_MPL_ASSERT((boost::is_same::type>::type, int>)); + BOOST_MPL_ASSERT((mpl::equal_to::type, mpl::int_<1> >)); + } + { + int i(1); + typedef deque<> initial_deque_type; + initial_deque_type initial_deque; + typedef front_extended_deque extended_type; + extended_type extended(initial_deque, i); + BOOST_TEST(extended == make_vector(1)); + + int i2(2); + extended_type extended2(initial_deque_type(), i2); + + extended = extended2; + + BOOST_TEST(extended == make_vector(2)); + + BOOST_TEST(i == i2); + } + { typedef deque initial_deque_type; initial_deque_type initial_deque('a', 101L);