summaryrefslogtreecommitdiffstats
path: root/base/time
diff options
context:
space:
mode:
authorrvargas <rvargas@chromium.org>2015-07-20 20:06:24 -0700
committerCommit bot <commit-bot@chromium.org>2015-07-21 03:07:05 +0000
commit15462e858ebf34721e28a023b0b670c2011183ac (patch)
tree8746989e841147a22bc05ce37df4bf7ad3b5311f /base/time
parentbf5d3646b61392bf126904696bc05d863faf4169 (diff)
downloadchromium_src-15462e858ebf34721e28a023b0b670c2011183ac.zip
chromium_src-15462e858ebf34721e28a023b0b670c2011183ac.tar.gz
chromium_src-15462e858ebf34721e28a023b0b670c2011183ac.tar.bz2
Base: Make TimeDelta constructors deal with overflow.
BUG=466445 Review URL: https://codereview.chromium.org/1229853004 Cr-Commit-Position: refs/heads/master@{#339605}
Diffstat (limited to 'base/time')
-rw-r--r--base/time/time.cc14
-rw-r--r--base/time/time.h40
-rw-r--r--base/time/time_unittest.cc130
3 files changed, 100 insertions, 84 deletions
diff --git a/base/time/time.cc b/base/time/time.cc
index 8cbb382..10ffcc6 100644
--- a/base/time/time.cc
+++ b/base/time/time.cc
@@ -144,7 +144,7 @@ Time Time::FromTimeT(time_t tt) {
return Time(); // Preserve 0 so we can tell it doesn't exist.
if (tt == std::numeric_limits<time_t>::max())
return Max();
- return Time((tt * kMicrosecondsPerSecond) + kTimeTToMicrosecondsOffset);
+ return Time(kTimeTToMicrosecondsOffset) + TimeDelta::FromSeconds(tt);
}
time_t Time::ToTimeT() const {
@@ -166,11 +166,7 @@ time_t Time::ToTimeT() const {
Time Time::FromDoubleT(double dt) {
if (dt == 0 || std::isnan(dt))
return Time(); // Preserve 0 so we can tell it doesn't exist.
- if (dt == std::numeric_limits<double>::infinity())
- return Max();
- return Time(static_cast<int64>((dt *
- static_cast<double>(kMicrosecondsPerSecond)) +
- kTimeTToMicrosecondsOffset));
+ return Time(kTimeTToMicrosecondsOffset) + TimeDelta::FromSecondsD(dt);
}
double Time::ToDoubleT() const {
@@ -197,10 +193,8 @@ Time Time::FromTimeSpec(const timespec& ts) {
Time Time::FromJsTime(double ms_since_epoch) {
// The epoch is a valid time, so this constructor doesn't interpret
// 0 as the null time.
- if (ms_since_epoch == std::numeric_limits<double>::infinity())
- return Max();
- return Time(static_cast<int64>(ms_since_epoch * kMicrosecondsPerMillisecond) +
- kTimeTToMicrosecondsOffset);
+ return Time(kTimeTToMicrosecondsOffset) +
+ TimeDelta::FromMillisecondsD(ms_since_epoch);
}
double Time::ToJsTime() const {
diff --git a/base/time/time.h b/base/time/time.h
index a02fbeb..e0a6ea3 100644
--- a/base/time/time.h
+++ b/base/time/time.h
@@ -264,6 +264,9 @@ class BASE_EXPORT TimeDelta {
explicit TimeDelta(int64 delta_us) : delta_(delta_us) {
}
+ // Private method to build a delta from a double.
+ static TimeDelta FromDouble(double value);
+
// Delta in microseconds.
int64 delta_;
};
@@ -597,7 +600,6 @@ class BASE_EXPORT Time : public time_internal::TimeBase<Time> {
// static
inline TimeDelta TimeDelta::FromDays(int days) {
- // Preserve max to prevent overflow.
if (days == std::numeric_limits<int>::max())
return Max();
return TimeDelta(days * Time::kMicrosecondsPerDay);
@@ -605,7 +607,6 @@ inline TimeDelta TimeDelta::FromDays(int days) {
// static
inline TimeDelta TimeDelta::FromHours(int hours) {
- // Preserve max to prevent overflow.
if (hours == std::numeric_limits<int>::max())
return Max();
return TimeDelta(hours * Time::kMicrosecondsPerHour);
@@ -613,7 +614,6 @@ inline TimeDelta TimeDelta::FromHours(int hours) {
// static
inline TimeDelta TimeDelta::FromMinutes(int minutes) {
- // Preserve max to prevent overflow.
if (minutes == std::numeric_limits<int>::max())
return Max();
return TimeDelta(minutes * Time::kMicrosecondsPerMinute);
@@ -621,44 +621,40 @@ inline TimeDelta TimeDelta::FromMinutes(int minutes) {
// static
inline TimeDelta TimeDelta::FromSeconds(int64 secs) {
- // Preserve max to prevent overflow.
- if (secs == std::numeric_limits<int64>::max())
- return Max();
- return TimeDelta(secs * Time::kMicrosecondsPerSecond);
+ return TimeDelta(secs) * Time::kMicrosecondsPerSecond;
}
// static
inline TimeDelta TimeDelta::FromMilliseconds(int64 ms) {
- // Preserve max to prevent overflow.
- if (ms == std::numeric_limits<int64>::max())
- return Max();
- return TimeDelta(ms * Time::kMicrosecondsPerMillisecond);
+ return TimeDelta(ms) * Time::kMicrosecondsPerMillisecond;
}
// static
inline TimeDelta TimeDelta::FromSecondsD(double secs) {
- // Preserve max to prevent overflow.
- if (secs == std::numeric_limits<double>::infinity())
- return Max();
- return TimeDelta(static_cast<int64>(secs * Time::kMicrosecondsPerSecond));
+ return FromDouble(secs * Time::kMicrosecondsPerSecond);
}
// static
inline TimeDelta TimeDelta::FromMillisecondsD(double ms) {
- // Preserve max to prevent overflow.
- if (ms == std::numeric_limits<double>::infinity())
- return Max();
- return TimeDelta(static_cast<int64>(ms * Time::kMicrosecondsPerMillisecond));
+ return FromDouble(ms * Time::kMicrosecondsPerMillisecond);
}
// static
inline TimeDelta TimeDelta::FromMicroseconds(int64 us) {
- // Preserve max to prevent overflow.
- if (us == std::numeric_limits<int64>::max())
- return Max();
return TimeDelta(us);
}
+// static
+inline TimeDelta TimeDelta::FromDouble(double value) {
+ double max_magnitude = std::numeric_limits<int64>::max();
+ TimeDelta delta = TimeDelta(static_cast<int64>(value));
+ if (value > max_magnitude)
+ delta = Max();
+ else if (value < -max_magnitude)
+ delta = -Max();
+ return delta;
+}
+
// For logging use only.
BASE_EXPORT std::ostream& operator<<(std::ostream& os, Time time);
diff --git a/base/time/time_unittest.cc b/base/time/time_unittest.cc
index b7e05b7..512fc37 100644
--- a/base/time/time_unittest.cc
+++ b/base/time/time_unittest.cc
@@ -484,52 +484,6 @@ TEST_F(TimeTest, ExplodeBeforeUnixEpoch) {
EXPECT_EQ(1, exploded.millisecond);
}
-TEST_F(TimeTest, TimeDeltaMax) {
- TimeDelta max = TimeDelta::Max();
- EXPECT_TRUE(max.is_max());
- EXPECT_EQ(max, TimeDelta::Max());
- EXPECT_GT(max, TimeDelta::FromDays(100 * 365));
- EXPECT_GT(max, TimeDelta());
-}
-
-TEST_F(TimeTest, TimeDeltaMaxConversions) {
- TimeDelta t = TimeDelta::Max();
- EXPECT_EQ(std::numeric_limits<int64>::max(), t.ToInternalValue());
-
- EXPECT_EQ(std::numeric_limits<int>::max(), t.InDays());
- EXPECT_EQ(std::numeric_limits<int>::max(), t.InHours());
- EXPECT_EQ(std::numeric_limits<int>::max(), t.InMinutes());
- EXPECT_EQ(std::numeric_limits<double>::infinity(), t.InSecondsF());
- EXPECT_EQ(std::numeric_limits<int64>::max(), t.InSeconds());
- EXPECT_EQ(std::numeric_limits<double>::infinity(), t.InMillisecondsF());
- EXPECT_EQ(std::numeric_limits<int64>::max(), t.InMilliseconds());
- EXPECT_EQ(std::numeric_limits<int64>::max(), t.InMillisecondsRoundedUp());
-
- t = TimeDelta::FromDays(std::numeric_limits<int>::max());
- EXPECT_TRUE(t.is_max());
-
- t = TimeDelta::FromHours(std::numeric_limits<int>::max());
- EXPECT_TRUE(t.is_max());
-
- t = TimeDelta::FromMinutes(std::numeric_limits<int>::max());
- EXPECT_TRUE(t.is_max());
-
- t = TimeDelta::FromSeconds(std::numeric_limits<int64>::max());
- EXPECT_TRUE(t.is_max());
-
- t = TimeDelta::FromMilliseconds(std::numeric_limits<int64>::max());
- EXPECT_TRUE(t.is_max());
-
- t = TimeDelta::FromSecondsD(std::numeric_limits<double>::infinity());
- EXPECT_TRUE(t.is_max());
-
- t = TimeDelta::FromMillisecondsD(std::numeric_limits<double>::infinity());
- EXPECT_TRUE(t.is_max());
-
- t = TimeDelta::FromMicroseconds(std::numeric_limits<int64>::max());
- EXPECT_TRUE(t.is_max());
-}
-
TEST_F(TimeTest, Max) {
Time max = Time::Max();
EXPECT_TRUE(max.is_max());
@@ -795,6 +749,7 @@ TEST(TimeDelta, FromAndIn) {
EXPECT_EQ(13, TimeDelta::FromMillisecondsD(13.3).InMilliseconds());
EXPECT_EQ(13.3, TimeDelta::FromMillisecondsD(13.3).InMillisecondsF());
EXPECT_EQ(13, TimeDelta::FromMicroseconds(13).InMicroseconds());
+ EXPECT_EQ(3.456, TimeDelta::FromMillisecondsD(3.45678).InMillisecondsF());
}
#if defined(OS_POSIX)
@@ -868,6 +823,83 @@ TEST(TimeDelta, Magnitude) {
TimeDelta::FromMicroseconds(min_int64_plus_two).magnitude());
}
+TEST(TimeDelta, Max) {
+ TimeDelta max = TimeDelta::Max();
+ EXPECT_TRUE(max.is_max());
+ EXPECT_EQ(max, TimeDelta::Max());
+ EXPECT_GT(max, TimeDelta::FromDays(100 * 365));
+ EXPECT_GT(max, TimeDelta());
+}
+
+bool IsMin(TimeDelta delta) {
+ return (-delta).is_max();
+}
+
+TEST(TimeDelta, MaxConversions) {
+ TimeDelta t = TimeDelta::Max();
+ EXPECT_EQ(std::numeric_limits<int64>::max(), t.ToInternalValue());
+
+ EXPECT_EQ(std::numeric_limits<int>::max(), t.InDays());
+ EXPECT_EQ(std::numeric_limits<int>::max(), t.InHours());
+ EXPECT_EQ(std::numeric_limits<int>::max(), t.InMinutes());
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), t.InSecondsF());
+ EXPECT_EQ(std::numeric_limits<int64>::max(), t.InSeconds());
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), t.InMillisecondsF());
+ EXPECT_EQ(std::numeric_limits<int64>::max(), t.InMilliseconds());
+ EXPECT_EQ(std::numeric_limits<int64>::max(), t.InMillisecondsRoundedUp());
+
+ t = TimeDelta::FromDays(std::numeric_limits<int>::max());
+ EXPECT_TRUE(t.is_max());
+
+ t = TimeDelta::FromHours(std::numeric_limits<int>::max());
+ EXPECT_TRUE(t.is_max());
+
+ t = TimeDelta::FromMinutes(std::numeric_limits<int>::max());
+ EXPECT_TRUE(t.is_max());
+
+ int64 max_int = std::numeric_limits<int64>::max();
+
+ t = TimeDelta::FromSeconds(max_int / Time::kMicrosecondsPerSecond + 1);
+ EXPECT_TRUE(t.is_max());
+
+ t = TimeDelta::FromMilliseconds(max_int / Time::kMillisecondsPerSecond + 1);
+ EXPECT_TRUE(t.is_max());
+
+ t = TimeDelta::FromMicroseconds(max_int);
+ EXPECT_TRUE(t.is_max());
+
+ t = TimeDelta::FromSeconds(-max_int / Time::kMicrosecondsPerSecond - 1);
+ EXPECT_TRUE(IsMin(t));
+
+ t = TimeDelta::FromMilliseconds(-max_int / Time::kMillisecondsPerSecond - 1);
+ EXPECT_TRUE(IsMin(t));
+
+ t = TimeDelta::FromMicroseconds(-max_int);
+ EXPECT_TRUE(IsMin(t));
+
+ t = -TimeDelta::FromMicroseconds(std::numeric_limits<int64>::min());
+ EXPECT_FALSE(IsMin(t));
+
+ t = TimeDelta::FromSecondsD(std::numeric_limits<double>::infinity());
+ EXPECT_TRUE(t.is_max());
+
+ double max_d = max_int;
+
+ t = TimeDelta::FromSecondsD(max_d / Time::kMicrosecondsPerSecond + 1);
+ EXPECT_TRUE(t.is_max());
+
+ t = TimeDelta::FromMillisecondsD(std::numeric_limits<double>::infinity());
+ EXPECT_TRUE(t.is_max());
+
+ t = TimeDelta::FromMillisecondsD(max_d / Time::kMillisecondsPerSecond * 2);
+ EXPECT_TRUE(t.is_max());
+
+ t = TimeDelta::FromSecondsD(-max_d / Time::kMicrosecondsPerSecond - 1);
+ EXPECT_TRUE(IsMin(t));
+
+ t = TimeDelta::FromMillisecondsD(-max_d / Time::kMillisecondsPerSecond * 2);
+ EXPECT_TRUE(IsMin(t));
+}
TEST(TimeDelta, NumericOperators) {
double d = 0.5;
@@ -894,7 +926,6 @@ TEST(TimeDelta, NumericOperators) {
EXPECT_EQ(TimeDelta::FromMilliseconds(500),
f * TimeDelta::FromMilliseconds(1000));
-
int i = 2;
EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
TimeDelta::FromMilliseconds(1000) * i);
@@ -919,7 +950,6 @@ TEST(TimeDelta, NumericOperators) {
EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
i64 * TimeDelta::FromMilliseconds(1000));
-
EXPECT_EQ(TimeDelta::FromMilliseconds(500),
TimeDelta::FromMilliseconds(1000) * 0.5);
EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
@@ -943,10 +973,6 @@ TEST(TimeDelta, NumericOperators) {
2 * TimeDelta::FromMilliseconds(1000));
}
-bool IsMin(TimeDelta delta) {
- return (-delta).is_max();
-}
-
TEST(TimeDelta, Overflows) {
// Some sanity checks.
EXPECT_TRUE(TimeDelta::Max().is_max());