diff -Naur -x '*~' -x '*.orig' glib-2.57.2/glib/gtimezone.c glib-2.57.2-guard-against-reading-past-the-end-of-a-timezone-file/glib/gtimezone.c --- glib-2.57.2/glib/gtimezone.c 2018-07-31 20:31:07.000000000 +0200 +++ glib-2.57.2-guard-against-reading-past-the-end-of-a-timezone-file/glib/gtimezone.c 2018-08-08 14:53:36.785909241 +0200 @@ -511,7 +511,7 @@ GBytes *zoneinfo, gchar *identifier /* (transfer full) */) { - gsize size; + gsize size, datasize32, datasize64; guint index; guint32 time_count, type_count; guint8 *tz_transitions, *tz_type_index, *tz_ttinfo; @@ -519,22 +519,32 @@ gsize timesize = sizeof (gint32); const struct tzhead *header = g_bytes_get_data (zoneinfo, &size); - g_return_if_fail (size >= sizeof (struct tzhead) && + datasize32 = guint32_from_be(header->tzh_ttisgmtcnt) + + guint32_from_be(header->tzh_ttisstdcnt) + + sizeof (gint32) * 2 * guint32_from_be(header->tzh_leapcnt) + + (sizeof (gint32) + sizeof (gint8)) * guint32_from_be(header->tzh_timecnt) + + sizeof(struct ttinfo) * guint32_from_be(header->tzh_typecnt) + + guint32_from_be(header->tzh_charcnt); + + datasize64 = guint32_from_be(header->tzh_ttisgmtcnt) + + guint32_from_be(header->tzh_ttisstdcnt) + + sizeof (gint32) * 2 * guint32_from_be(header->tzh_leapcnt) + + (sizeof (gint64) + sizeof (gint8)) * guint32_from_be(header->tzh_timecnt) + + sizeof(struct ttinfo) * guint32_from_be(header->tzh_typecnt) + + guint32_from_be(header->tzh_charcnt); + + g_return_if_fail (size >= (sizeof (struct tzhead) + datasize32) && memcmp (header, "TZif", 4) == 0); - if (header->tzh_version == '2') + if (header->tzh_version == '2' && + size >= (2 * sizeof (struct tzhead) + datasize32 + datasize64)) { /* Skip ahead to the newer 64-bit data if it's available. */ header = (const struct tzhead *) - (((const gchar *) (header + 1)) + - guint32_from_be(header->tzh_ttisgmtcnt) + - guint32_from_be(header->tzh_ttisstdcnt) + - 8 * guint32_from_be(header->tzh_leapcnt) + - 5 * guint32_from_be(header->tzh_timecnt) + - 6 * guint32_from_be(header->tzh_typecnt) + - guint32_from_be(header->tzh_charcnt)); + (((const gchar *) (header + 1)) + datasize32); timesize = sizeof (gint64); } + time_count = guint32_from_be(header->tzh_timecnt); type_count = guint32_from_be(header->tzh_typecnt);