PR #2347: Clamp subsecond of infinite log timestamps in FormatBoundedFields Imported from GitHub PR https://github.com/abseil/abseil-cpp/pull/2347 We could choose to forbid infinite timestamps by contract, but it is also important that logging not crash since it is used for debugging. For LLVM this does not pessimize log statements since value range propagation results in improved code generation from knowledge of the range. Merge a10575089e2147ae4b529eaf22612551cfcbcf99 into 761ddc54db31993f215a49d53326d6a879d4cfb7 Merging this change closes #2347 PiperOrigin-RevId: 1008280506
diff --git a/absl/log/internal/log_format.cc b/absl/log/internal/log_format.cc index ac33021..66b4cdc 100644 --- a/absl/log/internal/log_format.cc +++ b/absl/log/internal/log_format.cc
@@ -17,6 +17,7 @@ #include <string.h> +#include <algorithm> #include <cstddef> #include <cstdint> #include <limits> @@ -125,7 +126,10 @@ p); p += 2; *p++ = '.'; - const int64_t usecs = absl::ToInt64Microseconds(ci.subsecond); + // `ci.subsecond` is +/-InfiniteDuration() for absl::InfiniteFuture() and + // absl::InfinitePast(), so clamp it to the range PutTwoDigits() can encode. + const int64_t usecs = + std::clamp<int64_t>(absl::ToInt64Microseconds(ci.subsecond), 0, 999999); absl::numbers_internal::PutTwoDigits(static_cast<uint32_t>(usecs / 10000), p); p += 2; absl::numbers_internal::PutTwoDigits(static_cast<uint32_t>(usecs / 100 % 100),
diff --git a/absl/log/log_entry_test.cc b/absl/log/log_entry_test.cc index 4b3af4c..4c06d79 100644 --- a/absl/log/log_entry_test.cc +++ b/absl/log/log_entry_test.cc
@@ -465,4 +465,20 @@ EXPECT_THAT(entry.entry().text_message(), Eq("hello world")); } +TEST(LogEntryTest, InfiniteTimestamp) { + const auto format_prefix = [](absl::Time timestamp) { + std::string str(1000, '\0'); + absl::Span<char> buf(&str[0], str.size()); + const size_t prefix_size = absl::log_internal::FormatLogPrefix( + absl::LogSeverity::kInfo, timestamp, 451, "foo.cc", 1234, + absl::log_internal::PrefixFormat::kNotRaw, buf); + str.resize(prefix_size); + return str; + }; + EXPECT_THAT(format_prefix(absl::InfiniteFuture()), + StartsWith("I1231 23:59:59.999999 451 foo.cc:1234] ")); + EXPECT_THAT(format_prefix(absl::InfinitePast()), + StartsWith("I0101 00:00:00.000000 451 foo.cc:1234] ")); +} + } // namespace