$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r76318 - in trunk: boost libs/conversion
From: antoshkka_at_[hidden]
Date: 2012-01-05 07:09:16
Author: apolukhin
Date: 2012-01-05 07:09:15 EST (Thu, 05 Jan 2012)
New Revision: 76318
URL: http://svn.boost.org/trac/boost/changeset/76318
Log:
Fixes #6193
Text files modified: 
   trunk/boost/lexical_cast.hpp                |    21 ++++++++++++++++-----                   
   trunk/libs/conversion/lexical_cast_test.cpp |    11 +++++++++++                             
   2 files changed, 27 insertions(+), 5 deletions(-)
Modified: trunk/boost/lexical_cast.hpp
==============================================================================
--- trunk/boost/lexical_cast.hpp	(original)
+++ trunk/boost/lexical_cast.hpp	2012-01-05 07:09:15 EST (Thu, 05 Jan 2012)
@@ -18,7 +18,7 @@
 //        with additional fixes and suggestions from Gennaro Prota,
 //        Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
 //        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
 
 #include <climits>
@@ -591,6 +591,7 @@
             value = *end - czero;
             --end;
             T multiplier = 1;
+            bool multiplier_overflowed = false;
 
 #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
             std::locale loc;
@@ -613,12 +614,17 @@
                     for(;end>=begin; --end)
                     {
                         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
                                     /* 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
+                                    || (multiplier_overflowed && dig_value)
                                     )
                                 return false;
 
@@ -656,12 +662,17 @@
             {
                 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
                             /* 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
+                            || (multiplier_overflowed && dig_value)
                             )
                         return false;
 
Modified: trunk/libs/conversion/lexical_cast_test.cpp
==============================================================================
--- trunk/libs/conversion/lexical_cast_test.cpp	(original)
+++ trunk/libs/conversion/lexical_cast_test.cpp	2012-01-05 07:09:15 EST (Thu, 05 Jan 2012)
@@ -796,6 +796,17 @@
     BOOST_CHECK_THROW(lexical_cast<T>("+-9"), bad_lexical_cast);
     // 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;
 
     restore_oldloc guard;