Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP3:Update
libical.17519
libical-read-v2-v3-data.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File libical-read-v2-v3-data.patch of Package libical.17519
From c7e767bfe1d218aaf845686f9811195cecc7be2a Mon Sep 17 00:00:00 2001 From: Ken Murchison <murch@fastmail.com> Date: Wed, 11 Nov 2020 08:50:54 -0500 Subject: [PATCH] icaltzutil_fetch_timezone() should read v2/v3 data when available Rebased by Mike Gorse <mgorse@suse.com> --- diff -urp libical-1.0.1.orig/src/libical/icaltz-util.c libical-1.0.1/src/libical/icaltz-util.c --- libical-1.0.1.orig/src/libical/icaltz-util.c 2014-10-09 10:07:05.000000000 -0500 +++ libical-1.0.1/src/libical/icaltz-util.c 2020-11-30 17:23:00.060895834 -0600 @@ -99,6 +99,9 @@ typedef struct { + char magic[4]; + char version; + char unused[15]; char ttisgmtcnt [4]; char ttisstdcnt[4]; char leapcnt[4]; @@ -166,6 +169,24 @@ decode (const void *ptr) } } +static long long int +decode64(const void *ptr) +{ +#if defined(sun) && defined(__SVR4) +#if defined(_BIG_ENDIAN) + return *(const long long int *)ptr; +#else + return BSWAP_64(*(const long long int *)ptr); +#endif +#else + if ((BYTE_ORDER == BIG_ENDIAN)) { + return *(const long long int *)ptr; + } else { + return (int)bswap_64(*(const long long int *)ptr); + } +#endif +} + static char * zname_from_stridx (char *str, long int idx) { @@ -217,7 +238,7 @@ icaltzutil_fetch_timezone (const char *l { int ret = 0; FILE *f; - tzinfo type_cnts; + tzinfo header; unsigned int i, num_trans, num_types = 0, num_chars, num_leaps, num_isstd, num_isgmt; time_t *transitions = NULL; time_t start, end; @@ -229,6 +250,7 @@ icaltzutil_fetch_timezone (const char *l icalproperty *icalprop; icaltimetype dtstart; const char *basedir; + int trans_size = 4; if(icaltimezone_get_builtin_tzdata()) { return NULL; @@ -248,31 +270,85 @@ icaltzutil_fetch_timezone (const char *l return NULL; } - if ((ret = fseek (f, 20, SEEK_SET)) != 0) { - icalerror_set_errno (ICAL_FILE_ERROR); + /* read version 1 header */ + EFREAD(&header, 44, 1, f); + if (memcmp(header.magic, "TZif", 4)) { + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + goto error; + } + switch (header.version) { + case 0: + break; + case '2': + case '3': + if (sizeof(time_t) == 8) + trans_size = 8; + break; + default: + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); goto error; } - EFREAD(&type_cnts, 24, 1, f); + num_isgmt = (size_t)decode(header.ttisgmtcnt); + num_leaps = (size_t)decode(header.leapcnt); + num_chars = (size_t)decode(header.charcnt); + num_trans = (size_t)decode(header.timecnt); + num_isstd = (size_t)decode(header.ttisstdcnt); + num_types = (size_t)decode(header.typecnt); + + if (trans_size == 8) { + long skip = num_trans * 5 + num_types * 6 + + num_chars + num_leaps * 8 + num_isstd + num_isgmt; + + /* skip version 1 data block */ + if (fseek(f, skip, SEEK_CUR) != 0) { + icalerror_set_errno(ICAL_FILE_ERROR); + goto error; + } - num_isgmt = decode (type_cnts.ttisgmtcnt); - num_leaps = decode (type_cnts.leapcnt); - num_chars = decode (type_cnts.charcnt); - num_trans = decode (type_cnts.timecnt); - num_isstd = decode (type_cnts.ttisstdcnt); - num_types = decode (type_cnts.typecnt); - - transitions = calloc (num_trans, sizeof (time_t)); - r_trans = calloc (num_trans, 4); - EFREAD(r_trans, 4, num_trans, f); + /* read version 2+ header */ + EFREAD(&header, 44, 1, f); + if (memcmp(header.magic, "TZif", 4)) { + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + goto error; + } + + num_isgmt = (size_t)decode(header.ttisgmtcnt); + num_leaps = (size_t)decode(header.leapcnt); + num_chars = (size_t)decode(header.charcnt); + num_trans = (size_t)decode(header.timecnt); + num_isstd = (size_t)decode(header.ttisstdcnt); + num_types = (size_t)decode(header.typecnt); + } + + /* read data block */ + if (num_trans > 0) { + transitions = calloc(num_trans, sizeof(time_t)); + if (transitions == NULL) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + goto error; + } + r_trans = calloc(num_trans, trans_size); + if (r_trans == NULL) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + goto error; + } + } else { + icalerror_set_errno(ICAL_FILE_ERROR); + goto error; + } + EFREAD(r_trans, trans_size, num_trans, f); temp = r_trans; if (num_trans) { trans_idx = calloc (num_trans, sizeof (int)); for (i = 0; i < num_trans; i++) { trans_idx [i] = fgetc (f); - transitions [i] = decode (r_trans); - r_trans += 4; + if (trans_size == 8) + transitions[i] = (time_t) decode64(r_trans); + else + transitions[i] = (time_t) decode(r_trans); + r_trans += trans_size; } } @@ -301,10 +377,13 @@ icaltzutil_fetch_timezone (const char *l leaps = calloc (num_leaps, sizeof (leap)); for (i = 0; i < num_leaps; i++) { - char c [4]; + char c [8]; - EFREAD (c, 4, 1, f); - leaps [i].transition = decode (c); + EFREAD (c, trans_size, 1, f); + if (trans_size == 8) + leaps[i].transition = (time_t)decode64(c); + else + leaps[i].transition = (time_t)decode(c); EFREAD (c, 4, 1, f); leaps [i].change = decode (c); @@ -326,6 +405,10 @@ icaltzutil_fetch_timezone (const char *l while (i < num_types) types [i++].isgmt = 0; + if (trans_size == 8) { + /* XXX Do we need/want to read and use the footer? */ + } + /* Read all the contents now */ for (i = 0; i < num_types; i++)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor