Use absl::StripLeadingAsciiWhitespace instead of a lambda using std::isspace As written the lambda doesn't correctly handle sign-extension. Closes #2061 PiperOrigin-RevId: 921439321 Change-Id: I952e9f29c957546e91d3c91d9df0bbc45b7a2888
diff --git a/absl/time/format.cc b/absl/time/format.cc index bd06f8f..c59129f 100644 --- a/absl/time/format.cc +++ b/absl/time/format.cc
@@ -17,7 +17,7 @@ #include <cctype> #include <cstdint> #include <utility> - +#include "absl/strings/ascii.h" #include "absl/strings/match.h" #include "absl/strings/string_view.h" #include "absl/time/internal/cctz/include/cctz/time_zone.h" @@ -99,13 +99,6 @@ // the fields with respect to the given TimeZone. bool ParseTime(absl::string_view format, absl::string_view input, absl::TimeZone tz, absl::Time* time, std::string* err) { - auto strip_leading_space = [](absl::string_view* sv) { - while (!sv->empty()) { - if (!std::isspace(sv->front())) return; - sv->remove_prefix(1); - } - }; - // Portable toolchains means we don't get nice constexpr here. struct Literal { const char* name; @@ -116,12 +109,12 @@ {kInfiniteFutureStr, strlen(kInfiniteFutureStr), InfiniteFuture()}, {kInfinitePastStr, strlen(kInfinitePastStr), InfinitePast()}, }; - strip_leading_space(&input); + input = StripLeadingAsciiWhitespace(input); for (const auto& lit : literals) { if (absl::StartsWith(input, absl::string_view(lit.name, lit.size))) { absl::string_view tail = input; tail.remove_prefix(lit.size); - strip_leading_space(&tail); + tail = StripLeadingAsciiWhitespace(tail); if (tail.empty()) { *time = lit.value; return true;
diff --git a/absl/time/format_test.cc b/absl/time/format_test.cc index 0e145a8..38c0e3d 100644 --- a/absl/time/format_test.cc +++ b/absl/time/format_test.cc
@@ -250,6 +250,13 @@ EXPECT_FALSE( absl::ParseTime("%Y", std::string("2026\0payload", 12), &t, &err)); EXPECT_THAT(err, HasSubstr("Illegal trailing data")); + + // High-bit character test for sign-extension bugs. + for (int i = 128; i < 256; ++i) { + char c = static_cast<char>(i); + std::string input = std::string(1, c) + "2015-01-02"; + EXPECT_FALSE(absl::ParseTime("%Y-%m-%d", input, &t, &err)); + } } TEST(ParseTime, ExtendedSeconds) {