about summary refs log tree commit diff
path: root/third_party/abseil_cpp/absl/time/internal/cctz/src/time_zone_format.cc
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2020-11-21T13·43+0100
committerVincent Ambo <mail@tazj.in>2020-11-21T14·48+0100
commit082c006c04343a78d87b6c6ab3608c25d6213c3f (patch)
tree16e6f04f8d1d1d2d67e8e917d5e7bb48c1b60375 /third_party/abseil_cpp/absl/time/internal/cctz/src/time_zone_format.cc
parentcc27324d0226953943f408ce3c69ad7d648e005e (diff)
merge(3p/absl): subtree merge of Abseil up to e19260f r/1889
... notably, this includes Abseil's own StatusOr type, which
conflicted with our implementation (that was taken from TensorFlow).

Change-Id: Ie7d6764b64055caaeb8dc7b6b9d066291e6b538f
Diffstat (limited to 'third_party/abseil_cpp/absl/time/internal/cctz/src/time_zone_format.cc')
-rw-r--r--third_party/abseil_cpp/absl/time/internal/cctz/src/time_zone_format.cc22
1 files changed, 18 insertions, 4 deletions
diff --git a/third_party/abseil_cpp/absl/time/internal/cctz/src/time_zone_format.cc b/third_party/abseil_cpp/absl/time/internal/cctz/src/time_zone_format.cc
index 2e02233ce1..d8cb047425 100644
--- a/third_party/abseil_cpp/absl/time/internal/cctz/src/time_zone_format.cc
+++ b/third_party/abseil_cpp/absl/time/internal/cctz/src/time_zone_format.cc
@@ -654,14 +654,23 @@ const char* ParseTM(const char* dp, const char* fmt, std::tm* tm) {
 }
 
 // Sets year, tm_mon and tm_mday given the year, week_num, and tm_wday,
-// and the day on which weeks are defined to start.
-void FromWeek(int week_num, weekday week_start, year_t* year, std::tm* tm) {
+// and the day on which weeks are defined to start.  Returns false if year
+// would need to move outside its bounds.
+bool FromWeek(int week_num, weekday week_start, year_t* year, std::tm* tm) {
   const civil_year y(*year % 400);
   civil_day cd = prev_weekday(y, week_start);  // week 0
   cd = next_weekday(cd - 1, FromTmWday(tm->tm_wday)) + (week_num * 7);
-  *year += cd.year() - y.year();
+  if (const year_t shift = cd.year() - y.year()) {
+    if (shift > 0) {
+      if (*year > std::numeric_limits<year_t>::max() - shift) return false;
+    } else {
+      if (*year < std::numeric_limits<year_t>::min() - shift) return false;
+    }
+    *year += shift;
+  }
   tm->tm_mon = cd.month() - 1;
   tm->tm_mday = cd.day();
+  return true;
 }
 
 }  // namespace
@@ -965,7 +974,12 @@ bool parse(const std::string& format, const std::string& input,
   }
 
   // Compute year, tm.tm_mon and tm.tm_mday if we parsed a week number.
-  if (week_num != -1) FromWeek(week_num, week_start, &year, &tm);
+  if (week_num != -1) {
+    if (!FromWeek(week_num, week_start, &year, &tm)) {
+      if (err != nullptr) *err = "Out-of-range field";
+      return false;
+    }
+  }
 
   const int month = tm.tm_mon + 1;
   civil_second cs(year, month, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);