Update parallel to 20171222
[termux-packages] / packages / glib / glib-gtimezone.c.patch
CommitLineData
dcaafa88
FF
1diff -u -r ../glib-2.54.2/glib/gtimezone.c ./glib/gtimezone.c
2--- ../glib-2.54.2/glib/gtimezone.c 2017-07-14 01:03:39.000000000 +0200
4601842b
FF
3+++ ./glib/gtimezone.c 2017-12-21 23:47:57.704190589 +0100
4@@ -43,6 +43,10 @@
8aef3a59
FF
5 #include <windows.h>
6 #endif
7
8+#ifdef __ANDROID__
8aef3a59
FF
9+#include <sys/system_properties.h>
10+#endif
11+
12 /**
13 * SECTION:timezone
14 * @title: GTimeZone
4601842b 15@@ -392,7 +396,109 @@
dcaafa88
FF
16 gtz->transitions = NULL;
17 }
18
19-#ifdef G_OS_UNIX
8aef3a59 20+#ifdef __ANDROID__
ada1b36f 21+/* Android uses a 'persist.sys.timezone' system property for the
6acf9d4a
FF
22+ * current timezone instead of a /etc/localtime file:
23+ * https://android.googlesource.com/platform/ndk/+/android-2.2_r1/docs/system/libc/OVERVIEW.TXT#67
24+ *
25+ * There are no files under /usr/share/zoneinfo - instead a single
26+ * /system/usr/share/zoneinfo/tzdata file is used which contains all
27+ * files compiled together with the following tool:
28+ * https://android.googlesource.com/platform/system/timezone/+/master/zone_compactor/main/java/ZoneCompactor.java
29+ */
30+static GBytes *
dcaafa88
FF
31+zone_info_android (const gchar *identifier)
32+{
69fd9a5c 33+ char sys_timezone[PROP_VALUE_MAX];
4601842b
FF
34+ GMappedFile *file;
35+ gchar *tzdata;
36+ gsize tzdata_length;
37+ const gsize index_entry_size = 52;
38+ gint32 header_index_offset, header_data_offset;
39+ gint32 entry_count, current_index;
40+ char* entry_name;
41+ gint32 entry_offset, entry_length;
42+ GBytes *zoneinfo;
dcaafa88
FF
43+
44+ if (identifier == NULL)
45+ {
022cbc0f 46+ if (__system_property_get ("persist.sys.timezone", sys_timezone) < 1)
6acf9d4a
FF
47+ {
48+ g_warning ("__system_property_get(\"persist.sys.timezone\") failed");
49+ return NULL;
50+ }
dcaafa88 51+ identifier = sys_timezone;
8aef3a59 52+ }
dcaafa88 53+
4601842b
FF
54+ file = g_mapped_file_new ("/system/usr/share/zoneinfo/tzdata", FALSE, NULL);
55+ if (file == NULL)
56+ {
57+ g_warning ("Failed mapping tzdata file");
58+ return NULL;
59+ }
8aef3a59 60+
4601842b
FF
61+ tzdata = g_mapped_file_get_contents (file);
62+ tzdata_length = g_mapped_file_get_length (file);
63+ if (tzdata == NULL || tzdata_length < 24)
dcaafa88 64+ {
4601842b 65+ g_warning ("Too small tzdata file");
dcaafa88
FF
66+ goto error;
67+ }
68+
4601842b
FF
69+ header_index_offset = gint32_from_be (*((gint32_be*) (tzdata + 12)));
70+ header_data_offset = gint32_from_be (*((gint32_be*) (tzdata + 16)));
dcaafa88 71+
4601842b
FF
72+ entry_count = (header_data_offset - header_index_offset) / index_entry_size;
73+ if (entry_count < 1)
dcaafa88 74+ {
4601842b
FF
75+ g_warning("No index entry found");
76+ goto error;
77+ }
dcaafa88 78+
4601842b
FF
79+ current_index = 0;
80+ while (current_index < entry_count)
81+ {
82+ entry_name = tzdata + header_index_offset + current_index * index_entry_size;
83+ /* The name should be null terminated within the 40 chars. */
84+ if (memchr (entry_name, 0, 40) == NULL)
dcaafa88 85+ {
4601842b
FF
86+ g_warning("Invalid index entry");
87+ goto error;
88+ }
dcaafa88 89+
4601842b
FF
90+ if (strcmp (entry_name, identifier) == 0)
91+ {
92+ entry_offset = gint32_from_be (*(gint32_be*) (entry_name + 40));
93+ entry_length = gint32_from_be (*(gint32_be*) (entry_name + 44));
94+ if (entry_length == 0)
dcaafa88 95+ {
4601842b 96+ g_warning ("Invalid tzdata entry with length zero");
dcaafa88
FF
97+ goto error;
98+ }
4601842b 99+ else if (entry_length > 65536 || header_data_offset + entry_offset + entry_length > tzdata_length)
ada1b36f 100+ {
4601842b 101+ /* Use a reasonable but arbitrary max length of an entry. */
ada1b36f
FF
102+ g_warning ("Too large tzdata entry length");
103+ goto error;
104+ }
105+
4601842b
FF
106+ zoneinfo = g_bytes_new_with_free_func (tzdata + header_data_offset + entry_offset,
107+ entry_length,
108+ (GDestroyNotify)g_mapped_file_unref,
109+ g_mapped_file_ref (file));
110+ g_mapped_file_unref (file);
111+ return zoneinfo;
8aef3a59 112+ }
4601842b 113+ current_index++;
8aef3a59 114+ }
dcaafa88 115+
8aef3a59 116+error:
4601842b 117+ g_mapped_file_unref (file);
8aef3a59 118+ return NULL;
dcaafa88
FF
119+}
120+
121+#elif defined(G_OS_UNIX)
122+
123 static GBytes*
124 zone_info_unix (const gchar *identifier)
125 {
4601842b 126@@ -436,6 +542,10 @@
8aef3a59 127 return zoneinfo;
8aef3a59
FF
128 }
129
dcaafa88
FF
130+#endif
131+
132+#ifdef G_OS_UNIX
133+
8aef3a59 134 static void
dcaafa88
FF
135 init_zone_from_iana_info (GTimeZone *gtz, GBytes *zoneinfo)
136 {
4601842b 137@@ -1387,7 +1497,11 @@
dcaafa88
FF
138 if (tz->t_info == NULL)
139 {
140 #ifdef G_OS_UNIX
141+# ifdef __ANDROID__
142+ GBytes *zoneinfo = zone_info_android (identifier);
143+# else
144 GBytes *zoneinfo = zone_info_unix (identifier);
145+# endif
146 if (!zoneinfo)
147 zone_for_constant_offset (tz, "UTC");
148 else