# HG changeset patch # User Chris Cannam # Date 1512984520 0 # Node ID 622d193a00dc1dd5caf50bb242d840508ac1892c # Parent 9ae40c7aecdfd605099504ed5a9fc0179e96cfc1 Rework canonicalisation so as to avoid theoretical possibility of integer overflow diff -r 9ae40c7aecdf -r 622d193a00dc base/RealTimeSV.cpp --- a/base/RealTimeSV.cpp Thu Dec 07 13:33:30 2017 +0000 +++ b/base/RealTimeSV.cpp Mon Dec 11 09:28:40 2017 +0000 @@ -19,6 +19,7 @@ */ #include +#include #include #include @@ -43,16 +44,10 @@ RealTime::RealTime(int s, int n) : sec(s), nsec(n) { - if (sec == 0) { - while (nsec <= -ONE_BILLION) { nsec += ONE_BILLION; --sec; } - while (nsec >= ONE_BILLION) { nsec -= ONE_BILLION; ++sec; } - } else if (sec < 0) { - while (nsec <= -ONE_BILLION) { nsec += ONE_BILLION; --sec; } - while (nsec > 0 && sec < 0) { nsec -= ONE_BILLION; ++sec; } - } else { - while (nsec >= ONE_BILLION) { nsec -= ONE_BILLION; ++sec; } - while (nsec < 0 && sec > 0) { nsec += ONE_BILLION; --sec; } - } + while (nsec <= -ONE_BILLION && sec > INT_MIN) { nsec += ONE_BILLION; --sec; } + while (nsec >= ONE_BILLION && sec < INT_MAX) { nsec -= ONE_BILLION; ++sec; } + while (nsec > 0 && sec < 0) { nsec -= ONE_BILLION; ++sec; } + while (nsec < 0 && sec > 0) { nsec += ONE_BILLION; --sec; } } RealTime diff -r 9ae40c7aecdf -r 622d193a00dc base/test/TestOurRealTime.h --- a/base/test/TestOurRealTime.h Thu Dec 07 13:33:30 2017 +0000 +++ b/base/test/TestOurRealTime.h Mon Dec 11 09:28:40 2017 +0000 @@ -70,6 +70,11 @@ QCOMPARE(RealTime(-2, ONE_BILLION*2), RealTime(0, 0)); QCOMPARE(RealTime(-2, ONE_BILLION/2), RealTime(-1, -ONE_BILLION/2)); + + QCOMPARE(RealTime(1, -ONE_BILLION/2).sec, 0); + QCOMPARE(RealTime(1, -ONE_BILLION/2).nsec, ONE_BILLION/2); + QCOMPARE(RealTime(-1, ONE_BILLION/2).sec, 0); + QCOMPARE(RealTime(-1, ONE_BILLION/2).nsec, -ONE_BILLION/2); QCOMPARE(RealTime(0, 1).sec, 0); QCOMPARE(RealTime(0, 1).nsec, 1);