am 2e7b8d63: am f861bc5c: Merge "Don\'t search off the end of the index for bad Olson ids."

* commit '2e7b8d6399fdea6e43dd07f353346324d2bf4ec4':
  Don't search off the end of the index for bad Olson ids.
diff --git a/libc/tzcode/localtime.c b/libc/tzcode/localtime.c
index 689bbd3..8a54e81 100644
--- a/libc/tzcode/localtime.c
+++ b/libc/tzcode/localtime.c
@@ -2305,7 +2305,13 @@
 
   static const size_t NAME_LENGTH = 40;
   unsigned char buf[NAME_LENGTH + 3 * sizeof(int32_t)];
-  while (TEMP_FAILURE_RETRY(read(fd, buf, sizeof(buf))) == (ssize_t) sizeof(buf)) {
+
+  size_t id_count = (ntohl(header.data_offset) - ntohl(header.index_offset)) / sizeof(buf);
+  for (size_t i = 0; i < id_count; ++i) {
+    if (TEMP_FAILURE_RETRY(read(fd, buf, sizeof(buf))) != (ssize_t) sizeof(buf)) {
+      break;
+    }
+
     char this_id[NAME_LENGTH + 1];
     memcpy(this_id, buf, NAME_LENGTH);
     this_id[NAME_LENGTH] = '\0';
diff --git a/tests/Android.mk b/tests/Android.mk
index 633a6a9..46427ec 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -74,6 +74,7 @@
     string_test.cpp \
     strings_test.cpp \
     stubs_test.cpp \
+    time_test.cpp \
     unistd_test.cpp \
 
 test_dynamic_ldflags = -Wl,--export-dynamic -Wl,-u,DlSymTestFunction
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
new file mode 100644
index 0000000..9a5a706
--- /dev/null
+++ b/tests/time_test.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/cdefs.h>
+#include <features.h>
+#include <gtest/gtest.h>
+
+#include <time.h>
+
+#ifdef __BIONIC__ // mktime_tz is a bionic extension.
+#include <libc/private/bionic_time.h>
+TEST(time, mktime_tz) {
+  struct tm epoch;
+  memset(&epoch, 0, sizeof(tm));
+  epoch.tm_year = 1970 - 1900;
+  epoch.tm_mon = 1;
+  epoch.tm_mday = 1;
+
+  // Alphabetically first. Coincidentally equivalent to UTC.
+  ASSERT_EQ(2678400, mktime_tz(&epoch, "Africa/Abidjan"));
+
+  // Alphabetically last. Coincidentally equivalent to UTC.
+  ASSERT_EQ(2678400, mktime_tz(&epoch, "Zulu"));
+
+  // Somewhere in the middle, not UTC.
+  ASSERT_EQ(2707200, mktime_tz(&epoch, "America/Los_Angeles"));
+
+  // Missing. Falls back to UTC.
+  ASSERT_EQ(2678400, mktime_tz(&epoch, "PST"));
+}
+#endif