Merge "Fix tzdata loading."
diff --git a/libc/tzcode/localtime.c b/libc/tzcode/localtime.c
index adc2f1b..6e88819 100644
--- a/libc/tzcode/localtime.c
+++ b/libc/tzcode/localtime.c
@@ -369,7 +369,7 @@
   } u;
 };
 
-static int __bionic_open_tzdata(const char*);
+static int __bionic_open_tzdata(const char*, int32_t*);
 
 /* Load tz data from the file named NAME into *SP.  Read extended
    format if DOEXTEND.  Use *LSP for temporary storage.  Return 0 on
@@ -398,7 +398,8 @@
 	}
 
 #if defined(__BIONIC__)
-	fid = __bionic_open_tzdata(name);
+	int32_t entry_length;
+	fid = __bionic_open_tzdata(name, &entry_length);
 #else
 	if (name[0] == ':')
 		++name;
@@ -424,7 +425,11 @@
 	if (fid < 0)
 	  return errno;
 
+#if defined(__BIONIC__)
+	nread = read(fid, up->buf, entry_length);
+#else
 	nread = read(fid, up->buf, sizeof up->buf);
+#endif
 	if (nread < tzheadsize) {
 	  int err = nread < 0 ? errno : EINVAL;
 	  close(fid);
@@ -2342,7 +2347,8 @@
 #include <arpa/inet.h> // For ntohl(3).
 
 static int __bionic_open_tzdata_path(const char* path_prefix_variable, const char* path_suffix,
-                                     const char* olson_id) {
+                                     const char* olson_id,
+                                     int32_t* entry_length) {
   const char* path_prefix = getenv(path_prefix_variable);
   if (path_prefix == NULL) {
     fprintf(stderr, "%s: %s not set!\n", __FUNCTION__, path_prefix_variable);
@@ -2440,6 +2446,7 @@
 
     if (strcmp(this_id, olson_id) == 0) {
       specific_zone_offset = ntohl(entry->start) + ntohl(header.data_offset);
+      *entry_length = ntohl(entry->length);
       break;
     }
 
@@ -2467,10 +2474,12 @@
   return fd;
 }
 
-static int __bionic_open_tzdata(const char* olson_id) {
-  int fd = __bionic_open_tzdata_path("ANDROID_DATA", "/misc/zoneinfo/current/tzdata", olson_id);
+static int __bionic_open_tzdata(const char* olson_id, int32_t* entry_length) {
+  int fd = __bionic_open_tzdata_path("ANDROID_DATA", "/misc/zoneinfo/current/tzdata",
+                                     olson_id, entry_length);
   if (fd < 0) {
-    fd = __bionic_open_tzdata_path("ANDROID_ROOT", "/usr/share/zoneinfo/tzdata", olson_id);
+    fd = __bionic_open_tzdata_path("ANDROID_ROOT", "/usr/share/zoneinfo/tzdata",
+                                   olson_id, entry_length);
     if (fd == -2) {
       // The first thing that 'recovery' does is try to format the current time. It doesn't have
       // any tzdata available, so we must not abort here --- doing so breaks the recovery image!