Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2996)

Unified Diff: base/time/time_posix.cc

Issue 2405453002: Fix Integer-overflow in base::Time::FromExploded. (Closed)
Patch Set: move method under ifdef Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/time/time_posix.cc
diff --git a/base/time/time_posix.cc b/base/time/time_posix.cc
index ac0e99f7eb61b30de3eb16556f77869a8ee4704b..07f95a369461ead840fc003d7d0a88e06208503c 100644
--- a/base/time/time_posix.cc
+++ b/base/time/time_posix.cc
@@ -113,6 +113,18 @@ int64_t ClockNow(clockid_t clk_id) {
#else // _POSIX_MONOTONIC_CLOCK
#error No usable tick clock function on this platform.
#endif // _POSIX_MONOTONIC_CLOCK
+
+// Safely multiplies |init_value| by |multiply_value| and adds |add_value|
+// to that. Returns result or 0 value avoiding overflows.
+int64_t MultiplyAndAdd(int64_t init_value,
miu 2016/10/18 19:55:13 This helper hides whether overflow occurs (i.e., i
maksims (do not use this acc) 2016/10/19 16:41:04 Removed
+ int64_t multiply_value,
+ int64_t add_value) {
+ base::CheckedNumeric<int64_t> result(init_value);
+ result *= multiply_value;
+ result += add_value;
+ return result.ValueOrDefault(0);
+}
+
#endif // !defined(OS_MACOSX)
} // namespace
@@ -242,7 +254,7 @@ bool Time::FromExploded(bool is_local, const Exploded& exploded, Time* time) {
timestruct.tm_zone = NULL; // not a POSIX field, so mktime/timegm ignore
#endif
- int64_t milliseconds;
+ int64_t milliseconds = 0;
miu 2016/10/18 19:55:13 nit: Please move the declaration of |milliseconds|
maksims (do not use this acc) 2016/10/19 16:41:04 Done.
SysTime seconds;
// Certain exploded dates do not really exist due to daylight saving times,
@@ -312,13 +324,15 @@ bool Time::FromExploded(bool is_local, const Exploded& exploded, Time* time) {
milliseconds += (kMillisecondsPerSecond - 1);
}
} else {
- milliseconds = seconds * kMillisecondsPerSecond + exploded.millisecond;
+ milliseconds =
miu 2016/10/18 19:55:13 Suggestion (to return false if overflow occurs):
maksims (do not use this acc) 2016/10/19 16:41:04 Done.
+ MultiplyAndAdd(seconds, kMillisecondsPerSecond, exploded.millisecond);
}
// Adjust from Unix (1970) to Windows (1601) epoch.
- base::Time converted_time =
- Time((milliseconds * kMicrosecondsPerMillisecond) +
- kWindowsEpochDeltaMicroseconds);
+ int64_t microseconds_win_epoch =
miu 2016/10/18 19:55:13 Similar suggestion here: Declare |microseconds_win
maksims (do not use this acc) 2016/10/19 16:41:04 Done.
+ MultiplyAndAdd(milliseconds, kMicrosecondsPerMillisecond,
+ kWindowsEpochDeltaMicroseconds);
+ base::Time converted_time(microseconds_win_epoch);
// If |exploded.day_of_month| is set to 31 on a 28-30 day month, it will
// return the first day of the next month. Thus round-trip the time and

Powered by Google App Engine
This is Rietveld 408576698