Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r80887 - in trunk: boost/date_time boost/date_time/posix_time libs/date_time/test/posix_time
From: andrey.semashev_at_[hidden]
Date: 2012-10-06 13:34:06


Author: andysem
Date: 2012-10-06 13:34:06 EDT (Sat, 06 Oct 2012)
New Revision: 80887
URL: http://svn.boost.org/trac/boost/changeset/80887

Log:
Refs #3471. Precompute the duration conversion coefficient to avoid integer overflow. Added a test for integer overflow in the subsecond duration constructor.
Text files modified:
   trunk/boost/date_time/posix_time/posix_time_config.hpp | 2 +-
   trunk/boost/date_time/time_duration.hpp | 15 +++++++++++++--
   trunk/libs/date_time/test/posix_time/testduration.cpp | 11 ++++++++++-
   3 files changed, 24 insertions(+), 4 deletions(-)

Modified: trunk/boost/date_time/posix_time/posix_time_config.hpp
==============================================================================
--- trunk/boost/date_time/posix_time/posix_time_config.hpp (original)
+++ trunk/boost/date_time/posix_time/posix_time_config.hpp 2012-10-06 13:34:06 EDT (Sat, 06 Oct 2012)
@@ -81,7 +81,7 @@
     {}
     //Give duration access to ticks constructor -- hide from users
     friend class date_time::time_duration<time_duration, time_res_traits>;
- private:
+ protected:
     explicit time_duration(impl_type tick_count) :
       date_time::time_duration<time_duration, time_res_traits>(tick_count)
     {}

Modified: trunk/boost/date_time/time_duration.hpp
==============================================================================
--- trunk/boost/date_time/time_duration.hpp (original)
+++ trunk/boost/date_time/time_duration.hpp 2012-10-06 13:34:06 EDT (Sat, 06 Oct 2012)
@@ -11,6 +11,7 @@
 
 #include <boost/cstdint.hpp>
 #include <boost/operators.hpp>
+#include <boost/static_assert.hpp>
 #include <boost/date_time/time_defs.hpp>
 #include <boost/date_time/special_defs.hpp>
 #include <boost/date_time/compiler_config.hpp>
@@ -265,10 +266,20 @@
   class subsecond_duration : public base_duration
   {
   public:
+ typedef typename base_duration::impl_type impl_type;
     typedef typename base_duration::traits_type traits_type;
+
+ private:
+ // To avoid integer overflow we precompute the duration resolution conversion coefficient (ticket #3471)
+ BOOST_STATIC_ASSERT_MSG((traits_type::ticks_per_second >= frac_of_second ? traits_type::ticks_per_second % frac_of_second : frac_of_second % traits_type::ticks_per_second) == 0,\
+ "The base duration resolution must be a multiple of the subsecond duration resolution");
+ BOOST_STATIC_CONSTANT(boost::int64_t, adjustment_ratio = (traits_type::ticks_per_second >= frac_of_second ? traits_type::ticks_per_second / frac_of_second : frac_of_second / traits_type::ticks_per_second));
+
+ public:
     explicit subsecond_duration(boost::int64_t ss) :
- base_duration(0,0,0,ss*traits_type::res_adjust()/frac_of_second)
- {}
+ base_duration(impl_type(traits_type::ticks_per_second >= frac_of_second ? ss * adjustment_ratio : ss / adjustment_ratio))
+ {
+ }
   };
 
 

Modified: trunk/libs/date_time/test/posix_time/testduration.cpp
==============================================================================
--- trunk/libs/date_time/test/posix_time/testduration.cpp (original)
+++ trunk/libs/date_time/test/posix_time/testduration.cpp 2012-10-06 13:34:06 EDT (Sat, 06 Oct 2012)
@@ -176,7 +176,16 @@
   }
 #endif
 
- time_duration t_11(3600,0,0);
+ // Test for overflows (ticket #3471)
+ {
+ ptime start(boost::gregorian::date(2000, 1, 1));
+ ptime end(boost::gregorian::date(2000, 5, 1));
+ time_duration td = end - start;
+ ptime end2 = start + microseconds(td.total_microseconds());
+ check("microseconds constructor overflow", end == end2);
+ }
+
+ time_duration t_11(3600,0,0);
   check("3600 hours ", t_11.hours() == 3600);
   check("total seconds 3600 hours", t_11.total_seconds() == 12960000);
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk