forked from boostorg/conversion
@@ -18,7 +18,7 @@
|
|||||||
// with additional fixes and suggestions from Gennaro Prota,
|
// with additional fixes and suggestions from Gennaro Prota,
|
||||||
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
|
// Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
|
||||||
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
|
// Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
|
||||||
// Cheng Yang, Matthew Bradbury and other Boosters
|
// Cheng Yang, Matthew Bradbury, David W. Birdsall and other Boosters
|
||||||
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2012
|
// when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2012
|
||||||
|
|
||||||
#include <climits>
|
#include <climits>
|
||||||
@@ -591,6 +591,7 @@ namespace boost
|
|||||||
value = *end - czero;
|
value = *end - czero;
|
||||||
--end;
|
--end;
|
||||||
T multiplier = 1;
|
T multiplier = 1;
|
||||||
|
bool multiplier_overflowed = false;
|
||||||
|
|
||||||
#ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
|
#ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
|
||||||
std::locale loc;
|
std::locale loc;
|
||||||
@@ -613,12 +614,17 @@ namespace boost
|
|||||||
for(;end>=begin; --end)
|
for(;end>=begin; --end)
|
||||||
{
|
{
|
||||||
if (remained) {
|
if (remained) {
|
||||||
T const new_sub_value = multiplier * 10 * (*end - czero);
|
T const multiplier_10 = multiplier * 10;
|
||||||
|
if (multiplier_10 / 10 != multiplier) multiplier_overflowed = true;
|
||||||
|
|
||||||
|
T const dig_value = *end - czero;
|
||||||
|
T const new_sub_value = multiplier_10 * dig_value;
|
||||||
|
|
||||||
if (*end < czero || *end >= czero + 10
|
if (*end < czero || *end >= czero + 10
|
||||||
/* detecting overflow */
|
/* detecting overflow */
|
||||||
|| new_sub_value/10 != multiplier * (*end - czero)
|
|| (dig_value && new_sub_value / dig_value != multiplier_10)
|
||||||
|| static_cast<T>((std::numeric_limits<T>::max)()-new_sub_value) < value
|
|| static_cast<T>((std::numeric_limits<T>::max)()-new_sub_value) < value
|
||||||
|
|| (multiplier_overflowed && dig_value)
|
||||||
)
|
)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -656,12 +662,17 @@ namespace boost
|
|||||||
{
|
{
|
||||||
while ( begin <= end )
|
while ( begin <= end )
|
||||||
{
|
{
|
||||||
T const new_sub_value = multiplier * 10 * (*end - czero);
|
T const multiplier_10 = multiplier * 10;
|
||||||
|
if (multiplier_10 / 10 != multiplier) multiplier_overflowed = true;
|
||||||
|
|
||||||
|
T const dig_value = *end - czero;
|
||||||
|
T const new_sub_value = multiplier_10 * dig_value;
|
||||||
|
|
||||||
if (*end < czero || *end >= czero + 10
|
if (*end < czero || *end >= czero + 10
|
||||||
/* detecting overflow */
|
/* detecting overflow */
|
||||||
|| new_sub_value/10 != multiplier * (*end - czero)
|
|| (dig_value && new_sub_value / dig_value != multiplier_10)
|
||||||
|| static_cast<T>((std::numeric_limits<T>::max)()-new_sub_value) < value
|
|| static_cast<T>((std::numeric_limits<T>::max)()-new_sub_value) < value
|
||||||
|
|| (multiplier_overflowed && dig_value)
|
||||||
)
|
)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@@ -796,6 +796,17 @@ void test_conversion_from_to_integral()
|
|||||||
BOOST_CHECK_THROW(lexical_cast<T>("+-9"), bad_lexical_cast);
|
BOOST_CHECK_THROW(lexical_cast<T>("+-9"), bad_lexical_cast);
|
||||||
// test_conversion_from_to_integral_for_locale
|
// test_conversion_from_to_integral_for_locale
|
||||||
|
|
||||||
|
// Overflow test case from David W. Birdsall
|
||||||
|
std::string must_owerflow_str = "160000000000000000000";
|
||||||
|
std::string must_owerflow_negative_str = "-160000000000000000000";
|
||||||
|
for (int i = 0; i < 15; ++i) {
|
||||||
|
BOOST_CHECK_THROW(lexical_cast<T>(must_owerflow_str), bad_lexical_cast);
|
||||||
|
BOOST_CHECK_THROW(lexical_cast<T>(must_owerflow_negative_str), bad_lexical_cast);
|
||||||
|
|
||||||
|
must_owerflow_str += '0';
|
||||||
|
must_owerflow_negative_str += '0';
|
||||||
|
}
|
||||||
|
|
||||||
typedef std::numpunct<char> numpunct;
|
typedef std::numpunct<char> numpunct;
|
||||||
|
|
||||||
restore_oldloc guard;
|
restore_oldloc guard;
|
||||||
|
Reference in New Issue
Block a user