From 5d288580ee1c9a30ea2a56995438196ddd92a332 Mon Sep 17 00:00:00 2001 From: Antony Polukhin Date: Wed, 21 Dec 2011 17:03:52 +0000 Subject: [PATCH] Fixes #6298 Fixes #6264 [SVN r76096] --- include/boost/lexical_cast.hpp | 7 ++- test/lexical_cast_empty_input_test.cpp | 81 ++++++++++++++++++++++---- 2 files changed, 76 insertions(+), 12 deletions(-) diff --git a/include/boost/lexical_cast.hpp b/include/boost/lexical_cast.hpp index 5fa6a96..11ee183 100644 --- a/include/boost/lexical_cast.hpp +++ b/include/boost/lexical_cast.hpp @@ -586,7 +586,7 @@ namespace boost --end; value = 0; - if ( *end < czero || *end >= czero + 10 || begin > end) + if (begin > end || *end < czero || *end >= czero + 10) return false; value = *end - czero; --end; @@ -684,6 +684,7 @@ namespace boost , const CharT opening_brace, const CharT closing_brace) { using namespace std; + if (begin == end) return false; const CharT minus = lcast_char_constants::minus; const CharT plus = lcast_char_constants::plus; const int inifinity_size = 8; @@ -1183,7 +1184,7 @@ namespace boost bool const result = !(stream << input).fail(); start = stringbuffer.pbase(); finish = stringbuffer.pptr(); - return result && (start != finish); + return result; } template @@ -1358,6 +1359,7 @@ namespace boost template bool shr_unsigned(Type& output) { + if (start == finish) return false; CharT const minus = lcast_char_constants::minus; CharT const plus = lcast_char_constants::plus; bool has_minus = false; @@ -1392,6 +1394,7 @@ namespace boost template bool shr_signed(Type& output) { + if (start == finish) return false; CharT const minus = lcast_char_constants::minus; CharT const plus = lcast_char_constants::plus; typedef BOOST_DEDUCED_TYPENAME make_unsigned::type utype; diff --git a/test/lexical_cast_empty_input_test.cpp b/test/lexical_cast_empty_input_test.cpp index 42e7cec..0c67542 100755 --- a/test/lexical_cast_empty_input_test.cpp +++ b/test/lexical_cast_empty_input_test.cpp @@ -24,27 +24,86 @@ using namespace boost; void test_empty_iterator_range() { - boost::iterator_range v; + boost::iterator_range v; BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); - BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_EQUAL(lexical_cast(v), std::string()); BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); } void test_empty_string() { - BOOST_CHECK_THROW(lexical_cast(std::string()), bad_lexical_cast); - BOOST_CHECK_THROW(lexical_cast(std::string()), bad_lexical_cast); - BOOST_CHECK_THROW(lexical_cast(std::string()), bad_lexical_cast); - BOOST_CHECK_THROW(lexical_cast(std::string()), bad_lexical_cast); - BOOST_CHECK_THROW(lexical_cast(std::string()), bad_lexical_cast); - BOOST_CHECK_EQUAL(lexical_cast(std::string()), std::string()); - BOOST_CHECK_THROW(lexical_cast(std::string()), bad_lexical_cast); - BOOST_CHECK_THROW(lexical_cast(std::string()), bad_lexical_cast); + std::string v; + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_EQUAL(lexical_cast(v), std::string()); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); +} + +struct Escape +{ + Escape(const std::string& s) + : str_(s) + {} + + std::string str_; +}; + +inline std::ostream& operator<< (std::ostream& o, const Escape& rhs) +{ + return o << rhs.str_; +} + +void test_empty_user_class() +{ + Escape v(""); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_EQUAL(lexical_cast(v), std::string()); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); +} + +namespace std { +inline std::ostream & operator<<(std::ostream & out, const std::vector & v) +{ + std::ostream_iterator it(out); + std::copy(v.begin(), v.end(), it); + assert(out); + return out; +} +} + +void test_empty_vector() +{ + std::vector v; + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_EQUAL(lexical_cast(v), std::string()); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); + BOOST_CHECK_THROW(lexical_cast(v), bad_lexical_cast); } unit_test::test_suite *init_unit_test_suite(int, char *[]) @@ -53,6 +112,8 @@ unit_test::test_suite *init_unit_test_suite(int, char *[]) BOOST_TEST_SUITE("lexical_cast. Empty input unit test"); suite->add(BOOST_TEST_CASE(&test_empty_iterator_range)); suite->add(BOOST_TEST_CASE(&test_empty_string)); + suite->add(BOOST_TEST_CASE(&test_empty_user_class)); + suite->add(BOOST_TEST_CASE(&test_empty_vector)); return suite; }