diff options
-rw-r--r-- | ext/date/lib/parse_tz.c | 297 | ||||
-rw-r--r-- | ext/date/lib/timelib.h | 8 | ||||
-rw-r--r-- | ext/date/lib/timelib_private.h | 2 | ||||
-rw-r--r-- | ext/date/php_date.c | 10 |
4 files changed, 177 insertions, 140 deletions
diff --git a/ext/date/lib/parse_tz.c b/ext/date/lib/parse_tz.c index 5986cd6468..c8e501151f 100644 --- a/ext/date/lib/parse_tz.c +++ b/ext/date/lib/parse_tz.c @@ -51,17 +51,37 @@ static inline uint32_t timelib_conv_int_unsigned(uint32_t value) { return value; } + +static inline uint64_t timelib_conv_int64_unsigned(uint64_t value) +{ + return value; +} #else static inline uint32_t timelib_conv_int_unsigned(uint32_t value) { - return ((value & 0x000000ff) << 24) + - ((value & 0x0000ff00) << 8) + - ((value & 0x00ff0000) >> 8) + + return + ((value & 0x000000ff) << 24) + + ((value & 0x0000ff00) << 8) + + ((value & 0x00ff0000) >> 8) + ((value & 0xff000000) >> 24); } + +static inline uint64_t timelib_conv_int64_unsigned(uint64_t value) +{ + return + ((value & 0x00000000000000ff) << 56) + + ((value & 0x000000000000ff00) << 40) + + ((value & 0x0000000000ff0000) << 24) + + ((value & 0x00000000ff000000) << 8) + + ((value & 0x000000ff00000000) >> 8) + + ((value & 0x0000ff0000000000) >> 24) + + ((value & 0x00ff000000000000) >> 40) + + ((value & 0xff00000000000000) >> 56); +} #endif #define timelib_conv_int_signed(value) ((int32_t) timelib_conv_int_unsigned((int32_t) value)) +#define timelib_conv_int64_signed(value) ((int64_t) timelib_conv_int64_unsigned((int64_t) value)) static int read_php_preamble(const unsigned char **tzf, timelib_tzinfo *tz) { @@ -132,56 +152,49 @@ static int read_preamble(const unsigned char **tzf, timelib_tzinfo *tz, unsigned } } -static void read_header(const unsigned char **tzf, timelib_tzinfo *tz) +static void read_32bit_header(const unsigned char **tzf, timelib_tzinfo *tz) { uint32_t buffer[6]; memcpy(&buffer, *tzf, sizeof(buffer)); - tz->bit32.ttisgmtcnt = timelib_conv_int_unsigned(buffer[0]); - tz->bit32.ttisstdcnt = timelib_conv_int_unsigned(buffer[1]); - tz->bit32.leapcnt = timelib_conv_int_unsigned(buffer[2]); - tz->bit32.timecnt = timelib_conv_int_unsigned(buffer[3]); - tz->bit32.typecnt = timelib_conv_int_unsigned(buffer[4]); - tz->bit32.charcnt = timelib_conv_int_unsigned(buffer[5]); - *tzf += sizeof(buffer); -} + tz->_bit32.ttisgmtcnt = timelib_conv_int_unsigned(buffer[0]); + tz->_bit32.ttisstdcnt = timelib_conv_int_unsigned(buffer[1]); + tz->_bit32.leapcnt = timelib_conv_int_unsigned(buffer[2]); + tz->_bit32.timecnt = timelib_conv_int_unsigned(buffer[3]); + tz->_bit32.typecnt = timelib_conv_int_unsigned(buffer[4]); + tz->_bit32.charcnt = timelib_conv_int_unsigned(buffer[5]); -static void skip_64bit_transitions(const unsigned char **tzf, timelib_tzinfo *tz) -{ - if (tz->bit64.timecnt) { - *tzf += (sizeof(int64_t) * tz->bit64.timecnt); - *tzf += (sizeof(unsigned char) * tz->bit64.timecnt); - } + *tzf += sizeof(buffer); } -static int read_transitions(const unsigned char **tzf, timelib_tzinfo *tz) +static int read_64bit_transitions(const unsigned char **tzf, timelib_tzinfo *tz) { - int32_t *buffer = NULL; + int64_t *buffer = NULL; uint32_t i; unsigned char *cbuffer = NULL; - if (tz->bit32.timecnt) { - buffer = (int32_t*) timelib_malloc(tz->bit32.timecnt * sizeof(int32_t)); + if (tz->bit64.timecnt) { + buffer = (int64_t*) timelib_malloc(tz->bit64.timecnt * sizeof(int64_t)); if (!buffer) { return TIMELIB_ERROR_CANNOT_ALLOCATE; } - memcpy(buffer, *tzf, sizeof(int32_t) * tz->bit32.timecnt); - *tzf += (sizeof(int32_t) * tz->bit32.timecnt); - for (i = 0; i < tz->bit32.timecnt; i++) { - buffer[i] = timelib_conv_int_signed(buffer[i]); + memcpy(buffer, *tzf, sizeof(int64_t) * tz->bit64.timecnt); + *tzf += (sizeof(int64_t) * tz->bit64.timecnt); + for (i = 0; i < tz->bit64.timecnt; i++) { + buffer[i] = timelib_conv_int64_signed(buffer[i]); /* Sanity check to see whether TS is just increasing */ if (i > 0 && !(buffer[i] > buffer[i - 1])) { return TIMELIB_ERROR_CORRUPT_TRANSITIONS_DONT_INCREASE; } } - cbuffer = (unsigned char*) timelib_malloc(tz->bit32.timecnt * sizeof(unsigned char)); + cbuffer = (unsigned char*) timelib_malloc(tz->bit64.timecnt * sizeof(unsigned char)); if (!cbuffer) { timelib_free(buffer); return TIMELIB_ERROR_CANNOT_ALLOCATE; } - memcpy(cbuffer, *tzf, sizeof(unsigned char) * tz->bit32.timecnt); - *tzf += sizeof(unsigned char) * tz->bit32.timecnt; + memcpy(cbuffer, *tzf, sizeof(unsigned char) * tz->bit64.timecnt); + *tzf += sizeof(unsigned char) * tz->bit64.timecnt; } tz->trans = buffer; @@ -190,41 +203,35 @@ static int read_transitions(const unsigned char **tzf, timelib_tzinfo *tz) return 0; } -static void skip_64bit_types(const unsigned char **tzf, timelib_tzinfo *tz) +static void skip_32bit_transitions(const unsigned char **tzf, timelib_tzinfo *tz) { - *tzf += sizeof(unsigned char) * 6 * tz->bit64.typecnt; - *tzf += sizeof(char) * tz->bit64.charcnt; - if (tz->bit64.leapcnt) { - *tzf += sizeof(int64_t) * tz->bit64.leapcnt * 2; - } - if (tz->bit64.ttisstdcnt) { - *tzf += sizeof(unsigned char) * tz->bit64.ttisstdcnt; - } - if (tz->bit64.ttisgmtcnt) { - *tzf += sizeof(unsigned char) * tz->bit64.ttisgmtcnt; + if (tz->_bit32.timecnt) { + *tzf += (sizeof(int32_t) * tz->_bit32.timecnt); + *tzf += sizeof(unsigned char) * tz->_bit32.timecnt; } } -static int read_types(const unsigned char **tzf, timelib_tzinfo *tz) +static int read_64bit_types(const unsigned char **tzf, timelib_tzinfo *tz) { unsigned char *buffer; int32_t *leap_buffer; unsigned int i, j; - buffer = (unsigned char*) timelib_malloc(tz->bit32.typecnt * sizeof(unsigned char) * 6); + /* Offset Types */ + buffer = (unsigned char*) timelib_malloc(tz->bit64.typecnt * sizeof(unsigned char) * 6); if (!buffer) { return TIMELIB_ERROR_CANNOT_ALLOCATE; } - memcpy(buffer, *tzf, sizeof(unsigned char) * 6 * tz->bit32.typecnt); - *tzf += sizeof(unsigned char) * 6 * tz->bit32.typecnt; + memcpy(buffer, *tzf, sizeof(unsigned char) * 6 * tz->bit64.typecnt); + *tzf += sizeof(unsigned char) * 6 * tz->bit64.typecnt; - tz->type = (ttinfo*) timelib_malloc(tz->bit32.typecnt * sizeof(ttinfo)); + tz->type = (ttinfo*) timelib_malloc(tz->bit64.typecnt * sizeof(ttinfo)); if (!tz->type) { timelib_free(buffer); return TIMELIB_ERROR_CANNOT_ALLOCATE; } - for (i = 0; i < tz->bit32.typecnt; i++) { + for (i = 0; i < tz->bit64.typecnt; i++) { j = i * 6; tz->type[i].offset = 0; tz->type[i].offset += (int32_t) (((uint32_t) buffer[j]) << 24) + (buffer[j + 1] << 16) + (buffer[j + 2] << 8) + tz->type[i].offset + buffer[j + 3]; @@ -233,56 +240,60 @@ static int read_types(const unsigned char **tzf, timelib_tzinfo *tz) } timelib_free(buffer); - tz->timezone_abbr = (char*) timelib_malloc(tz->bit32.charcnt); + /* Abbreviations */ + tz->timezone_abbr = (char*) timelib_malloc(tz->bit64.charcnt); if (!tz->timezone_abbr) { return TIMELIB_ERROR_CORRUPT_NO_ABBREVIATION; } - memcpy(tz->timezone_abbr, *tzf, sizeof(char) * tz->bit32.charcnt); - *tzf += sizeof(char) * tz->bit32.charcnt; + memcpy(tz->timezone_abbr, *tzf, sizeof(char) * tz->bit64.charcnt); + *tzf += sizeof(char) * tz->bit64.charcnt; - if (tz->bit32.leapcnt) { - leap_buffer = (int32_t *) timelib_malloc(tz->bit32.leapcnt * 2 * sizeof(int32_t)); + /* Leap seconds (only use in 'right/') format */ + if (tz->bit64.leapcnt) { + leap_buffer = (int32_t *) timelib_malloc(tz->bit64.leapcnt * (sizeof(int64_t) + sizeof(int32_t))); if (!leap_buffer) { return TIMELIB_ERROR_CANNOT_ALLOCATE; } - memcpy(leap_buffer, *tzf, sizeof(int32_t) * tz->bit32.leapcnt * 2); - *tzf += sizeof(int32_t) * tz->bit32.leapcnt * 2; + memcpy(leap_buffer, *tzf, tz->bit64.leapcnt * (sizeof(int64_t) + sizeof(int32_t))); + *tzf += tz->bit64.leapcnt * (sizeof(int64_t) + sizeof(int32_t)); - tz->leap_times = (tlinfo*) timelib_malloc(tz->bit32.leapcnt * sizeof(tlinfo)); + tz->leap_times = (tlinfo*) timelib_malloc(tz->bit64.leapcnt * sizeof(tlinfo)); if (!tz->leap_times) { timelib_free(leap_buffer); return TIMELIB_ERROR_CANNOT_ALLOCATE; } - for (i = 0; i < tz->bit32.leapcnt; i++) { - tz->leap_times[i].trans = timelib_conv_int_signed(leap_buffer[i * 2]); - tz->leap_times[i].offset = timelib_conv_int_signed(leap_buffer[i * 2 + 1]); + for (i = 0; i < tz->bit64.leapcnt; i++) { + tz->leap_times[i].trans = timelib_conv_int64_signed(leap_buffer[i * 3 + 1] * 4294967296 + leap_buffer[i * 3]); + tz->leap_times[i].offset = timelib_conv_int_signed(leap_buffer[i * 3 + 2]); } timelib_free(leap_buffer); } - if (tz->bit32.ttisstdcnt) { - buffer = (unsigned char*) timelib_malloc(tz->bit32.ttisstdcnt * sizeof(unsigned char)); + /* Standard/Wall Indicators (unused) */ + if (tz->bit64.ttisstdcnt) { + buffer = (unsigned char*) timelib_malloc(tz->bit64.ttisstdcnt * sizeof(unsigned char)); if (!buffer) { return TIMELIB_ERROR_CANNOT_ALLOCATE; } - memcpy(buffer, *tzf, sizeof(unsigned char) * tz->bit32.ttisstdcnt); - *tzf += sizeof(unsigned char) * tz->bit32.ttisstdcnt; + memcpy(buffer, *tzf, sizeof(unsigned char) * tz->bit64.ttisstdcnt); + *tzf += sizeof(unsigned char) * tz->bit64.ttisstdcnt; - for (i = 0; i < tz->bit32.ttisstdcnt; i++) { + for (i = 0; i < tz->bit64.ttisstdcnt; i++) { tz->type[i].isstdcnt = buffer[i]; } timelib_free(buffer); } - if (tz->bit32.ttisgmtcnt) { - buffer = (unsigned char*) timelib_malloc(tz->bit32.ttisgmtcnt * sizeof(unsigned char)); + /* UT/Local Time Indicators (unused) */ + if (tz->bit64.ttisgmtcnt) { + buffer = (unsigned char*) timelib_malloc(tz->bit64.ttisgmtcnt * sizeof(unsigned char)); if (!buffer) { return TIMELIB_ERROR_CANNOT_ALLOCATE; } - memcpy(buffer, *tzf, sizeof(unsigned char) * tz->bit32.ttisgmtcnt); - *tzf += sizeof(unsigned char) * tz->bit32.ttisgmtcnt; + memcpy(buffer, *tzf, sizeof(unsigned char) * tz->bit64.ttisgmtcnt); + *tzf += sizeof(unsigned char) * tz->bit64.ttisgmtcnt; - for (i = 0; i < tz->bit32.ttisgmtcnt; i++) { + for (i = 0; i < tz->bit64.ttisgmtcnt; i++) { tz->type[i].isgmtcnt = buffer[i]; } timelib_free(buffer); @@ -291,6 +302,30 @@ static int read_types(const unsigned char **tzf, timelib_tzinfo *tz) return 0; } +static void skip_32bit_types(const unsigned char **tzf, timelib_tzinfo *tz) +{ + /* Offset Types */ + *tzf += sizeof(unsigned char) * 6 * tz->_bit32.typecnt; + + /* Abbreviations */ + *tzf += sizeof(char) * tz->_bit32.charcnt; + + /* Leap seconds (only use in 'right/') format */ + if (tz->_bit32.leapcnt) { + *tzf += sizeof(int32_t) * tz->_bit32.leapcnt * 2; + } + + /* Standard/Wall Indicators (unused) */ + if (tz->_bit32.ttisstdcnt) { + *tzf += sizeof(unsigned char) * tz->_bit32.ttisstdcnt; + } + + /* UT/Local Time Indicators (unused) */ + if (tz->_bit32.ttisgmtcnt) { + *tzf += sizeof(unsigned char) * tz->_bit32.ttisgmtcnt; + } +} + static void skip_posix_string(const unsigned char **tzf, timelib_tzinfo *tz) { int n_count = 0; @@ -339,14 +374,16 @@ void timelib_dump_tzinfo(timelib_tzinfo *tz) printf("Geo Location: %f,%f\n", tz->location.latitude, tz->location.longitude); printf("Comments:\n%s\n", tz->location.comments); printf("BC: %s\n", tz->bc ? "" : "yes"); - printf("UTC/Local count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit32.ttisgmtcnt); - printf("Std/Wall count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit32.ttisstdcnt); - printf("Leap.sec. count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit32.leapcnt); - printf("Trans. count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit32.timecnt); - printf("Local types count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit32.typecnt); - printf("Zone Abbr. count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit32.charcnt); - - printf ("%8s (%12s) = %3d [%5ld %1d %3d '%s' (%d,%d)]\n", + + printf("\n64-bit:\n"); + printf("UTC/Local count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit64.ttisgmtcnt); + printf("Std/Wall count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit64.ttisstdcnt); + printf("Leap.sec. count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit64.leapcnt); + printf("Trans. count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit64.timecnt); + printf("Local types count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit64.typecnt); + printf("Zone Abbr. count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit64.charcnt); + + printf ("%16s (%20s) = %3d [%5ld %1d %3d '%s' (%d,%d)]\n", "", "", 0, (long int) tz->type[0].offset, tz->type[0].isdst, @@ -355,8 +392,8 @@ void timelib_dump_tzinfo(timelib_tzinfo *tz) tz->type[0].isstdcnt, tz->type[0].isgmtcnt ); - for (i = 0; i < tz->bit32.timecnt; i++) { - printf ("%08X (%12d) = %3d [%5ld %1d %3d '%s' (%d,%d)]\n", + for (i = 0; i < tz->bit64.timecnt; i++) { + printf ("%016lX (%20ld) = %3d [%5ld %1d %3d '%s' (%d,%d)]\n", tz->trans[i], tz->trans[i], tz->trans_idx[i], (long int) tz->type[tz->trans_idx[i]].offset, tz->type[tz->trans_idx[i]].isdst, @@ -366,8 +403,8 @@ void timelib_dump_tzinfo(timelib_tzinfo *tz) tz->type[tz->trans_idx[i]].isgmtcnt ); } - for (i = 0; i < tz->bit32.leapcnt; i++) { - printf ("%08X (%12ld) = %d\n", + for (i = 0; i < tz->bit64.leapcnt; i++) { + printf ("%016lX (%20ld) = %d\n", tz->leap_times[i].trans, (long) tz->leap_times[i].trans, tz->leap_times[i].offset); @@ -470,31 +507,35 @@ timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb, i timelib_tzinfo_dtor(tmp); return NULL; } + if (version < 2 || version > 3) { + *error_code = TIMELIB_ERROR_UNSUPPORTED_VERSION; + timelib_tzinfo_dtor(tmp); + return NULL; + } //printf("- timezone: %s, version: %0d\n", timezone, version); - read_header(&tzf, tmp); - if ((transitions_result = read_transitions(&tzf, tmp)) != 0) { + read_32bit_header(&tzf, tmp); + skip_32bit_transitions(&tzf, tmp); + skip_32bit_types(&tzf, tmp); + + if (!skip_64bit_preamble(&tzf, tmp)) { + /* 64 bit preamble is not in place */ + *error_code = TIMELIB_ERROR_CORRUPT_NO_64BIT_PREAMBLE; + return NULL; + } + read_64bit_header(&tzf, tmp); + if ((transitions_result = read_64bit_transitions(&tzf, tmp)) != 0) { /* Corrupt file as transitions do not increase */ *error_code = transitions_result; timelib_tzinfo_dtor(tmp); return NULL; } - if ((types_result = read_types(&tzf, tmp)) != 0) { + if ((types_result = read_64bit_types(&tzf, tmp)) != 0) { *error_code = types_result; timelib_tzinfo_dtor(tmp); return NULL; } - if (version == 2 || version == 3) { - if (!skip_64bit_preamble(&tzf, tmp)) { - /* 64 bit preamble is not in place */ - *error_code = TIMELIB_ERROR_CORRUPT_NO_64BIT_PREAMBLE; - return NULL; - } - read_64bit_header(&tzf, tmp); - skip_64bit_transitions(&tzf, tmp); - skip_64bit_types(&tzf, tmp); - skip_posix_string(&tzf, tmp); - } + skip_posix_string(&tzf, tmp); if (type == TIMELIB_TZINFO_PHP) { read_location(&tzf, tmp); @@ -525,29 +566,35 @@ void timelib_tzinfo_dtor(timelib_tzinfo *tz) timelib_tzinfo *timelib_tzinfo_clone(timelib_tzinfo *tz) { timelib_tzinfo *tmp = timelib_tzinfo_ctor(tz->name); - tmp->bit32.ttisgmtcnt = tz->bit32.ttisgmtcnt; - tmp->bit32.ttisstdcnt = tz->bit32.ttisstdcnt; - tmp->bit32.leapcnt = tz->bit32.leapcnt; - tmp->bit32.timecnt = tz->bit32.timecnt; - tmp->bit32.typecnt = tz->bit32.typecnt; - tmp->bit32.charcnt = tz->bit32.charcnt; - - if (tz->bit32.timecnt) { - tmp->trans = (int32_t *) timelib_malloc(tz->bit32.timecnt * sizeof(int32_t)); - tmp->trans_idx = (unsigned char*) timelib_malloc(tz->bit32.timecnt * sizeof(unsigned char)); - memcpy(tmp->trans, tz->trans, tz->bit32.timecnt * sizeof(int32_t)); - memcpy(tmp->trans_idx, tz->trans_idx, tz->bit32.timecnt * sizeof(unsigned char)); + tmp->_bit32.ttisgmtcnt = tz->_bit32.ttisgmtcnt; + tmp->_bit32.ttisstdcnt = tz->_bit32.ttisstdcnt; + tmp->_bit32.leapcnt = tz->_bit32.leapcnt; + tmp->_bit32.timecnt = tz->_bit32.timecnt; + tmp->_bit32.typecnt = tz->_bit32.typecnt; + tmp->_bit32.charcnt = tz->_bit32.charcnt; + tmp->bit64.ttisgmtcnt = tz->bit64.ttisgmtcnt; + tmp->bit64.ttisstdcnt = tz->bit64.ttisstdcnt; + tmp->bit64.leapcnt = tz->bit64.leapcnt; + tmp->bit64.timecnt = tz->bit64.timecnt; + tmp->bit64.typecnt = tz->bit64.typecnt; + tmp->bit64.charcnt = tz->bit64.charcnt; + + if (tz->bit64.timecnt) { + tmp->trans = (int64_t *) timelib_malloc(tz->bit64.timecnt * sizeof(int64_t)); + tmp->trans_idx = (unsigned char*) timelib_malloc(tz->bit64.timecnt * sizeof(unsigned char)); + memcpy(tmp->trans, tz->trans, tz->bit64.timecnt * sizeof(int64_t)); + memcpy(tmp->trans_idx, tz->trans_idx, tz->bit64.timecnt * sizeof(unsigned char)); } - tmp->type = (ttinfo*) timelib_malloc(tz->bit32.typecnt * sizeof(ttinfo)); - memcpy(tmp->type, tz->type, tz->bit32.typecnt * sizeof(ttinfo)); + tmp->type = (ttinfo*) timelib_malloc(tz->bit64.typecnt * sizeof(ttinfo)); + memcpy(tmp->type, tz->type, tz->bit64.typecnt * sizeof(ttinfo)); - tmp->timezone_abbr = (char*) timelib_malloc(tz->bit32.charcnt); - memcpy(tmp->timezone_abbr, tz->timezone_abbr, tz->bit32.charcnt); + tmp->timezone_abbr = (char*) timelib_malloc(tz->bit64.charcnt); + memcpy(tmp->timezone_abbr, tz->timezone_abbr, tz->bit64.charcnt); - if (tz->bit32.leapcnt) { - tmp->leap_times = (tlinfo*) timelib_malloc(tz->bit32.leapcnt * sizeof(tlinfo)); - memcpy(tmp->leap_times, tz->leap_times, tz->bit32.leapcnt * sizeof(tlinfo)); + if (tz->bit64.leapcnt) { + tmp->leap_times = (tlinfo*) timelib_malloc(tz->bit64.leapcnt * sizeof(tlinfo)); + memcpy(tmp->leap_times, tz->leap_times, tz->bit64.leapcnt * sizeof(tlinfo)); } return tmp; @@ -559,9 +606,9 @@ static ttinfo* fetch_timezone_offset(timelib_tzinfo *tz, timelib_sll ts, timelib /* If there is no transition time, we pick the first one, if that doesn't * exist we return NULL */ - if (!tz->bit32.timecnt || !tz->trans) { + if (!tz->bit64.timecnt || !tz->trans) { *transition_time = 0; - if (tz->bit32.typecnt == 1) { + if (tz->bit64.typecnt == 1) { return &(tz->type[0]); } return NULL; @@ -572,40 +619,30 @@ static ttinfo* fetch_timezone_offset(timelib_tzinfo *tz, timelib_sll ts, timelib * one in case there are only DST entries. Not sure which smartass came up * with this idea in the first though :) */ if (ts < tz->trans[0]) { - uint32_t j; - - *transition_time = 0; - j = 0; - while (j < tz->bit32.timecnt && tz->type[tz->trans_idx[j]].isdst) { - ++j; - } - if (j == tz->bit32.timecnt) { - j = 0; - } - return &(tz->type[tz->trans_idx[j]]); + return &(tz->type[0]); } /* In all other cases we loop through the available transition times to find * the correct entry */ - for (i = 0; i < tz->bit32.timecnt; i++) { + for (i = 0; i < tz->bit64.timecnt; i++) { if (ts < tz->trans[i]) { *transition_time = tz->trans[i - 1]; return &(tz->type[tz->trans_idx[i - 1]]); } } - *transition_time = tz->trans[tz->bit32.timecnt - 1]; - return &(tz->type[tz->trans_idx[tz->bit32.timecnt - 1]]); + *transition_time = tz->trans[tz->bit64.timecnt - 1]; + return &(tz->type[tz->trans_idx[tz->bit64.timecnt - 1]]); } static tlinfo* fetch_leaptime_offset(timelib_tzinfo *tz, timelib_sll ts) { int i; - if (!tz->bit32.leapcnt || !tz->leap_times) { + if (!tz->bit64.leapcnt || !tz->leap_times) { return NULL; } - for (i = tz->bit32.leapcnt - 1; i > 0; i--) { + for (i = tz->bit64.leapcnt - 1; i > 0; i--) { if (ts > tz->leap_times[i].trans) { return &(tz->leap_times[i]); } diff --git a/ext/date/lib/timelib.h b/ext/date/lib/timelib.h index 537c75a695..72f81992fc 100644 --- a/ext/date/lib/timelib.h +++ b/ext/date/lib/timelib.h @@ -153,7 +153,7 @@ typedef struct _timelib_tzinfo uint32_t timecnt; uint32_t typecnt; uint32_t charcnt; - } bit32; + } _bit32; struct { uint64_t ttisgmtcnt; uint64_t ttisstdcnt; @@ -163,7 +163,7 @@ typedef struct _timelib_tzinfo uint64_t charcnt; } bit64; - int32_t *trans; + int64_t *trans; unsigned char *trans_idx; ttinfo *type; @@ -322,8 +322,8 @@ typedef struct _timelib_tzdb { #endif #define TIMELIB_VERSION 201801 -#define TIMELIB_EXTENDED_VERSION 20180104 -#define TIMELIB_ASCII_VERSION "2018.01RC2" +#define TIMELIB_EXTENDED_VERSION 20180105 +#define TIMELIB_ASCII_VERSION "2018.01RC3" #define TIMELIB_NONE 0x00 #define TIMELIB_OVERRIDE_TIME 0x01 diff --git a/ext/date/lib/timelib_private.h b/ext/date/lib/timelib_private.h index ac75a46a28..b2116e63a2 100644 --- a/ext/date/lib/timelib_private.h +++ b/ext/date/lib/timelib_private.h @@ -123,7 +123,7 @@ struct _ttinfo struct _tlinfo { - int32_t trans; + int64_t trans; int32_t offset; }; diff --git a/ext/date/php_date.c b/ext/date/php_date.c index c152c71d3d..7b1836e938 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -4032,7 +4032,7 @@ PHP_FUNCTION(timezone_transitions_get) add_assoc_string(&element, "abbr", &tzobj->tzi.tz->timezone_abbr[tzobj->tzi.tz->type[tzobj->tzi.tz->trans_idx[i]].abbr_idx]); \ add_next_index_zval(return_value, &element); -#define add_last() add(tzobj->tzi.tz->bit32.timecnt - 1, timestamp_begin) +#define add_last() add(tzobj->tzi.tz->bit64.timecnt - 1, timestamp_begin) array_init(return_value); @@ -4043,7 +4043,7 @@ PHP_FUNCTION(timezone_transitions_get) } else { begin = 0; found = 0; - if (tzobj->tzi.tz->bit32.timecnt > 0) { + if (tzobj->tzi.tz->bit64.timecnt > 0) { do { if (tzobj->tzi.tz->trans[begin] > timestamp_begin) { if (begin > 0) { @@ -4055,19 +4055,19 @@ PHP_FUNCTION(timezone_transitions_get) break; } begin++; - } while (begin < tzobj->tzi.tz->bit32.timecnt); + } while (begin < tzobj->tzi.tz->bit64.timecnt); } } if (!found) { - if (tzobj->tzi.tz->bit32.timecnt > 0) { + if (tzobj->tzi.tz->bit64.timecnt > 0) { add_last(); } else { add_nominal(); } } else { unsigned int i; - for (i = begin; i < tzobj->tzi.tz->bit32.timecnt; ++i) { + for (i = begin; i < tzobj->tzi.tz->bit64.timecnt; ++i) { if (tzobj->tzi.tz->trans[i] < timestamp_end) { add(i, tzobj->tzi.tz->trans[i]); } |