Index: third_party/crashpad/crashpad/tools/crashpad_database_util.cc |
diff --git a/third_party/crashpad/crashpad/tools/crashpad_database_util.cc b/third_party/crashpad/crashpad/tools/crashpad_database_util.cc |
index acbadd02167d65f695f4da798dc301bce320422e..e7d89bc438ceb9aef32bbcccbcb3917f699605b6 100644 |
--- a/third_party/crashpad/crashpad/tools/crashpad_database_util.cc |
+++ b/third_party/crashpad/crashpad/tools/crashpad_database_util.cc |
@@ -38,6 +38,7 @@ |
#include "util/file/file_io.h" |
#include "util/file/file_reader.h" |
#include "util/misc/uuid.h" |
+#include "util/stdlib/string_number_conversion.h" |
namespace crashpad { |
namespace { |
@@ -130,16 +131,23 @@ std::string BoolToString(bool boolean) { |
return std::string(boolean ? "true" : "false"); |
} |
-// Converts |string| to |time|, returning true if a conversion could be |
+// Converts |string| to |out_time|, returning true if a conversion could be |
// performed, and false without setting |boolean| if no conversion could be |
// performed. Various time formats are recognized, including several string |
-// representations and a numeric time_t representation. The special string |
-// "never" is recognized as |string| and converts to a |time| value of 0. |utc|, |
-// when true, causes |string| to be interpreted as a UTC time rather than a |
-// local time when the time zone is ambiguous. |
-bool StringToTime(const char* string, time_t* time, bool utc) { |
+// representations and a numeric time_t representation. The special |string| |
+// "never" is recognized as converted to a |out_time| value of 0; "now" is |
+// converted to the current time. |utc|, when true, causes |string| to be |
+// interpreted as a UTC time rather than a local time when the time zone is |
+// ambiguous. |
+bool StringToTime(const char* string, time_t* out_time, bool utc) { |
if (strcasecmp(string, "never") == 0) { |
- *time = 0; |
+ *out_time = 0; |
+ return true; |
+ } |
+ |
+ if (strcasecmp(string, "now") == 0) { |
+ errno = 0; |
+ PCHECK(time(out_time) != -1 || errno == 0); |
return true; |
} |
@@ -155,41 +163,53 @@ bool StringToTime(const char* string, time_t* time, bool utc) { |
tm time_tm; |
const char* strptime_result = strptime(string, kFormats[index], &time_tm); |
if (strptime_result == end) { |
+ time_t test_out_time; |
if (utc) { |
- *time = timegm(&time_tm); |
+ test_out_time = timegm(&time_tm); |
} else { |
- *time = mktime(&time_tm); |
+ test_out_time = mktime(&time_tm); |
} |
- return true; |
+ // mktime() is supposed to set errno in the event of an error, but support |
+ // for this is spotty, so there’s no way to distinguish between a true |
+ // time_t of -1 (1969-12-31 23:59:59 UTC) and an error. Assume error. |
+ // |
+ // See 10.11.5 Libc-1082.50.1/stdtime/FreeBSD/localtime.c and |
+ // glibc-2.24/time/mktime.c, which don’t set errno or save and restore |
+ // errno. Post-Android 7.1.0 Bionic is even more hopeless, setting errno |
+ // whenever the time conversion returns -1, even for valid input. See |
+ // libc/tzcode/localtime.c mktime(). Windows seems to get it right: see |
+ // 10.0.14393 SDK Source/ucrt/time/mktime.cpp. |
+ if (test_out_time != -1) { |
+ *out_time = test_out_time; |
+ return true; |
+ } |
} |
} |
- char* end_result; |
- errno = 0; |
- long long strtoll_result = strtoll(string, &end_result, 0); |
- if (end_result == end && errno == 0 && |
- base::IsValueInRangeForNumericType<time_t>(strtoll_result)) { |
- *time = strtoll_result; |
+ int64_t int64_result; |
+ if (StringToNumber(string, &int64_result) && |
+ base::IsValueInRangeForNumericType<time_t>(int64_result)) { |
+ *out_time = int64_result; |
return true; |
} |
return false; |
} |
-// Converts |time_tt| to a string, and returns it. |utc| determines whether the |
-// converted time will reference local time or UTC. If |time_tt| is 0, the |
+// Converts |out_time| to a string, and returns it. |utc| determines whether the |
+// converted time will reference local time or UTC. If |out_time| is 0, the |
// string "never" will be returned as a special case. |
-std::string TimeToString(time_t time_tt, bool utc) { |
- if (time_tt == 0) { |
+std::string TimeToString(time_t out_time, bool utc) { |
+ if (out_time == 0) { |
return std::string("never"); |
} |
tm time_tm; |
if (utc) { |
- gmtime_r(&time_tt, &time_tm); |
+ PCHECK(gmtime_r(&out_time, &time_tm)); |
} else { |
- localtime_r(&time_tt, &time_tm); |
+ PCHECK(localtime_r(&out_time, &time_tm)); |
} |
char string[64]; |