parse_tz.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. /*
  2. * The MIT License (MIT)
  3. *
  4. * Copyright (c) 2015-2019 Derick Rethans
  5. * Copyright (c) 2018 MongoDB, Inc.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. */
  25. #include "timelib.h"
  26. #include "timelib_private.h"
  27. #define TIMELIB_SUPPORTS_V2DATA
  28. #include "timezonedb.h"
  29. #if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__))
  30. # if defined(__LITTLE_ENDIAN__)
  31. # undef WORDS_BIGENDIAN
  32. # else
  33. # if defined(__BIG_ENDIAN__)
  34. # define WORDS_BIGENDIAN
  35. # endif
  36. # endif
  37. #endif
  38. #if defined(__s390__)
  39. # if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  40. # define WORDS_BIGENDIAN
  41. # else
  42. # undef WORDS_BIGENDIAN
  43. # endif
  44. #endif
  45. #ifdef WORDS_BIGENDIAN
  46. static inline uint32_t timelib_conv_int_unsigned(uint32_t value)
  47. {
  48. return value;
  49. }
  50. static inline uint64_t timelib_conv_int64_unsigned(uint64_t value)
  51. {
  52. return value;
  53. }
  54. #else
  55. static inline uint32_t timelib_conv_int_unsigned(uint32_t value)
  56. {
  57. return
  58. ((value & 0x000000ff) << 24) +
  59. ((value & 0x0000ff00) << 8) +
  60. ((value & 0x00ff0000) >> 8) +
  61. ((value & 0xff000000) >> 24);
  62. }
  63. static inline uint64_t timelib_conv_int64_unsigned(uint64_t value)
  64. {
  65. return
  66. ((value & 0x00000000000000ff) << 56) +
  67. ((value & 0x000000000000ff00) << 40) +
  68. ((value & 0x0000000000ff0000) << 24) +
  69. ((value & 0x00000000ff000000) << 8) +
  70. ((value & 0x000000ff00000000) >> 8) +
  71. ((value & 0x0000ff0000000000) >> 24) +
  72. ((value & 0x00ff000000000000) >> 40) +
  73. ((value & 0xff00000000000000) >> 56);
  74. }
  75. #endif
  76. #define timelib_conv_int_signed(value) ((int32_t) timelib_conv_int_unsigned((int32_t) value))
  77. #define timelib_conv_int64_signed(value) ((int64_t) timelib_conv_int64_unsigned((int64_t) value))
  78. static int read_php_preamble(const unsigned char **tzf, timelib_tzinfo *tz)
  79. {
  80. uint32_t version;
  81. /* read ID */
  82. version = (*tzf)[3] - '0';
  83. *tzf += 4;
  84. /* read BC flag */
  85. tz->bc = (**tzf == '\1');
  86. *tzf += 1;
  87. /* read country code */
  88. memcpy(tz->location.country_code, *tzf, 2);
  89. tz->location.country_code[2] = '\0';
  90. *tzf += 2;
  91. /* skip rest of preamble */
  92. *tzf += 13;
  93. return version;
  94. }
  95. static int read_tzif_preamble(const unsigned char **tzf, timelib_tzinfo *tz)
  96. {
  97. uint32_t version;
  98. /* read ID */
  99. switch ((*tzf)[4]) {
  100. case '\0':
  101. version = 0;
  102. break;
  103. case '2':
  104. version = 2;
  105. break;
  106. case '3':
  107. version = 3;
  108. break;
  109. default:
  110. return -1;
  111. }
  112. *tzf += 5;
  113. /* set BC flag and country code to default */
  114. tz->bc = 0;
  115. tz->location.country_code[0] = '?';
  116. tz->location.country_code[1] = '?';
  117. tz->location.country_code[2] = '\0';
  118. /* skip rest of preamble */
  119. *tzf += 15;
  120. return version;
  121. }
  122. static int read_preamble(const unsigned char **tzf, timelib_tzinfo *tz, unsigned int *type)
  123. {
  124. /* read marker (TZif) or (PHP) */
  125. if (memcmp(*tzf, "PHP", 3) == 0) {
  126. *type = TIMELIB_TZINFO_PHP;
  127. return read_php_preamble(tzf, tz);
  128. } else if (memcmp(*tzf, "TZif", 4) == 0) {
  129. *type = TIMELIB_TZINFO_ZONEINFO;
  130. return read_tzif_preamble(tzf, tz);
  131. } else {
  132. return -1;
  133. }
  134. }
  135. static void read_32bit_header(const unsigned char **tzf, timelib_tzinfo *tz)
  136. {
  137. uint32_t buffer[6];
  138. memcpy(&buffer, *tzf, sizeof(buffer));
  139. tz->_bit32.ttisgmtcnt = timelib_conv_int_unsigned(buffer[0]);
  140. tz->_bit32.ttisstdcnt = timelib_conv_int_unsigned(buffer[1]);
  141. tz->_bit32.leapcnt = timelib_conv_int_unsigned(buffer[2]);
  142. tz->_bit32.timecnt = timelib_conv_int_unsigned(buffer[3]);
  143. tz->_bit32.typecnt = timelib_conv_int_unsigned(buffer[4]);
  144. tz->_bit32.charcnt = timelib_conv_int_unsigned(buffer[5]);
  145. *tzf += sizeof(buffer);
  146. }
  147. static int read_64bit_transitions(const unsigned char **tzf, timelib_tzinfo *tz)
  148. {
  149. int64_t *buffer = NULL;
  150. uint32_t i;
  151. unsigned char *cbuffer = NULL;
  152. if (tz->bit64.timecnt) {
  153. buffer = (int64_t*) timelib_malloc(tz->bit64.timecnt * sizeof(int64_t));
  154. if (!buffer) {
  155. return TIMELIB_ERROR_CANNOT_ALLOCATE;
  156. }
  157. memcpy(buffer, *tzf, sizeof(int64_t) * tz->bit64.timecnt);
  158. *tzf += (sizeof(int64_t) * tz->bit64.timecnt);
  159. for (i = 0; i < tz->bit64.timecnt; i++) {
  160. buffer[i] = timelib_conv_int64_signed(buffer[i]);
  161. /* Sanity check to see whether TS is just increasing */
  162. if (i > 0 && !(buffer[i] > buffer[i - 1])) {
  163. return TIMELIB_ERROR_CORRUPT_TRANSITIONS_DONT_INCREASE;
  164. }
  165. }
  166. cbuffer = (unsigned char*) timelib_malloc(tz->bit64.timecnt * sizeof(unsigned char));
  167. if (!cbuffer) {
  168. timelib_free(buffer);
  169. return TIMELIB_ERROR_CANNOT_ALLOCATE;
  170. }
  171. memcpy(cbuffer, *tzf, sizeof(unsigned char) * tz->bit64.timecnt);
  172. *tzf += sizeof(unsigned char) * tz->bit64.timecnt;
  173. }
  174. tz->trans = buffer;
  175. tz->trans_idx = cbuffer;
  176. return 0;
  177. }
  178. static void skip_32bit_transitions(const unsigned char **tzf, timelib_tzinfo *tz)
  179. {
  180. if (tz->_bit32.timecnt) {
  181. *tzf += (sizeof(int32_t) * tz->_bit32.timecnt);
  182. *tzf += sizeof(unsigned char) * tz->_bit32.timecnt;
  183. }
  184. }
  185. static int read_64bit_types(const unsigned char **tzf, timelib_tzinfo *tz)
  186. {
  187. unsigned char *buffer;
  188. int32_t *leap_buffer;
  189. unsigned int i, j;
  190. /* Offset Types */
  191. buffer = (unsigned char*) timelib_malloc(tz->bit64.typecnt * sizeof(unsigned char) * 6);
  192. if (!buffer) {
  193. return TIMELIB_ERROR_CANNOT_ALLOCATE;
  194. }
  195. memcpy(buffer, *tzf, sizeof(unsigned char) * 6 * tz->bit64.typecnt);
  196. *tzf += sizeof(unsigned char) * 6 * tz->bit64.typecnt;
  197. tz->type = (ttinfo*) timelib_malloc(tz->bit64.typecnt * sizeof(ttinfo));
  198. if (!tz->type) {
  199. timelib_free(buffer);
  200. return TIMELIB_ERROR_CANNOT_ALLOCATE;
  201. }
  202. for (i = 0; i < tz->bit64.typecnt; i++) {
  203. j = i * 6;
  204. tz->type[i].offset = 0;
  205. 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];
  206. tz->type[i].isdst = buffer[j + 4];
  207. tz->type[i].abbr_idx = buffer[j + 5];
  208. }
  209. timelib_free(buffer);
  210. /* Abbreviations */
  211. tz->timezone_abbr = (char*) timelib_malloc(tz->bit64.charcnt);
  212. if (!tz->timezone_abbr) {
  213. return TIMELIB_ERROR_CORRUPT_NO_ABBREVIATION;
  214. }
  215. memcpy(tz->timezone_abbr, *tzf, sizeof(char) * tz->bit64.charcnt);
  216. *tzf += sizeof(char) * tz->bit64.charcnt;
  217. /* Leap seconds (only use in 'right/') format */
  218. if (tz->bit64.leapcnt) {
  219. leap_buffer = (int32_t *) timelib_malloc(tz->bit64.leapcnt * (sizeof(int64_t) + sizeof(int32_t)));
  220. if (!leap_buffer) {
  221. return TIMELIB_ERROR_CANNOT_ALLOCATE;
  222. }
  223. memcpy(leap_buffer, *tzf, tz->bit64.leapcnt * (sizeof(int64_t) + sizeof(int32_t)));
  224. *tzf += tz->bit64.leapcnt * (sizeof(int64_t) + sizeof(int32_t));
  225. tz->leap_times = (tlinfo*) timelib_malloc(tz->bit64.leapcnt * sizeof(tlinfo));
  226. if (!tz->leap_times) {
  227. timelib_free(leap_buffer);
  228. return TIMELIB_ERROR_CANNOT_ALLOCATE;
  229. }
  230. for (i = 0; i < tz->bit64.leapcnt; i++) {
  231. tz->leap_times[i].trans = timelib_conv_int64_signed(leap_buffer[i * 3 + 1] * 4294967296 + leap_buffer[i * 3]);
  232. tz->leap_times[i].offset = timelib_conv_int_signed(leap_buffer[i * 3 + 2]);
  233. }
  234. timelib_free(leap_buffer);
  235. }
  236. /* Standard/Wall Indicators (unused) */
  237. if (tz->bit64.ttisstdcnt) {
  238. buffer = (unsigned char*) timelib_malloc(tz->bit64.ttisstdcnt * sizeof(unsigned char));
  239. if (!buffer) {
  240. return TIMELIB_ERROR_CANNOT_ALLOCATE;
  241. }
  242. memcpy(buffer, *tzf, sizeof(unsigned char) * tz->bit64.ttisstdcnt);
  243. *tzf += sizeof(unsigned char) * tz->bit64.ttisstdcnt;
  244. for (i = 0; i < tz->bit64.ttisstdcnt; i++) {
  245. tz->type[i].isstdcnt = buffer[i];
  246. }
  247. timelib_free(buffer);
  248. }
  249. /* UT/Local Time Indicators (unused) */
  250. if (tz->bit64.ttisgmtcnt) {
  251. buffer = (unsigned char*) timelib_malloc(tz->bit64.ttisgmtcnt * sizeof(unsigned char));
  252. if (!buffer) {
  253. return TIMELIB_ERROR_CANNOT_ALLOCATE;
  254. }
  255. memcpy(buffer, *tzf, sizeof(unsigned char) * tz->bit64.ttisgmtcnt);
  256. *tzf += sizeof(unsigned char) * tz->bit64.ttisgmtcnt;
  257. for (i = 0; i < tz->bit64.ttisgmtcnt; i++) {
  258. tz->type[i].isgmtcnt = buffer[i];
  259. }
  260. timelib_free(buffer);
  261. }
  262. return 0;
  263. }
  264. static void skip_32bit_types(const unsigned char **tzf, timelib_tzinfo *tz)
  265. {
  266. /* Offset Types */
  267. *tzf += sizeof(unsigned char) * 6 * tz->_bit32.typecnt;
  268. /* Abbreviations */
  269. *tzf += sizeof(char) * tz->_bit32.charcnt;
  270. /* Leap seconds (only use in 'right/') format */
  271. if (tz->_bit32.leapcnt) {
  272. *tzf += sizeof(int32_t) * tz->_bit32.leapcnt * 2;
  273. }
  274. /* Standard/Wall Indicators (unused) */
  275. if (tz->_bit32.ttisstdcnt) {
  276. *tzf += sizeof(unsigned char) * tz->_bit32.ttisstdcnt;
  277. }
  278. /* UT/Local Time Indicators (unused) */
  279. if (tz->_bit32.ttisgmtcnt) {
  280. *tzf += sizeof(unsigned char) * tz->_bit32.ttisgmtcnt;
  281. }
  282. }
  283. static void skip_posix_string(const unsigned char **tzf, timelib_tzinfo *tz)
  284. {
  285. int n_count = 0;
  286. do {
  287. if (*tzf[0] == '\n') {
  288. n_count++;
  289. }
  290. (*tzf)++;
  291. } while (n_count < 2);
  292. }
  293. static void read_location(const unsigned char **tzf, timelib_tzinfo *tz)
  294. {
  295. uint32_t buffer[3];
  296. uint32_t comments_len;
  297. memcpy(&buffer, *tzf, sizeof(buffer));
  298. tz->location.latitude = timelib_conv_int_unsigned(buffer[0]);
  299. tz->location.latitude = (tz->location.latitude / 100000) - 90;
  300. tz->location.longitude = timelib_conv_int_unsigned(buffer[1]);
  301. tz->location.longitude = (tz->location.longitude / 100000) - 180;
  302. comments_len = timelib_conv_int_unsigned(buffer[2]);
  303. *tzf += sizeof(buffer);
  304. tz->location.comments = timelib_malloc(comments_len + 1);
  305. memcpy(tz->location.comments, *tzf, comments_len);
  306. tz->location.comments[comments_len] = '\0';
  307. *tzf += comments_len;
  308. }
  309. static void set_default_location_and_comments(const unsigned char **tzf, timelib_tzinfo *tz)
  310. {
  311. tz->location.latitude = 0;
  312. tz->location.longitude = 0;
  313. tz->location.comments = timelib_malloc(2);
  314. tz->location.comments[0] = '?';
  315. tz->location.comments[1] = '\0';
  316. }
  317. void timelib_dump_tzinfo(timelib_tzinfo *tz)
  318. {
  319. uint32_t i;
  320. printf("Country Code: %s\n", tz->location.country_code);
  321. printf("Geo Location: %f,%f\n", tz->location.latitude, tz->location.longitude);
  322. printf("Comments:\n%s\n", tz->location.comments);
  323. printf("BC: %s\n", tz->bc ? "" : "yes");
  324. printf("\n64-bit:\n");
  325. printf("UTC/Local count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit64.ttisgmtcnt);
  326. printf("Std/Wall count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit64.ttisstdcnt);
  327. printf("Leap.sec. count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit64.leapcnt);
  328. printf("Trans. count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit64.timecnt);
  329. printf("Local types count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit64.typecnt);
  330. printf("Zone Abbr. count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit64.charcnt);
  331. printf ("%16s (%20s) = %3d [%5ld %1d %3d '%s' (%d,%d)]\n",
  332. "", "", 0,
  333. (long int) tz->type[0].offset,
  334. tz->type[0].isdst,
  335. tz->type[0].abbr_idx,
  336. &tz->timezone_abbr[tz->type[0].abbr_idx],
  337. tz->type[0].isstdcnt,
  338. tz->type[0].isgmtcnt
  339. );
  340. for (i = 0; i < tz->bit64.timecnt; i++) {
  341. printf ("%016" PRIX64 " (%20" PRId64 ") = %3d [%5ld %1d %3d '%s' (%d,%d)]\n",
  342. tz->trans[i], tz->trans[i], tz->trans_idx[i],
  343. (long int) tz->type[tz->trans_idx[i]].offset,
  344. tz->type[tz->trans_idx[i]].isdst,
  345. tz->type[tz->trans_idx[i]].abbr_idx,
  346. &tz->timezone_abbr[tz->type[tz->trans_idx[i]].abbr_idx],
  347. tz->type[tz->trans_idx[i]].isstdcnt,
  348. tz->type[tz->trans_idx[i]].isgmtcnt
  349. );
  350. }
  351. for (i = 0; i < tz->bit64.leapcnt; i++) {
  352. printf ("%016" PRIX64 " (%20ld) = %d\n",
  353. tz->leap_times[i].trans,
  354. (long) tz->leap_times[i].trans,
  355. tz->leap_times[i].offset);
  356. }
  357. }
  358. static int seek_to_tz_position(const unsigned char **tzf, char *timezone, const timelib_tzdb *tzdb)
  359. {
  360. int left = 0, right = tzdb->index_size - 1;
  361. if (tzdb->index_size == 0) {
  362. return 0;
  363. }
  364. do {
  365. int mid = ((unsigned)left + right) >> 1;
  366. int cmp = timelib_strcasecmp(timezone, tzdb->index[mid].id);
  367. if (cmp < 0) {
  368. right = mid - 1;
  369. } else if (cmp > 0) {
  370. left = mid + 1;
  371. } else { /* (cmp == 0) */
  372. (*tzf) = &(tzdb->data[tzdb->index[mid].pos]);
  373. return 1;
  374. }
  375. } while (left <= right);
  376. return 0;
  377. }
  378. const timelib_tzdb *timelib_builtin_db(void)
  379. {
  380. return &timezonedb_builtin;
  381. }
  382. const timelib_tzdb_index_entry *timelib_timezone_identifiers_list(const timelib_tzdb *tzdb, int *count)
  383. {
  384. *count = tzdb->index_size;
  385. return tzdb->index;
  386. }
  387. int timelib_timezone_id_is_valid(char *timezone, const timelib_tzdb *tzdb)
  388. {
  389. const unsigned char *tzf;
  390. return (seek_to_tz_position(&tzf, timezone, tzdb));
  391. }
  392. static int skip_64bit_preamble(const unsigned char **tzf, timelib_tzinfo *tz)
  393. {
  394. if (memcmp(*tzf, "TZif2", 5) == 0) {
  395. *tzf += 20;
  396. return 1;
  397. } else if (memcmp(*tzf, "TZif3", 5) == 0) {
  398. *tzf += 20;
  399. return 1;
  400. } else {
  401. return 0;
  402. }
  403. }
  404. static void read_64bit_header(const unsigned char **tzf, timelib_tzinfo *tz)
  405. {
  406. uint32_t buffer[6];
  407. memcpy(&buffer, *tzf, sizeof(buffer));
  408. tz->bit64.ttisgmtcnt = timelib_conv_int_unsigned(buffer[0]);
  409. tz->bit64.ttisstdcnt = timelib_conv_int_unsigned(buffer[1]);
  410. tz->bit64.leapcnt = timelib_conv_int_unsigned(buffer[2]);
  411. tz->bit64.timecnt = timelib_conv_int_unsigned(buffer[3]);
  412. tz->bit64.typecnt = timelib_conv_int_unsigned(buffer[4]);
  413. tz->bit64.charcnt = timelib_conv_int_unsigned(buffer[5]);
  414. *tzf += sizeof(buffer);
  415. }
  416. static timelib_tzinfo* timelib_tzinfo_ctor(char *name)
  417. {
  418. timelib_tzinfo *t;
  419. t = timelib_calloc(1, sizeof(timelib_tzinfo));
  420. t->name = timelib_strdup(name);
  421. return t;
  422. }
  423. timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb, int *error_code)
  424. {
  425. const unsigned char *tzf;
  426. timelib_tzinfo *tmp;
  427. int version;
  428. int transitions_result, types_result;
  429. unsigned int type; /* TIMELIB_TZINFO_PHP or TIMELIB_TZINFO_ZONEINFO */
  430. if (seek_to_tz_position(&tzf, timezone, tzdb)) {
  431. tmp = timelib_tzinfo_ctor(timezone);
  432. version = read_preamble(&tzf, tmp, &type);
  433. if (version < 2 || version > 3) {
  434. *error_code = TIMELIB_ERROR_UNSUPPORTED_VERSION;
  435. timelib_tzinfo_dtor(tmp);
  436. return NULL;
  437. }
  438. //printf("- timezone: %s, version: %0d\n", timezone, version);
  439. read_32bit_header(&tzf, tmp);
  440. skip_32bit_transitions(&tzf, tmp);
  441. skip_32bit_types(&tzf, tmp);
  442. if (!skip_64bit_preamble(&tzf, tmp)) {
  443. /* 64 bit preamble is not in place */
  444. *error_code = TIMELIB_ERROR_CORRUPT_NO_64BIT_PREAMBLE;
  445. timelib_tzinfo_dtor(tmp);
  446. return NULL;
  447. }
  448. read_64bit_header(&tzf, tmp);
  449. if ((transitions_result = read_64bit_transitions(&tzf, tmp)) != 0) {
  450. /* Corrupt file as transitions do not increase */
  451. *error_code = transitions_result;
  452. timelib_tzinfo_dtor(tmp);
  453. return NULL;
  454. }
  455. if ((types_result = read_64bit_types(&tzf, tmp)) != 0) {
  456. *error_code = types_result;
  457. timelib_tzinfo_dtor(tmp);
  458. return NULL;
  459. }
  460. skip_posix_string(&tzf, tmp);
  461. if (type == TIMELIB_TZINFO_PHP) {
  462. read_location(&tzf, tmp);
  463. } else {
  464. set_default_location_and_comments(&tzf, tmp);
  465. }
  466. } else {
  467. *error_code = TIMELIB_ERROR_NO_SUCH_TIMEZONE;
  468. tmp = NULL;
  469. }
  470. return tmp;
  471. }
  472. void timelib_tzinfo_dtor(timelib_tzinfo *tz)
  473. {
  474. TIMELIB_TIME_FREE(tz->name);
  475. TIMELIB_TIME_FREE(tz->trans);
  476. TIMELIB_TIME_FREE(tz->trans_idx);
  477. TIMELIB_TIME_FREE(tz->type);
  478. TIMELIB_TIME_FREE(tz->timezone_abbr);
  479. TIMELIB_TIME_FREE(tz->leap_times);
  480. TIMELIB_TIME_FREE(tz->location.comments);
  481. TIMELIB_TIME_FREE(tz);
  482. tz = NULL;
  483. }
  484. timelib_tzinfo *timelib_tzinfo_clone(timelib_tzinfo *tz)
  485. {
  486. timelib_tzinfo *tmp = timelib_tzinfo_ctor(tz->name);
  487. tmp->_bit32.ttisgmtcnt = tz->_bit32.ttisgmtcnt;
  488. tmp->_bit32.ttisstdcnt = tz->_bit32.ttisstdcnt;
  489. tmp->_bit32.leapcnt = tz->_bit32.leapcnt;
  490. tmp->_bit32.timecnt = tz->_bit32.timecnt;
  491. tmp->_bit32.typecnt = tz->_bit32.typecnt;
  492. tmp->_bit32.charcnt = tz->_bit32.charcnt;
  493. tmp->bit64.ttisgmtcnt = tz->bit64.ttisgmtcnt;
  494. tmp->bit64.ttisstdcnt = tz->bit64.ttisstdcnt;
  495. tmp->bit64.leapcnt = tz->bit64.leapcnt;
  496. tmp->bit64.timecnt = tz->bit64.timecnt;
  497. tmp->bit64.typecnt = tz->bit64.typecnt;
  498. tmp->bit64.charcnt = tz->bit64.charcnt;
  499. if (tz->bit64.timecnt) {
  500. tmp->trans = (int64_t *) timelib_malloc(tz->bit64.timecnt * sizeof(int64_t));
  501. tmp->trans_idx = (unsigned char*) timelib_malloc(tz->bit64.timecnt * sizeof(unsigned char));
  502. memcpy(tmp->trans, tz->trans, tz->bit64.timecnt * sizeof(int64_t));
  503. memcpy(tmp->trans_idx, tz->trans_idx, tz->bit64.timecnt * sizeof(unsigned char));
  504. }
  505. tmp->type = (ttinfo*) timelib_malloc(tz->bit64.typecnt * sizeof(ttinfo));
  506. memcpy(tmp->type, tz->type, tz->bit64.typecnt * sizeof(ttinfo));
  507. tmp->timezone_abbr = (char*) timelib_malloc(tz->bit64.charcnt);
  508. memcpy(tmp->timezone_abbr, tz->timezone_abbr, tz->bit64.charcnt);
  509. if (tz->bit64.leapcnt) {
  510. tmp->leap_times = (tlinfo*) timelib_malloc(tz->bit64.leapcnt * sizeof(tlinfo));
  511. memcpy(tmp->leap_times, tz->leap_times, tz->bit64.leapcnt * sizeof(tlinfo));
  512. }
  513. return tmp;
  514. }
  515. static ttinfo* fetch_timezone_offset(timelib_tzinfo *tz, timelib_sll ts, timelib_sll *transition_time)
  516. {
  517. uint32_t i;
  518. /* If there is no transition time, we pick the first one, if that doesn't
  519. * exist we return NULL */
  520. if (!tz->bit64.timecnt || !tz->trans) {
  521. if (tz->bit64.typecnt == 1) {
  522. *transition_time = INT64_MIN;
  523. return &(tz->type[0]);
  524. }
  525. return NULL;
  526. }
  527. /* If the TS is lower than the first transition time, then we scan over
  528. * all the transition times to find the first non-DST one, or the first
  529. * one in case there are only DST entries. Not sure which smartass came up
  530. * with this idea in the first though :) */
  531. if (ts < tz->trans[0]) {
  532. *transition_time = INT64_MIN;
  533. return &(tz->type[0]);
  534. }
  535. /* In all other cases we loop through the available transition times to find
  536. * the correct entry */
  537. for (i = 0; i < tz->bit64.timecnt; i++) {
  538. if (ts < tz->trans[i]) {
  539. *transition_time = tz->trans[i - 1];
  540. return &(tz->type[tz->trans_idx[i - 1]]);
  541. }
  542. }
  543. *transition_time = tz->trans[tz->bit64.timecnt - 1];
  544. return &(tz->type[tz->trans_idx[tz->bit64.timecnt - 1]]);
  545. }
  546. static tlinfo* fetch_leaptime_offset(timelib_tzinfo *tz, timelib_sll ts)
  547. {
  548. int i;
  549. if (!tz->bit64.leapcnt || !tz->leap_times) {
  550. return NULL;
  551. }
  552. for (i = tz->bit64.leapcnt - 1; i > 0; i--) {
  553. if (ts > tz->leap_times[i].trans) {
  554. return &(tz->leap_times[i]);
  555. }
  556. }
  557. return NULL;
  558. }
  559. int timelib_timestamp_is_in_dst(timelib_sll ts, timelib_tzinfo *tz)
  560. {
  561. ttinfo *to;
  562. timelib_sll dummy;
  563. if ((to = fetch_timezone_offset(tz, ts, &dummy))) {
  564. return to->isdst;
  565. }
  566. return -1;
  567. }
  568. timelib_time_offset *timelib_get_time_zone_info(timelib_sll ts, timelib_tzinfo *tz)
  569. {
  570. ttinfo *to;
  571. tlinfo *tl;
  572. int32_t offset = 0, leap_secs = 0;
  573. char *abbr;
  574. timelib_time_offset *tmp = timelib_time_offset_ctor();
  575. timelib_sll transition_time;
  576. if ((to = fetch_timezone_offset(tz, ts, &transition_time))) {
  577. offset = to->offset;
  578. abbr = &(tz->timezone_abbr[to->abbr_idx]);
  579. tmp->is_dst = to->isdst;
  580. tmp->transition_time = transition_time;
  581. } else {
  582. offset = 0;
  583. abbr = tz->timezone_abbr;
  584. tmp->is_dst = 0;
  585. tmp->transition_time = 0;
  586. }
  587. if ((tl = fetch_leaptime_offset(tz, ts))) {
  588. leap_secs = -tl->offset;
  589. }
  590. tmp->offset = offset;
  591. tmp->leap_secs = leap_secs;
  592. tmp->abbr = abbr ? timelib_strdup(abbr) : timelib_strdup("GMT");
  593. return tmp;
  594. }
  595. timelib_sll timelib_get_current_offset(timelib_time *t)
  596. {
  597. timelib_time_offset *gmt_offset;
  598. timelib_sll retval;
  599. switch (t->zone_type) {
  600. case TIMELIB_ZONETYPE_ABBR:
  601. case TIMELIB_ZONETYPE_OFFSET:
  602. return t->z + (t->dst * 3600);
  603. case TIMELIB_ZONETYPE_ID:
  604. gmt_offset = timelib_get_time_zone_info(t->sse, t->tz_info);
  605. retval = gmt_offset->offset;
  606. timelib_time_offset_dtor(gmt_offset);
  607. return retval;
  608. default:
  609. return 0;
  610. }
  611. }