Opened 13 years ago

Closed 10 years ago

#3471 closed Patches (fixed)

microseconds constructor overflows

Reported by: Andrey Semashev Owned by: Andrey Semashev
Milestone: Boost 1.43.0 Component: date_time
Version: Boost 1.40.0 Severity: Problem
Keywords: microseconds Cc:

Description

From the users ML: http://lists.boost.org/boost-users/2008/10/41763.php

The boost::date_time::microseconds(...) constructor overflows the int64 size limits in intermediary calculations. The code below will reproduce the error (using VC++ 2008 and boost 1.36).

ptime start(boost::gregorian::date(2000, 1, 1));
ptime end(boost::gregorian::date(2000, 5, 1));
time_duration td = end - start;

ptime wrongEnd = start + microseconds(td.total_microseconds());
BOOST_CHECK_EQUAL(end, wrongEnd);

The microseconds constructor takes an int64 as input and the total_microseconds is well within its range. Inside the date_time::subsecond_duration<time_duration, 1000000> the internal duration is calculated as

ss*traits_type::res_adjust()/frac_of_second

Since the both res_adjust() and frac_of_second have the value 1000000, the result should be ss*1 but... the intermediary value ss*res_adjust overflows the int64 causing a negative number to be returned.

Question is, is this by design or is it a bug? I'm rather new to boost::date_time and was hoping to replace our current datetime types with it. We are using millisecond timestamped data over long time series (years).

I guess the simple solution would be to add parentheses around (res_adjust()/frac_of_second) assuming frac_of_second always divides res_adjust. However, there are similar issues when adding 200 years worth of seconds which overflows the int32 argument (but that's not of my immediate concern).

Attachments (1)

subsecond_duration-overflow-fix.diff (4.1 KB ) - added by anonymous 12 years ago.

Download all attachments as: .zip

Change History (12)

comment:1 by anonymous, 13 years ago

In my opinion, this is definitely a bug. I'd take it one step further: the presence of this simple integer-overflow bug suggests that there may be integer arithmetic bugs throughout the date_time library. An expert in integer arithmetic should review the entire date_time library looking for similar bugs.

Note that the suggested solution of adding parentheses won't work in many common cases, such as when this function is called from the nanoseconds constructor.

comment:2 by anonymous, 12 years ago

Owner: changed from az_sw_dude to anonymous
Status: newassigned

comment:3 by anonymous, 12 years ago

Milestone: Boost 1.41.0Boost 1.43.0

comment:4 by anonymous, 12 years ago

Owner: changed from anonymous to az_sw_dude
Status: assignednew

comment:5 by anonymous, 12 years ago

Owner: changed from az_sw_dude to Andrey Semashev

by anonymous, 12 years ago

comment:6 by johanditmar@…, 12 years ago

Any estimate when this will make it into a release? Milestone is still set for 1.43.

comment:7 by anonymous, 12 years ago

Or something like "(ss / frac_of_second) * traits_type::res_adjust() + (ss % frac_of_second) * traits_type::res_adjust() / frac_of_second" ?

comment:8 by Vicente Botet <vicente.botet@…>, 12 years ago

Type: BugsPatches

comment:9 by Jon Bartosch <jon@…>, 10 years ago

So, this is a real problem. Will this ever make it into a release? It's as simple as a set of parenthesis. If not, can we have some rational in the bug?

comment:10 by Andrey Semashev, 10 years ago

(In [80887]) Refs #3471. Precompute the duration conversion coefficient to avoid integer overflow. Added a test for integer overflow in the subsecond duration constructor.

comment:11 by Andrey Semashev, 10 years ago

Resolution: fixed
Status: newclosed

(In [80940]) Merged changes from trunk. Fixes #3471.

Note: See TracTickets for help on using tickets.