diff options
| author | Ross Burton <ross@burtonini.com> | 2020-10-26 18:01:06 +0000 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2020-10-26 22:08:36 +0000 |
| commit | 5689a70b23df001d5502bf756f115a84b29b0159 (patch) | |
| tree | 2fa50593ff53a97857ce7e569005a2f02cb454c2 | |
| parent | ad818f8b23ad9317a7e7d5daa6958ff9054e93f6 (diff) | |
| download | poky-5689a70b23df001d5502bf756f115a84b29b0159.tar.gz | |
glib-2.0: fix parsing of slim encoded tzdata
As of tzcode 2020b the timezone data is encoded using the 'slim' format
instead of the previous 'fat'. This exposes a number of bugs in GLib,
so backport the fixes to improve the parser.
[ YOCTO #14106 ]
(From OE-Core rev: 09aec7ea87ffc28d1b22d904b20dc23ea55225c9)
Signed-off-by: Ross Burton <ross.burton@arm.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
| -rw-r--r-- | meta/recipes-core/glib-2.0/glib-2.0/tzdata-update.patch | 458 | ||||
| -rw-r--r-- | meta/recipes-core/glib-2.0/glib-2.0_2.64.5.bb | 1 |
2 files changed, 459 insertions, 0 deletions
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/tzdata-update.patch b/meta/recipes-core/glib-2.0/glib-2.0/tzdata-update.patch new file mode 100644 index 0000000000..0af036f8bd --- /dev/null +++ b/meta/recipes-core/glib-2.0/glib-2.0/tzdata-update.patch | |||
| @@ -0,0 +1,458 @@ | |||
| 1 | Backport a number of patches from upstream to fix reading of the new 'slim' | ||
| 2 | encoding for tzdata files. | ||
| 3 | |||
| 4 | Upstream-Status: Backport | ||
| 5 | Signed-off-by: Ross Burton <ross.burton@arm.com> | ||
| 6 | |||
| 7 | commit 18cbd5e5a4812e9bd0b06a058322d2b44ed2ad92 | ||
| 8 | Author: Paul Eggert <eggert@cs.ucla.edu> | ||
| 9 | Date: Thu Jul 16 12:41:49 2020 -0700 | ||
| 10 | |||
| 11 | Clarify memset in set_tz_name | ||
| 12 | |||
| 13 | * glib/gtimezone.c (set_tz_name): Use size, not NAME_SIZE, | ||
| 14 | to clear the buffer. Suggested by Philip Withnall in: | ||
| 15 | https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1533#note_867859 | ||
| 16 | |||
| 17 | commit 1ab3f927d6d09a8cf3349a3545f5351446f43d47 | ||
| 18 | Author: Paul Eggert <eggert@cs.ucla.edu> | ||
| 19 | Date: Thu Jul 16 12:41:49 2020 -0700 | ||
| 20 | |||
| 21 | gtimezone: support footers in TZif files | ||
| 22 | |||
| 23 | Since tzcode95f (1995), TZif files have had a trailing | ||
| 24 | TZ string, used for timestamps after the last transition. | ||
| 25 | This string is specified in Internet RFC 8536 section 3.3. | ||
| 26 | init_zone_from_iana_info has ignored this string, causing it | ||
| 27 | to mishandle timestamps past the year 2038. With zic's new -b | ||
| 28 | slim flag, init_zone_from_iana_info would even mishandle current | ||
| 29 | timestamps. Fix this by parsing the trailing TZ string and adding | ||
| 30 | its transitions. | ||
| 31 | |||
| 32 | Closes #2129 | ||
| 33 | |||
| 34 | commit e8b763e35235a2c6b4bdd48a5099c00f72741059 | ||
| 35 | Author: Paul Eggert <eggert@cs.ucla.edu> | ||
| 36 | Date: Thu Jul 16 12:41:49 2020 -0700 | ||
| 37 | |||
| 38 | gtimezone: add support for RFC 8536 time zone transitions | ||
| 39 | |||
| 40 | Time zone transition times can range from -167:59:59 through | ||
| 41 | +167:59:59, according to Internet RFC 8536 section 3.3.1; | ||
| 42 | this is an extension to POSIX. It is needed for proper | ||
| 43 | support of TZif version 3 files. | ||
| 44 | |||
| 45 | commit 1c65dd48b8ebd31af8bc9b2263f83c0c411f7519 | ||
| 46 | Author: Paul Eggert <eggert@cs.ucla.edu> | ||
| 47 | Date: Thu Jul 16 12:41:49 2020 -0700 | ||
| 48 | |||
| 49 | gtimezone: allow hh to be 24, as per POSIX | ||
| 50 | |||
| 51 | POSIX allows hh to be 24; see | ||
| 52 | https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03 | ||
| 53 | |||
| 54 | commit 368b65cb4cb17e29a4f55654149f554a14f48bc6 | ||
| 55 | Author: Paul Eggert <eggert@cs.ucla.edu> | ||
| 56 | Date: Thu Jul 16 12:41:49 2020 -0700 | ||
| 57 | |||
| 58 | gtimezone: support POSIX 1003.1-2001 quoted TZ abbreviations | ||
| 59 | |||
| 60 | TZ strings like '<-03>3' were introduced in POSIX 1003.1-2001 and | ||
| 61 | are currently specified in: | ||
| 62 | https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03 | ||
| 63 | |||
| 64 | commit fd528aaab6bb077c6d217e62f2228ec9fe3ed760 | ||
| 65 | Author: Paul Eggert <eggert@cs.ucla.edu> | ||
| 66 | Date: Thu Jul 16 12:41:49 2020 -0700 | ||
| 67 | |||
| 68 | gtimezone: get 64-bit data from version-3 TZif files | ||
| 69 | |||
| 70 | Version 3 was introduced in tzdb 2013e (2013). | ||
| 71 | See Internet RFC 8536 section 3.1 under "ver(sion)". | ||
| 72 | |||
| 73 | diff --git a/glib/gtimezone.c b/glib/gtimezone.c | ||
| 74 | index 5a835dea9..f9eee1967 100644 | ||
| 75 | --- a/glib/gtimezone.c | ||
| 76 | +++ b/glib/gtimezone.c | ||
| 77 | @@ -142,9 +142,7 @@ typedef struct | ||
| 78 | gint mday; | ||
| 79 | gint wday; | ||
| 80 | gint week; | ||
| 81 | - gint hour; | ||
| 82 | - gint min; | ||
| 83 | - gint sec; | ||
| 84 | + gint32 offset; /* hour*3600 + min*60 + sec; can be negative. */ | ||
| 85 | } TimeZoneDate; | ||
| 86 | |||
| 87 | /* POSIX Timezone abbreviations are typically 3 or 4 characters, but | ||
| 88 | @@ -205,6 +203,10 @@ static GTimeZone *tz_local = NULL; | ||
| 89 | there's no point in getting carried | ||
| 90 | away. */ | ||
| 91 | |||
| 92 | +#ifdef G_OS_UNIX | ||
| 93 | +static GTimeZone *parse_footertz (const gchar *, size_t); | ||
| 94 | +#endif | ||
| 95 | + | ||
| 96 | /** | ||
| 97 | * g_time_zone_unref: | ||
| 98 | * @tz: a #GTimeZone | ||
| 99 | @@ -286,13 +288,20 @@ g_time_zone_ref (GTimeZone *tz) | ||
| 100 | /* fake zoneinfo creation (for RFC3339/ISO 8601 timezones) {{{1 */ | ||
| 101 | /* | ||
| 102 | * parses strings of the form h or hh[[:]mm[[[:]ss]]] where: | ||
| 103 | - * - h[h] is 0 to 23 | ||
| 104 | + * - h[h] is 0 to 24 | ||
| 105 | * - mm is 00 to 59 | ||
| 106 | * - ss is 00 to 59 | ||
| 107 | + * If RFC8536, TIME_ is a transition time sans sign, | ||
| 108 | + * so colons are required before mm and ss, and hh can be up to 167. | ||
| 109 | + * See Internet RFC 8536 section 3.3.1: | ||
| 110 | + * https://tools.ietf.org/html/rfc8536#section-3.3.1 | ||
| 111 | + * and POSIX Base Definitions 8.3 TZ rule time: | ||
| 112 | + * https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03 | ||
| 113 | */ | ||
| 114 | static gboolean | ||
| 115 | parse_time (const gchar *time_, | ||
| 116 | - gint32 *offset) | ||
| 117 | + gint32 *offset, | ||
| 118 | + gboolean rfc8536) | ||
| 119 | { | ||
| 120 | if (*time_ < '0' || '9' < *time_) | ||
| 121 | return FALSE; | ||
| 122 | @@ -310,7 +319,20 @@ parse_time (const gchar *time_, | ||
| 123 | *offset *= 10; | ||
| 124 | *offset += 60 * 60 * (*time_++ - '0'); | ||
| 125 | |||
| 126 | - if (*offset > 23 * 60 * 60) | ||
| 127 | + if (rfc8536) | ||
| 128 | + { | ||
| 129 | + /* Internet RFC 8536 section 3.3.1 and POSIX 8.3 TZ together say | ||
| 130 | + that a transition time must be of the form [+-]hh[:mm[:ss]] where | ||
| 131 | + the hours part can range from -167 to 167. */ | ||
| 132 | + if ('0' <= *time_ && *time_ <= '9') | ||
| 133 | + { | ||
| 134 | + *offset *= 10; | ||
| 135 | + *offset += 60 * 60 * (*time_++ - '0'); | ||
| 136 | + } | ||
| 137 | + if (*offset > 167 * 60 * 60) | ||
| 138 | + return FALSE; | ||
| 139 | + } | ||
| 140 | + else if (*offset > 24 * 60 * 60) | ||
| 141 | return FALSE; | ||
| 142 | |||
| 143 | if (*time_ == '\0') | ||
| 144 | @@ -319,6 +341,8 @@ parse_time (const gchar *time_, | ||
| 145 | |||
| 146 | if (*time_ == ':') | ||
| 147 | time_++; | ||
| 148 | + else if (rfc8536) | ||
| 149 | + return FALSE; | ||
| 150 | |||
| 151 | if (*time_ < '0' || '5' < *time_) | ||
| 152 | return FALSE; | ||
| 153 | @@ -335,6 +359,8 @@ parse_time (const gchar *time_, | ||
| 154 | |||
| 155 | if (*time_ == ':') | ||
| 156 | time_++; | ||
| 157 | + else if (rfc8536) | ||
| 158 | + return FALSE; | ||
| 159 | |||
| 160 | if (*time_ < '0' || '5' < *time_) | ||
| 161 | return FALSE; | ||
| 162 | @@ -351,28 +377,32 @@ parse_time (const gchar *time_, | ||
| 163 | |||
| 164 | static gboolean | ||
| 165 | parse_constant_offset (const gchar *name, | ||
| 166 | - gint32 *offset) | ||
| 167 | + gint32 *offset, | ||
| 168 | + gboolean rfc8536) | ||
| 169 | { | ||
| 170 | - if (g_strcmp0 (name, "UTC") == 0) | ||
| 171 | + /* Internet RFC 8536 section 3.3.1 and POSIX 8.3 TZ together say | ||
| 172 | + that a transition time must be numeric. */ | ||
| 173 | + if (!rfc8536 && g_strcmp0 (name, "UTC") == 0) | ||
| 174 | { | ||
| 175 | *offset = 0; | ||
| 176 | return TRUE; | ||
| 177 | } | ||
| 178 | |||
| 179 | if (*name >= '0' && '9' >= *name) | ||
| 180 | - return parse_time (name, offset); | ||
| 181 | + return parse_time (name, offset, rfc8536); | ||
| 182 | |||
| 183 | switch (*name++) | ||
| 184 | { | ||
| 185 | case 'Z': | ||
| 186 | *offset = 0; | ||
| 187 | - return !*name; | ||
| 188 | + /* Internet RFC 8536 section 3.3.1 requires a numeric zone. */ | ||
| 189 | + return !rfc8536 && !*name; | ||
| 190 | |||
| 191 | case '+': | ||
| 192 | - return parse_time (name, offset); | ||
| 193 | + return parse_time (name, offset, rfc8536); | ||
| 194 | |||
| 195 | case '-': | ||
| 196 | - if (parse_time (name, offset)) | ||
| 197 | + if (parse_time (name, offset, rfc8536)) | ||
| 198 | { | ||
| 199 | *offset = -*offset; | ||
| 200 | return TRUE; | ||
| 201 | @@ -391,7 +421,7 @@ zone_for_constant_offset (GTimeZone *gtz, const gchar *name) | ||
| 202 | gint32 offset; | ||
| 203 | TransitionInfo info; | ||
| 204 | |||
| 205 | - if (name == NULL || !parse_constant_offset (name, &offset)) | ||
| 206 | + if (name == NULL || !parse_constant_offset (name, &offset, FALSE)) | ||
| 207 | return; | ||
| 208 | |||
| 209 | info.gmt_offset = offset; | ||
| 210 | @@ -529,12 +559,17 @@ init_zone_from_iana_info (GTimeZone *gtz, | ||
| 211 | guint8 *tz_transitions, *tz_type_index, *tz_ttinfo; | ||
| 212 | guint8 *tz_abbrs; | ||
| 213 | gsize timesize = sizeof (gint32); | ||
| 214 | - const struct tzhead *header = g_bytes_get_data (zoneinfo, &size); | ||
| 215 | + gconstpointer header_data = g_bytes_get_data (zoneinfo, &size); | ||
| 216 | + const gchar *data = header_data; | ||
| 217 | + const struct tzhead *header = header_data; | ||
| 218 | + GTimeZone *footertz = NULL; | ||
| 219 | + guint extra_time_count = 0, extra_type_count = 0; | ||
| 220 | + gint64 last_explicit_transition_time; | ||
| 221 | |||
| 222 | g_return_if_fail (size >= sizeof (struct tzhead) && | ||
| 223 | memcmp (header, "TZif", 4) == 0); | ||
| 224 | |||
| 225 | - if (header->tzh_version == '2') | ||
| 226 | + if (header->tzh_version >= '2') | ||
| 227 | { | ||
| 228 | /* Skip ahead to the newer 64-bit data if it's available. */ | ||
| 229 | header = (const struct tzhead *) | ||
| 230 | @@ -550,6 +585,30 @@ init_zone_from_iana_info (GTimeZone *gtz, | ||
| 231 | time_count = guint32_from_be(header->tzh_timecnt); | ||
| 232 | type_count = guint32_from_be(header->tzh_typecnt); | ||
| 233 | |||
| 234 | + if (header->tzh_version >= '2') | ||
| 235 | + { | ||
| 236 | + const gchar *footer = (((const gchar *) (header + 1)) | ||
| 237 | + + guint32_from_be(header->tzh_ttisgmtcnt) | ||
| 238 | + + guint32_from_be(header->tzh_ttisstdcnt) | ||
| 239 | + + 12 * guint32_from_be(header->tzh_leapcnt) | ||
| 240 | + + 9 * time_count | ||
| 241 | + + 6 * type_count | ||
| 242 | + + guint32_from_be(header->tzh_charcnt)); | ||
| 243 | + const gchar *footerlast; | ||
| 244 | + size_t footerlen; | ||
| 245 | + g_return_if_fail (footer <= data + size - 2 && footer[0] == '\n'); | ||
| 246 | + footerlast = memchr (footer + 1, '\n', data + size - (footer + 1)); | ||
| 247 | + g_return_if_fail (footerlast); | ||
| 248 | + footerlen = footerlast + 1 - footer; | ||
| 249 | + if (footerlen != 2) | ||
| 250 | + { | ||
| 251 | + footertz = parse_footertz (footer, footerlen); | ||
| 252 | + g_return_if_fail (footertz); | ||
| 253 | + extra_type_count = footertz->t_info->len; | ||
| 254 | + extra_time_count = footertz->transitions->len; | ||
| 255 | + } | ||
| 256 | + } | ||
| 257 | + | ||
| 258 | tz_transitions = ((guint8 *) (header) + sizeof (*header)); | ||
| 259 | tz_type_index = tz_transitions + timesize * time_count; | ||
| 260 | tz_ttinfo = tz_type_index + time_count; | ||
| 261 | @@ -557,9 +616,9 @@ init_zone_from_iana_info (GTimeZone *gtz, | ||
| 262 | |||
| 263 | gtz->name = g_steal_pointer (&identifier); | ||
| 264 | gtz->t_info = g_array_sized_new (FALSE, TRUE, sizeof (TransitionInfo), | ||
| 265 | - type_count); | ||
| 266 | + type_count + extra_type_count); | ||
| 267 | gtz->transitions = g_array_sized_new (FALSE, TRUE, sizeof (Transition), | ||
| 268 | - time_count); | ||
| 269 | + time_count + extra_time_count); | ||
| 270 | |||
| 271 | for (index = 0; index < type_count; index++) | ||
| 272 | { | ||
| 273 | @@ -574,15 +633,50 @@ init_zone_from_iana_info (GTimeZone *gtz, | ||
| 274 | for (index = 0; index < time_count; index++) | ||
| 275 | { | ||
| 276 | Transition trans; | ||
| 277 | - if (header->tzh_version == '2') | ||
| 278 | + if (header->tzh_version >= '2') | ||
| 279 | trans.time = gint64_from_be (((gint64_be*)tz_transitions)[index]); | ||
| 280 | else | ||
| 281 | trans.time = gint32_from_be (((gint32_be*)tz_transitions)[index]); | ||
| 282 | + last_explicit_transition_time = trans.time; | ||
| 283 | trans.info_index = tz_type_index[index]; | ||
| 284 | g_assert (trans.info_index >= 0); | ||
| 285 | g_assert ((guint) trans.info_index < gtz->t_info->len); | ||
| 286 | g_array_append_val (gtz->transitions, trans); | ||
| 287 | } | ||
| 288 | + | ||
| 289 | + if (footertz) | ||
| 290 | + { | ||
| 291 | + /* Append footer time types. Don't bother to coalesce | ||
| 292 | + duplicates with existing time types. */ | ||
| 293 | + for (index = 0; index < extra_type_count; index++) | ||
| 294 | + { | ||
| 295 | + TransitionInfo t_info; | ||
| 296 | + TransitionInfo *footer_t_info | ||
| 297 | + = &g_array_index (footertz->t_info, TransitionInfo, index); | ||
| 298 | + t_info.gmt_offset = footer_t_info->gmt_offset; | ||
| 299 | + t_info.is_dst = footer_t_info->is_dst; | ||
| 300 | + t_info.abbrev = g_steal_pointer (&footer_t_info->abbrev); | ||
| 301 | + g_array_append_val (gtz->t_info, t_info); | ||
| 302 | + } | ||
| 303 | + | ||
| 304 | + /* Append footer transitions that follow the last explicit | ||
| 305 | + transition. */ | ||
| 306 | + for (index = 0; index < extra_time_count; index++) | ||
| 307 | + { | ||
| 308 | + Transition *footer_transition | ||
| 309 | + = &g_array_index (footertz->transitions, Transition, index); | ||
| 310 | + if (time_count <= 0 | ||
| 311 | + || last_explicit_transition_time < footer_transition->time) | ||
| 312 | + { | ||
| 313 | + Transition trans; | ||
| 314 | + trans.time = footer_transition->time; | ||
| 315 | + trans.info_index = type_count + footer_transition->info_index; | ||
| 316 | + g_array_append_val (gtz->transitions, trans); | ||
| 317 | + } | ||
| 318 | + } | ||
| 319 | + | ||
| 320 | + g_time_zone_unref (footertz); | ||
| 321 | + } | ||
| 322 | } | ||
| 323 | |||
| 324 | #elif defined (G_OS_WIN32) | ||
| 325 | @@ -590,9 +684,8 @@ init_zone_from_iana_info (GTimeZone *gtz, | ||
| 326 | static void | ||
| 327 | copy_windows_systemtime (SYSTEMTIME *s_time, TimeZoneDate *tzdate) | ||
| 328 | { | ||
| 329 | - tzdate->sec = s_time->wSecond; | ||
| 330 | - tzdate->min = s_time->wMinute; | ||
| 331 | - tzdate->hour = s_time->wHour; | ||
| 332 | + tzdate->offset | ||
| 333 | + = s_time->wHour * 3600 + s_time->wMinute * 60 + s_time->wSecond; | ||
| 334 | tzdate->mon = s_time->wMonth; | ||
| 335 | tzdate->year = s_time->wYear; | ||
| 336 | tzdate->wday = s_time->wDayOfWeek ? s_time->wDayOfWeek : 7; | ||
| 337 | @@ -979,7 +1072,7 @@ boundary_for_year (TimeZoneDate *boundary, | ||
| 338 | g_date_clear (&date, 1); | ||
| 339 | g_date_set_dmy (&date, buffer.mday, buffer.mon, buffer.year); | ||
| 340 | return ((g_date_get_julian (&date) - unix_epoch_start) * seconds_per_day + | ||
| 341 | - buffer.hour * 3600 + buffer.min * 60 + buffer.sec - offset); | ||
| 342 | + buffer.offset - offset); | ||
| 343 | } | ||
| 344 | |||
| 345 | static void | ||
| 346 | @@ -1156,7 +1249,7 @@ init_zone_from_rules (GTimeZone *gtz, | ||
| 347 | * - N is 0 to 365 | ||
| 348 | * | ||
| 349 | * time is either h or hh[[:]mm[[[:]ss]]] | ||
| 350 | - * - h[h] is 0 to 23 | ||
| 351 | + * - h[h] is 0 to 24 | ||
| 352 | * - mm is 00 to 59 | ||
| 353 | * - ss is 00 to 59 | ||
| 354 | */ | ||
| 355 | @@ -1289,25 +1382,10 @@ parse_tz_boundary (const gchar *identifier, | ||
| 356 | /* Time */ | ||
| 357 | |||
| 358 | if (*pos == '/') | ||
| 359 | - { | ||
| 360 | - gint32 offset; | ||
| 361 | - | ||
| 362 | - if (!parse_time (++pos, &offset)) | ||
| 363 | - return FALSE; | ||
| 364 | - | ||
| 365 | - boundary->hour = offset / 3600; | ||
| 366 | - boundary->min = (offset / 60) % 60; | ||
| 367 | - boundary->sec = offset % 3600; | ||
| 368 | - | ||
| 369 | - return TRUE; | ||
| 370 | - } | ||
| 371 | - | ||
| 372 | + return parse_constant_offset (pos + 1, &boundary->offset, TRUE); | ||
| 373 | else | ||
| 374 | { | ||
| 375 | - boundary->hour = 2; | ||
| 376 | - boundary->min = 0; | ||
| 377 | - boundary->sec = 0; | ||
| 378 | - | ||
| 379 | + boundary->offset = 2 * 60 * 60; | ||
| 380 | return *pos == '\0'; | ||
| 381 | } | ||
| 382 | } | ||
| 383 | @@ -1341,7 +1419,7 @@ parse_offset (gchar **pos, gint32 *target) | ||
| 384 | ++(*pos); | ||
| 385 | |||
| 386 | buffer = g_strndup (target_pos, *pos - target_pos); | ||
| 387 | - ret = parse_constant_offset (buffer, target); | ||
| 388 | + ret = parse_constant_offset (buffer, target, FALSE); | ||
| 389 | g_free (buffer); | ||
| 390 | |||
| 391 | return ret; | ||
| 392 | @@ -1366,21 +1444,32 @@ parse_identifier_boundary (gchar **pos, TimeZoneDate *target) | ||
| 393 | static gboolean | ||
| 394 | set_tz_name (gchar **pos, gchar *buffer, guint size) | ||
| 395 | { | ||
| 396 | + gboolean quoted = **pos == '<'; | ||
| 397 | gchar *name_pos = *pos; | ||
| 398 | guint len; | ||
| 399 | |||
| 400 | - /* Name is ASCII alpha (Is this necessarily true?) */ | ||
| 401 | - while (g_ascii_isalpha (**pos)) | ||
| 402 | - ++(*pos); | ||
| 403 | + if (quoted) | ||
| 404 | + { | ||
| 405 | + name_pos++; | ||
| 406 | + do | ||
| 407 | + ++(*pos); | ||
| 408 | + while (g_ascii_isalnum (**pos) || **pos == '-' || **pos == '+'); | ||
| 409 | + if (**pos != '>') | ||
| 410 | + return FALSE; | ||
| 411 | + } | ||
| 412 | + else | ||
| 413 | + while (g_ascii_isalpha (**pos)) | ||
| 414 | + ++(*pos); | ||
| 415 | |||
| 416 | - /* Name should be three or more alphabetic characters */ | ||
| 417 | + /* Name should be three or more characters */ | ||
| 418 | if (*pos - name_pos < 3) | ||
| 419 | return FALSE; | ||
| 420 | |||
| 421 | - memset (buffer, 0, NAME_SIZE); | ||
| 422 | + memset (buffer, 0, size); | ||
| 423 | /* name_pos isn't 0-terminated, so we have to limit the length expressly */ | ||
| 424 | len = *pos - name_pos > size - 1 ? size - 1 : *pos - name_pos; | ||
| 425 | strncpy (buffer, name_pos, len); | ||
| 426 | + *pos += quoted; | ||
| 427 | return TRUE; | ||
| 428 | } | ||
| 429 | |||
| 430 | @@ -1483,6 +1572,28 @@ rules_from_identifier (const gchar *identifier, | ||
| 431 | return create_ruleset_from_rule (rules, &tzr); | ||
| 432 | } | ||
| 433 | |||
| 434 | +#ifdef G_OS_UNIX | ||
| 435 | +static GTimeZone * | ||
| 436 | +parse_footertz (const gchar *footer, size_t footerlen) | ||
| 437 | +{ | ||
| 438 | + gchar *tzstring = g_strndup (footer + 1, footerlen - 2); | ||
| 439 | + GTimeZone *footertz = NULL; | ||
| 440 | + gchar *ident; | ||
| 441 | + TimeZoneRule *rules; | ||
| 442 | + guint rules_num = rules_from_identifier (tzstring, &ident, &rules); | ||
| 443 | + g_free (ident); | ||
| 444 | + g_free (tzstring); | ||
| 445 | + if (rules_num > 1) | ||
| 446 | + { | ||
| 447 | + footertz = g_slice_new0 (GTimeZone); | ||
| 448 | + init_zone_from_rules (footertz, rules, rules_num, NULL); | ||
| 449 | + footertz->ref_count++; | ||
| 450 | + } | ||
| 451 | + g_free (rules); | ||
| 452 | + return footertz; | ||
| 453 | +} | ||
| 454 | +#endif | ||
| 455 | + | ||
| 456 | /* Construction {{{1 */ | ||
| 457 | /** | ||
| 458 | * g_time_zone_new: | ||
diff --git a/meta/recipes-core/glib-2.0/glib-2.0_2.64.5.bb b/meta/recipes-core/glib-2.0/glib-2.0_2.64.5.bb index a1233e6926..a30c5215be 100644 --- a/meta/recipes-core/glib-2.0/glib-2.0_2.64.5.bb +++ b/meta/recipes-core/glib-2.0/glib-2.0_2.64.5.bb | |||
| @@ -16,6 +16,7 @@ SRC_URI = "${GNOME_MIRROR}/glib/${SHRT_VER}/glib-${PV}.tar.xz \ | |||
| 16 | file://0001-Do-not-write-bindir-into-pkg-config-files.patch \ | 16 | file://0001-Do-not-write-bindir-into-pkg-config-files.patch \ |
| 17 | file://0001-meson-Run-atomics-test-on-clang-as-well.patch \ | 17 | file://0001-meson-Run-atomics-test-on-clang-as-well.patch \ |
| 18 | file://0001-gio-tests-resources.c-comment-out-a-build-host-only-.patch \ | 18 | file://0001-gio-tests-resources.c-comment-out-a-build-host-only-.patch \ |
| 19 | file://tzdata-update.patch \ | ||
| 19 | " | 20 | " |
| 20 | 21 | ||
| 21 | SRC_URI_append_class-native = " file://relocate-modules.patch" | 22 | SRC_URI_append_class-native = " file://relocate-modules.patch" |
