tz.cpp 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636
  1. // SPDX-FileCopyrightText: 2023 yuzu Emulator Project
  2. // SPDX-FileCopyrightText: 1996 Arthur David Olson
  3. // SPDX-License-Identifier: BSD-2-Clause
  4. #include <climits>
  5. #include <cstring>
  6. #include <ctime>
  7. #include "tz.h"
  8. namespace Tz {
  9. namespace {
  10. #define EINVAL 22
  11. static Rule gmtmem{};
  12. static Rule* const gmtptr = &gmtmem;
  13. struct TzifHeader {
  14. std::array<char, 4> tzh_magic; // "TZif"
  15. std::array<char, 1> tzh_version;
  16. std::array<char, 15> tzh_reserved;
  17. std::array<char, 4> tzh_ttisutcnt;
  18. std::array<char, 4> tzh_ttisstdcnt;
  19. std::array<char, 4> tzh_leapcnt;
  20. std::array<char, 4> tzh_timecnt;
  21. std::array<char, 4> tzh_typecnt;
  22. std::array<char, 4> tzh_charcnt;
  23. };
  24. static_assert(sizeof(TzifHeader) == 0x2C, "TzifHeader has the wrong size!");
  25. struct local_storage {
  26. // Binary layout:
  27. // char buf[2 * sizeof(TzifHeader) + 2 * sizeof(Rule) + 4 * TZ_MAX_TIMES];
  28. std::span<const u8> binary;
  29. Rule state;
  30. };
  31. static local_storage tzloadbody_local_storage;
  32. enum rtype : s32 {
  33. JULIAN_DAY = 0,
  34. DAY_OF_YEAR = 1,
  35. MONTH_NTH_DAY_OF_WEEK = 2,
  36. };
  37. struct tzrule {
  38. rtype r_type;
  39. int r_day;
  40. int r_week;
  41. int r_mon;
  42. s64 r_time;
  43. };
  44. static_assert(sizeof(tzrule) == 0x18, "tzrule has the wrong size!");
  45. constexpr static char UNSPEC[] = "-00";
  46. constexpr static char TZDEFRULESTRING[] = ",M3.2.0,M11.1.0";
  47. enum {
  48. SECSPERMIN = 60,
  49. MINSPERHOUR = 60,
  50. SECSPERHOUR = SECSPERMIN * MINSPERHOUR,
  51. HOURSPERDAY = 24,
  52. DAYSPERWEEK = 7,
  53. DAYSPERNYEAR = 365,
  54. DAYSPERLYEAR = DAYSPERNYEAR + 1,
  55. MONSPERYEAR = 12,
  56. YEARSPERREPEAT = 400 /* years before a Gregorian repeat */
  57. };
  58. #define SECSPERDAY ((s64)SECSPERHOUR * HOURSPERDAY)
  59. #define DAYSPERREPEAT ((s64)400 * 365 + 100 - 4 + 1)
  60. #define SECSPERREPEAT ((int_fast64_t)DAYSPERREPEAT * SECSPERDAY)
  61. #define AVGSECSPERYEAR (SECSPERREPEAT / YEARSPERREPEAT)
  62. enum {
  63. TM_SUNDAY,
  64. TM_MONDAY,
  65. TM_TUESDAY,
  66. TM_WEDNESDAY,
  67. TM_THURSDAY,
  68. TM_FRIDAY,
  69. TM_SATURDAY,
  70. };
  71. enum {
  72. TM_JANUARY,
  73. TM_FEBRUARY,
  74. TM_MARCH,
  75. TM_APRIL,
  76. TM_MAY,
  77. TM_JUNE,
  78. TM_JULY,
  79. TM_AUGUST,
  80. TM_SEPTEMBER,
  81. TM_OCTOBER,
  82. TM_NOVEMBER,
  83. TM_DECEMBER,
  84. };
  85. constexpr s32 TM_YEAR_BASE = 1900;
  86. constexpr s32 TM_WDAY_BASE = TM_MONDAY;
  87. constexpr s32 EPOCH_YEAR = 1970;
  88. constexpr s32 EPOCH_WDAY = TM_THURSDAY;
  89. #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
  90. static constexpr std::array<std::array<int, MONSPERYEAR>, 2> mon_lengths = { {
  91. {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
  92. {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
  93. } };
  94. static constexpr std::array<int, 2> year_lengths = {
  95. DAYSPERNYEAR,
  96. DAYSPERLYEAR,
  97. };
  98. constexpr static time_t leaps_thru_end_of_nonneg(time_t y) {
  99. return y / 4 - y / 100 + y / 400;
  100. }
  101. constexpr static time_t leaps_thru_end_of(time_t y) {
  102. return (y < 0 ? -1 - leaps_thru_end_of_nonneg(-1 - y) : leaps_thru_end_of_nonneg(y));
  103. }
  104. #define TWOS_COMPLEMENT(t) ((t) ~(t)0 < 0)
  105. s32 detzcode(const char* const codep) {
  106. s32 result;
  107. int i;
  108. s32 one = 1;
  109. s32 halfmaxval = one << (32 - 2);
  110. s32 maxval = halfmaxval - 1 + halfmaxval;
  111. s32 minval = -1 - maxval;
  112. result = codep[0] & 0x7f;
  113. for (i = 1; i < 4; ++i) {
  114. result = (result << 8) | (codep[i] & 0xff);
  115. }
  116. if (codep[0] & 0x80) {
  117. /* Do two's-complement negation even on non-two's-complement machines.
  118. If the result would be minval - 1, return minval. */
  119. result -= !TWOS_COMPLEMENT(s32) && result != 0;
  120. result += minval;
  121. }
  122. return result;
  123. }
  124. int_fast64_t detzcode64(const char* const codep) {
  125. int_fast64_t result;
  126. int i;
  127. int_fast64_t one = 1;
  128. int_fast64_t halfmaxval = one << (64 - 2);
  129. int_fast64_t maxval = halfmaxval - 1 + halfmaxval;
  130. int_fast64_t minval = -static_cast<int_fast64_t>(TWOS_COMPLEMENT(int_fast64_t)) - maxval;
  131. result = codep[0] & 0x7f;
  132. for (i = 1; i < 8; ++i) {
  133. result = (result << 8) | (codep[i] & 0xff);
  134. }
  135. if (codep[0] & 0x80) {
  136. /* Do two's-complement negation even on non-two's-complement machines.
  137. If the result would be minval - 1, return minval. */
  138. result -= !TWOS_COMPLEMENT(int_fast64_t) && result != 0;
  139. result += minval;
  140. }
  141. return result;
  142. }
  143. /* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */
  144. constexpr void init_ttinfo(ttinfo* s, s64 utoff, bool isdst, int desigidx) {
  145. s->tt_utoff = static_cast<s32>(utoff);
  146. s->tt_isdst = isdst;
  147. s->tt_desigidx = desigidx;
  148. s->tt_ttisstd = false;
  149. s->tt_ttisut = false;
  150. }
  151. /* Return true if SP's time type I does not specify local time. */
  152. bool ttunspecified(struct Rule const* sp, int i) {
  153. char const* abbr = &sp->chars[sp->ttis[i].tt_desigidx];
  154. /* memcmp is likely faster than strcmp, and is safe due to CHARS_EXTRA. */
  155. return memcmp(abbr, UNSPEC, sizeof(UNSPEC)) == 0;
  156. }
  157. bool typesequiv(const Rule* sp, int a, int b) {
  158. bool result;
  159. if (sp == nullptr || a < 0 || a >= sp->typecnt || b < 0 || b >= sp->typecnt) {
  160. result = false;
  161. }
  162. else {
  163. /* Compare the relevant members of *AP and *BP.
  164. Ignore tt_ttisstd and tt_ttisut, as they are
  165. irrelevant now and counting them could cause
  166. sp->goahead to mistakenly remain false. */
  167. const ttinfo* ap = &sp->ttis[a];
  168. const ttinfo* bp = &sp->ttis[b];
  169. result = (ap->tt_utoff == bp->tt_utoff && ap->tt_isdst == bp->tt_isdst &&
  170. (strcmp(&sp->chars[ap->tt_desigidx], &sp->chars[bp->tt_desigidx]) == 0));
  171. }
  172. return result;
  173. }
  174. constexpr const char* getqzname(const char* strp, const int delim) {
  175. int c;
  176. while ((c = *strp) != '\0' && c != delim) {
  177. ++strp;
  178. }
  179. return strp;
  180. }
  181. /* Is C an ASCII digit? */
  182. constexpr bool is_digit(char c) {
  183. return '0' <= c && c <= '9';
  184. }
  185. /*
  186. ** Given a pointer into a timezone string, scan until a character that is not
  187. ** a valid character in a time zone abbreviation is found.
  188. ** Return a pointer to that character.
  189. */
  190. constexpr const char* getzname(const char* strp) {
  191. char c;
  192. while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && c != '+') {
  193. ++strp;
  194. }
  195. return strp;
  196. }
  197. static const char* getnum(const char* strp, int* const nump, const int min, const int max) {
  198. char c;
  199. int num;
  200. if (strp == nullptr || !is_digit(c = *strp)) {
  201. return nullptr;
  202. }
  203. num = 0;
  204. do {
  205. num = num * 10 + (c - '0');
  206. if (num > max) {
  207. return nullptr; /* illegal value */
  208. }
  209. c = *++strp;
  210. } while (is_digit(c));
  211. if (num < min) {
  212. return nullptr; /* illegal value */
  213. }
  214. *nump = num;
  215. return strp;
  216. }
  217. /*
  218. ** Given a pointer into a timezone string, extract a number of seconds,
  219. ** in hh[:mm[:ss]] form, from the string.
  220. ** If any error occurs, return NULL.
  221. ** Otherwise, return a pointer to the first character not part of the number
  222. ** of seconds.
  223. */
  224. const char* getsecs(const char* strp, s64* const secsp) {
  225. int num;
  226. s64 secsperhour = SECSPERHOUR;
  227. /*
  228. ** 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
  229. ** "M10.4.6/26", which does not conform to Posix,
  230. ** but which specifies the equivalent of
  231. ** "02:00 on the first Sunday on or after 23 Oct".
  232. */
  233. strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
  234. if (strp == nullptr) {
  235. return nullptr;
  236. }
  237. *secsp = num * secsperhour;
  238. if (*strp == ':') {
  239. ++strp;
  240. strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
  241. if (strp == nullptr) {
  242. return nullptr;
  243. }
  244. *secsp += num * SECSPERMIN;
  245. if (*strp == ':') {
  246. ++strp;
  247. /* 'SECSPERMIN' allows for leap seconds. */
  248. strp = getnum(strp, &num, 0, SECSPERMIN);
  249. if (strp == nullptr) {
  250. return nullptr;
  251. }
  252. *secsp += num;
  253. }
  254. }
  255. return strp;
  256. }
  257. /*
  258. ** Given a pointer into a timezone string, extract an offset, in
  259. ** [+-]hh[:mm[:ss]] form, from the string.
  260. ** If any error occurs, return NULL.
  261. ** Otherwise, return a pointer to the first character not part of the time.
  262. */
  263. const char* getoffset(const char* strp, s64* const offsetp) {
  264. bool neg = false;
  265. if (*strp == '-') {
  266. neg = true;
  267. ++strp;
  268. }
  269. else if (*strp == '+') {
  270. ++strp;
  271. }
  272. strp = getsecs(strp, offsetp);
  273. if (strp == nullptr) {
  274. return nullptr; /* illegal time */
  275. }
  276. if (neg) {
  277. *offsetp = -*offsetp;
  278. }
  279. return strp;
  280. }
  281. constexpr const char* getrule(const char* strp, tzrule* const rulep) {
  282. if (*strp == 'J') {
  283. /*
  284. ** Julian day.
  285. */
  286. rulep->r_type = JULIAN_DAY;
  287. ++strp;
  288. strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
  289. }
  290. else if (*strp == 'M') {
  291. /*
  292. ** Month, week, day.
  293. */
  294. rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
  295. ++strp;
  296. strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
  297. if (strp == nullptr) {
  298. return nullptr;
  299. }
  300. if (*strp++ != '.') {
  301. return nullptr;
  302. }
  303. strp = getnum(strp, &rulep->r_week, 1, 5);
  304. if (strp == nullptr) {
  305. return nullptr;
  306. }
  307. if (*strp++ != '.') {
  308. return nullptr;
  309. }
  310. strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
  311. }
  312. else if (is_digit(*strp)) {
  313. /*
  314. ** Day of year.
  315. */
  316. rulep->r_type = DAY_OF_YEAR;
  317. strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
  318. }
  319. else {
  320. return nullptr;
  321. } /* invalid format */
  322. if (strp == nullptr) {
  323. return nullptr;
  324. }
  325. if (*strp == '/') {
  326. /*
  327. ** Time specified.
  328. */
  329. ++strp;
  330. strp = getoffset(strp, &rulep->r_time);
  331. }
  332. else {
  333. rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
  334. }
  335. return strp;
  336. }
  337. constexpr bool increment_overflow(int* ip, int j) {
  338. int const i = *ip;
  339. /*
  340. ** If i >= 0 there can only be overflow if i + j > INT_MAX
  341. ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
  342. ** If i < 0 there can only be overflow if i + j < INT_MIN
  343. ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
  344. */
  345. if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i)) {
  346. return true;
  347. }
  348. *ip += j;
  349. return false;
  350. }
  351. constexpr bool increment_overflow32(s64* const lp, int const m) {
  352. s64 const l = *lp;
  353. if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
  354. return true;
  355. *lp += m;
  356. return false;
  357. }
  358. constexpr bool increment_overflow_time(time_t* tp, s64 j) {
  359. /*
  360. ** This is like
  361. ** 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...',
  362. ** except that it does the right thing even if *tp + j would overflow.
  363. */
  364. if (!(j < 0 ? (std::is_signed_v<time_t> ? TIME_T_MIN - j <= *tp : -1 - j < *tp)
  365. : *tp <= TIME_T_MAX - j)) {
  366. return true;
  367. }
  368. *tp += j;
  369. return false;
  370. }
  371. CalendarTimeInternal* timesub(const time_t* timep, s64 offset, const Rule* sp,
  372. CalendarTimeInternal* tmp) {
  373. time_t tdays;
  374. const int* ip;
  375. s64 idays, rem, dayoff, dayrem;
  376. time_t y;
  377. /* Calculate the year, avoiding integer overflow even if
  378. time_t is unsigned. */
  379. tdays = *timep / SECSPERDAY;
  380. rem = *timep % SECSPERDAY;
  381. rem += offset % SECSPERDAY + 3 * SECSPERDAY;
  382. dayoff = offset / SECSPERDAY + rem / SECSPERDAY - 3;
  383. rem %= SECSPERDAY;
  384. /* y = (EPOCH_YEAR
  385. + floor((tdays + dayoff) / DAYSPERREPEAT) * YEARSPERREPEAT),
  386. sans overflow. But calculate against 1570 (EPOCH_YEAR -
  387. YEARSPERREPEAT) instead of against 1970 so that things work
  388. for localtime values before 1970 when time_t is unsigned. */
  389. dayrem = tdays % DAYSPERREPEAT;
  390. dayrem += dayoff % DAYSPERREPEAT;
  391. y = (EPOCH_YEAR - YEARSPERREPEAT +
  392. ((1ull + dayoff / DAYSPERREPEAT + dayrem / DAYSPERREPEAT - ((dayrem % DAYSPERREPEAT) < 0) +
  393. tdays / DAYSPERREPEAT) *
  394. YEARSPERREPEAT));
  395. /* idays = (tdays + dayoff) mod DAYSPERREPEAT, sans overflow. */
  396. idays = tdays % DAYSPERREPEAT;
  397. idays += dayoff % DAYSPERREPEAT + 2 * DAYSPERREPEAT;
  398. idays %= DAYSPERREPEAT;
  399. /* Increase Y and decrease IDAYS until IDAYS is in range for Y. */
  400. while (year_lengths[isleap(y)] <= idays) {
  401. s64 tdelta = idays / DAYSPERLYEAR;
  402. s64 ydelta = tdelta + !tdelta;
  403. time_t newy = y + ydelta;
  404. int leapdays;
  405. leapdays = static_cast<s32>(leaps_thru_end_of(newy - 1) - leaps_thru_end_of(y - 1));
  406. idays -= ydelta * DAYSPERNYEAR;
  407. idays -= leapdays;
  408. y = newy;
  409. }
  410. if constexpr (!std::is_signed_v<time_t> && y < TM_YEAR_BASE) {
  411. int signed_y = static_cast<s32>(y);
  412. tmp->tm_year = signed_y - TM_YEAR_BASE;
  413. }
  414. else if ((!std::is_signed_v<time_t> || std::numeric_limits<s32>::min() + TM_YEAR_BASE <= y) &&
  415. y - TM_YEAR_BASE <= std::numeric_limits<s32>::max()) {
  416. tmp->tm_year = static_cast<s32>(y - TM_YEAR_BASE);
  417. }
  418. else {
  419. // errno = EOVERFLOW;
  420. return nullptr;
  421. }
  422. tmp->tm_yday = static_cast<s32>(idays);
  423. /*
  424. ** The "extra" mods below avoid overflow problems.
  425. */
  426. tmp->tm_wday = static_cast<s32>(
  427. TM_WDAY_BASE + ((tmp->tm_year % DAYSPERWEEK) * (DAYSPERNYEAR % DAYSPERWEEK)) +
  428. leaps_thru_end_of(y - 1) - leaps_thru_end_of(TM_YEAR_BASE - 1) + idays);
  429. tmp->tm_wday %= DAYSPERWEEK;
  430. if (tmp->tm_wday < 0) {
  431. tmp->tm_wday += DAYSPERWEEK;
  432. }
  433. tmp->tm_hour = static_cast<s32>(rem / SECSPERHOUR);
  434. rem %= SECSPERHOUR;
  435. tmp->tm_min = static_cast<s32>(rem / SECSPERMIN);
  436. tmp->tm_sec = static_cast<s32>(rem % SECSPERMIN);
  437. ip = mon_lengths[isleap(y)].data();
  438. for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) {
  439. idays -= ip[tmp->tm_mon];
  440. }
  441. tmp->tm_mday = static_cast<s32>(idays + 1);
  442. tmp->tm_isdst = 0;
  443. return tmp;
  444. }
  445. CalendarTimeInternal* gmtsub([[maybe_unused]] Rule const* sp, time_t const* timep,
  446. s64 offset, CalendarTimeInternal* tmp) {
  447. CalendarTimeInternal* result;
  448. result = timesub(timep, offset, gmtptr, tmp);
  449. return result;
  450. }
  451. CalendarTimeInternal* localsub(Rule const* sp, time_t const* timep, s64 setname,
  452. CalendarTimeInternal* const tmp) {
  453. const ttinfo* ttisp;
  454. int i;
  455. CalendarTimeInternal* result;
  456. const time_t t = *timep;
  457. if (sp == nullptr) {
  458. /* Don't bother to set tzname etc.; tzset has already done it. */
  459. return gmtsub(gmtptr, timep, 0, tmp);
  460. }
  461. if ((sp->goback && t < sp->ats[0]) || (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
  462. time_t newt;
  463. time_t seconds;
  464. time_t years;
  465. if (t < sp->ats[0]) {
  466. seconds = sp->ats[0] - t;
  467. }
  468. else {
  469. seconds = t - sp->ats[sp->timecnt - 1];
  470. }
  471. --seconds;
  472. /* Beware integer overflow, as SECONDS might
  473. be close to the maximum time_t. */
  474. years = seconds / SECSPERREPEAT * YEARSPERREPEAT;
  475. seconds = years * AVGSECSPERYEAR;
  476. years += YEARSPERREPEAT;
  477. if (t < sp->ats[0]) {
  478. newt = t + seconds + SECSPERREPEAT;
  479. }
  480. else {
  481. newt = t - seconds - SECSPERREPEAT;
  482. }
  483. if (newt < sp->ats[0] || newt > sp->ats[sp->timecnt - 1]) {
  484. return nullptr; /* "cannot happen" */
  485. }
  486. result = localsub(sp, &newt, setname, tmp);
  487. if (result) {
  488. int_fast64_t newy;
  489. newy = result->tm_year;
  490. if (t < sp->ats[0]) {
  491. newy -= years;
  492. }
  493. else {
  494. newy += years;
  495. }
  496. if (!(std::numeric_limits<s32>::min() <= newy &&
  497. newy <= std::numeric_limits<s32>::max())) {
  498. return nullptr;
  499. }
  500. result->tm_year = static_cast<s32>(newy);
  501. }
  502. return result;
  503. }
  504. if (sp->timecnt == 0 || t < sp->ats[0]) {
  505. i = sp->defaulttype;
  506. }
  507. else {
  508. int lo = 1;
  509. int hi = sp->timecnt;
  510. while (lo < hi) {
  511. int mid = (lo + hi) >> 1;
  512. if (t < sp->ats[mid])
  513. hi = mid;
  514. else
  515. lo = mid + 1;
  516. }
  517. i = sp->types[lo - 1];
  518. }
  519. ttisp = &sp->ttis[i];
  520. /*
  521. ** To get (wrong) behavior that's compatible with System V Release 2.0
  522. ** you'd replace the statement below with
  523. ** t += ttisp->tt_utoff;
  524. ** timesub(&t, 0L, sp, tmp);
  525. */
  526. result = timesub(&t, ttisp->tt_utoff, sp, tmp);
  527. if (result) {
  528. result->tm_isdst = ttisp->tt_isdst;
  529. if (ttisp->tt_desigidx > static_cast<s32>(sp->chars.size() - CHARS_EXTRA)) {
  530. return nullptr;
  531. }
  532. auto num_chars_to_copy{
  533. std::min(sp->chars.size() - ttisp->tt_desigidx, result->tm_zone.size()) - 1 };
  534. std::strncpy(result->tm_zone.data(), &sp->chars[ttisp->tt_desigidx], num_chars_to_copy);
  535. result->tm_zone[num_chars_to_copy] = '\0';
  536. auto original_size{ std::strlen(&sp->chars[ttisp->tt_desigidx]) };
  537. if (original_size > num_chars_to_copy) {
  538. return nullptr;
  539. }
  540. result->tm_utoff = ttisp->tt_utoff;
  541. result->time_index = i;
  542. }
  543. return result;
  544. }
  545. /*
  546. ** Given a year, a rule, and the offset from UT at the time that rule takes
  547. ** effect, calculate the year-relative time that rule takes effect.
  548. */
  549. constexpr s64 transtime(const int year, const tzrule* const rulep,
  550. const s64 offset) {
  551. bool leapyear;
  552. s64 value;
  553. int i;
  554. int d, m1, yy0, yy1, yy2, dow;
  555. leapyear = isleap(year);
  556. switch (rulep->r_type) {
  557. case JULIAN_DAY:
  558. /*
  559. ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
  560. ** years.
  561. ** In non-leap years, or if the day number is 59 or less, just
  562. ** add SECSPERDAY times the day number-1 to the time of
  563. ** January 1, midnight, to get the day.
  564. */
  565. value = (rulep->r_day - 1) * SECSPERDAY;
  566. if (leapyear && rulep->r_day >= 60) {
  567. value += SECSPERDAY;
  568. }
  569. break;
  570. case DAY_OF_YEAR:
  571. /*
  572. ** n - day of year.
  573. ** Just add SECSPERDAY times the day number to the time of
  574. ** January 1, midnight, to get the day.
  575. */
  576. value = rulep->r_day * SECSPERDAY;
  577. break;
  578. case MONTH_NTH_DAY_OF_WEEK:
  579. /*
  580. ** Mm.n.d - nth "dth day" of month m.
  581. */
  582. /*
  583. ** Use Zeller's Congruence to get day-of-week of first day of
  584. ** month.
  585. */
  586. m1 = (rulep->r_mon + 9) % 12 + 1;
  587. yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
  588. yy1 = yy0 / 100;
  589. yy2 = yy0 % 100;
  590. dow = ((26 * m1 - 2) / 10 + 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
  591. if (dow < 0) {
  592. dow += DAYSPERWEEK;
  593. }
  594. /*
  595. ** "dow" is the day-of-week of the first day of the month. Get
  596. ** the day-of-month (zero-origin) of the first "dow" day of the
  597. ** month.
  598. */
  599. d = rulep->r_day - dow;
  600. if (d < 0) {
  601. d += DAYSPERWEEK;
  602. }
  603. for (i = 1; i < rulep->r_week; ++i) {
  604. if (d + DAYSPERWEEK >= mon_lengths[leapyear][rulep->r_mon - 1]) {
  605. break;
  606. }
  607. d += DAYSPERWEEK;
  608. }
  609. /*
  610. ** "d" is the day-of-month (zero-origin) of the day we want.
  611. */
  612. value = d * SECSPERDAY;
  613. for (i = 0; i < rulep->r_mon - 1; ++i) {
  614. value += mon_lengths[leapyear][i] * SECSPERDAY;
  615. }
  616. break;
  617. default:
  618. //UNREACHABLE();
  619. break;
  620. }
  621. /*
  622. ** "value" is the year-relative time of 00:00:00 UT on the day in
  623. ** question. To get the year-relative time of the specified local
  624. ** time on that day, add the transition time and the current offset
  625. ** from UT.
  626. */
  627. return value + rulep->r_time + offset;
  628. }
  629. bool tzparse(const char* name, Rule* sp) {
  630. const char* stdname{};
  631. const char* dstname{};
  632. s64 stdoffset;
  633. s64 dstoffset;
  634. char* cp;
  635. ptrdiff_t stdlen;
  636. ptrdiff_t dstlen{};
  637. ptrdiff_t charcnt;
  638. time_t atlo = TIME_T_MIN, leaplo = TIME_T_MIN;
  639. stdname = name;
  640. if (*name == '<') {
  641. name++;
  642. stdname = name;
  643. name = getqzname(name, '>');
  644. if (*name != '>') {
  645. return false;
  646. }
  647. stdlen = name - stdname;
  648. name++;
  649. }
  650. else {
  651. name = getzname(name);
  652. stdlen = name - stdname;
  653. }
  654. if (!(0 < stdlen && stdlen <= TZNAME_MAXIMUM)) {
  655. return false;
  656. }
  657. name = getoffset(name, &stdoffset);
  658. if (name == nullptr) {
  659. return false;
  660. }
  661. charcnt = stdlen + 1;
  662. if (charcnt > TZ_MAX_CHARS) {
  663. return false;
  664. }
  665. if (*name != '\0') {
  666. if (*name == '<') {
  667. dstname = ++name;
  668. name = getqzname(name, '>');
  669. if (*name != '>')
  670. return false;
  671. dstlen = name - dstname;
  672. name++;
  673. }
  674. else {
  675. dstname = name;
  676. name = getzname(name);
  677. dstlen = name - dstname; /* length of DST abbr. */
  678. }
  679. if (!(0 < dstlen && dstlen <= TZNAME_MAXIMUM)) {
  680. return false;
  681. }
  682. charcnt += dstlen + 1;
  683. if (charcnt > TZ_MAX_CHARS) {
  684. return false;
  685. }
  686. if (*name != '\0' && *name != ',' && *name != ';') {
  687. name = getoffset(name, &dstoffset);
  688. if (name == nullptr) {
  689. return false;
  690. }
  691. }
  692. else {
  693. dstoffset = stdoffset - SECSPERHOUR;
  694. }
  695. if (*name == '\0') {
  696. name = TZDEFRULESTRING;
  697. }
  698. if (*name == ',' || *name == ';') {
  699. struct tzrule start;
  700. struct tzrule end;
  701. int year;
  702. int timecnt;
  703. time_t janfirst;
  704. s64 janoffset = 0;
  705. int yearbeg, yearlim;
  706. ++name;
  707. if ((name = getrule(name, &start)) == nullptr) {
  708. return false;
  709. }
  710. if (*name++ != ',') {
  711. return false;
  712. }
  713. if ((name = getrule(name, &end)) == nullptr) {
  714. return false;
  715. }
  716. if (*name != '\0') {
  717. return false;
  718. }
  719. sp->typecnt = 2; /* standard time and DST */
  720. /*
  721. ** Two transitions per year, from EPOCH_YEAR forward.
  722. */
  723. init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
  724. init_ttinfo(&sp->ttis[1], -dstoffset, true, static_cast<s32>(stdlen + 1));
  725. sp->defaulttype = 0;
  726. timecnt = 0;
  727. janfirst = 0;
  728. yearbeg = EPOCH_YEAR;
  729. do {
  730. s64 yearsecs = year_lengths[isleap(yearbeg - 1)] * SECSPERDAY;
  731. yearbeg--;
  732. if (increment_overflow_time(&janfirst, -yearsecs)) {
  733. janoffset = -yearsecs;
  734. break;
  735. }
  736. } while (atlo < janfirst && EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg);
  737. while (true) {
  738. s64 yearsecs = year_lengths[isleap(yearbeg)] * SECSPERDAY;
  739. int yearbeg1 = yearbeg;
  740. time_t janfirst1 = janfirst;
  741. if (increment_overflow_time(&janfirst1, yearsecs) ||
  742. increment_overflow(&yearbeg1, 1) || atlo <= janfirst1) {
  743. break;
  744. }
  745. yearbeg = yearbeg1;
  746. janfirst = janfirst1;
  747. }
  748. yearlim = yearbeg;
  749. if (increment_overflow(&yearlim, YEARSPERREPEAT + 1)) {
  750. yearlim = INT_MAX;
  751. }
  752. for (year = yearbeg; year < yearlim; year++) {
  753. s64 starttime = transtime(year, &start, stdoffset),
  754. endtime = transtime(year, &end, dstoffset);
  755. s64 yearsecs = (year_lengths[isleap(year)] * SECSPERDAY);
  756. bool reversed = endtime < starttime;
  757. if (reversed) {
  758. s64 swap = starttime;
  759. starttime = endtime;
  760. endtime = swap;
  761. }
  762. if (reversed || (starttime < endtime && endtime - starttime < yearsecs)) {
  763. if (TZ_MAX_TIMES - 2 < timecnt) {
  764. break;
  765. }
  766. sp->ats[timecnt] = janfirst;
  767. if (!increment_overflow_time(reinterpret_cast<time_t*>(&sp->ats[timecnt]), janoffset + starttime) &&
  768. atlo <= sp->ats[timecnt]) {
  769. sp->types[timecnt++] = !reversed;
  770. }
  771. sp->ats[timecnt] = janfirst;
  772. if (!increment_overflow_time(reinterpret_cast<time_t*>(&sp->ats[timecnt]), janoffset + endtime) &&
  773. atlo <= sp->ats[timecnt]) {
  774. sp->types[timecnt++] = reversed;
  775. }
  776. }
  777. if (endtime < leaplo) {
  778. yearlim = year;
  779. if (increment_overflow(&yearlim, YEARSPERREPEAT + 1)) {
  780. yearlim = INT_MAX;
  781. }
  782. }
  783. if (increment_overflow_time(&janfirst, janoffset + yearsecs)) {
  784. break;
  785. }
  786. janoffset = 0;
  787. }
  788. sp->timecnt = timecnt;
  789. if (!timecnt) {
  790. sp->ttis[0] = sp->ttis[1];
  791. sp->typecnt = 1; /* Perpetual DST. */
  792. }
  793. else if (YEARSPERREPEAT < year - yearbeg) {
  794. sp->goback = sp->goahead = true;
  795. }
  796. }
  797. else {
  798. s64 theirstdoffset;
  799. s64 theirdstoffset;
  800. s64 theiroffset;
  801. bool isdst;
  802. int i;
  803. int j;
  804. if (*name != '\0') {
  805. return false;
  806. }
  807. /*
  808. ** Initial values of theirstdoffset and theirdstoffset.
  809. */
  810. theirstdoffset = 0;
  811. for (i = 0; i < sp->timecnt; ++i) {
  812. j = sp->types[i];
  813. if (!sp->ttis[j].tt_isdst) {
  814. theirstdoffset = -sp->ttis[j].tt_utoff;
  815. break;
  816. }
  817. }
  818. theirdstoffset = 0;
  819. for (i = 0; i < sp->timecnt; ++i) {
  820. j = sp->types[i];
  821. if (sp->ttis[j].tt_isdst) {
  822. theirdstoffset = -sp->ttis[j].tt_utoff;
  823. break;
  824. }
  825. }
  826. /*
  827. ** Initially we're assumed to be in standard time.
  828. */
  829. isdst = false;
  830. /*
  831. ** Now juggle transition times and types
  832. ** tracking offsets as you do.
  833. */
  834. for (i = 0; i < sp->timecnt; ++i) {
  835. j = sp->types[i];
  836. sp->types[i] = sp->ttis[j].tt_isdst;
  837. if (sp->ttis[j].tt_ttisut) {
  838. /* No adjustment to transition time */
  839. }
  840. else {
  841. /*
  842. ** If daylight saving time is in
  843. ** effect, and the transition time was
  844. ** not specified as standard time, add
  845. ** the daylight saving time offset to
  846. ** the transition time; otherwise, add
  847. ** the standard time offset to the
  848. ** transition time.
  849. */
  850. /*
  851. ** Transitions from DST to DDST
  852. ** will effectively disappear since
  853. ** POSIX provides for only one DST
  854. ** offset.
  855. */
  856. if (isdst && !sp->ttis[j].tt_ttisstd) {
  857. sp->ats[i] += dstoffset - theirdstoffset;
  858. }
  859. else {
  860. sp->ats[i] += stdoffset - theirstdoffset;
  861. }
  862. }
  863. theiroffset = -sp->ttis[j].tt_utoff;
  864. if (sp->ttis[j].tt_isdst) {
  865. theirdstoffset = theiroffset;
  866. }
  867. else {
  868. theirstdoffset = theiroffset;
  869. }
  870. }
  871. /*
  872. ** Finally, fill in ttis.
  873. */
  874. init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
  875. init_ttinfo(&sp->ttis[1], -dstoffset, true, static_cast<s32>(stdlen + 1));
  876. sp->typecnt = 2;
  877. sp->defaulttype = 0;
  878. }
  879. }
  880. else {
  881. dstlen = 0;
  882. sp->typecnt = 1; /* only standard time */
  883. sp->timecnt = 0;
  884. init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
  885. sp->defaulttype = 0;
  886. }
  887. sp->charcnt = static_cast<s32>(charcnt);
  888. cp = &sp->chars[0];
  889. memcpy(cp, stdname, stdlen);
  890. cp += stdlen;
  891. *cp++ = '\0';
  892. if (dstlen != 0) {
  893. memcpy(cp, dstname, dstlen);
  894. *(cp + dstlen) = '\0';
  895. }
  896. return true;
  897. }
  898. int tzloadbody(Rule* sp, local_storage& local_storage) {
  899. int i;
  900. int stored;
  901. size_t nread{ local_storage.binary.size_bytes() };
  902. int tzheadsize = sizeof(struct TzifHeader);
  903. TzifHeader header{};
  904. //ASSERT(local_storage.binary.size_bytes() >= sizeof(TzifHeader));
  905. std::memcpy(&header, local_storage.binary.data(), sizeof(TzifHeader));
  906. sp->goback = sp->goahead = false;
  907. for (stored = 8; stored <= 8; stored *= 2) {
  908. s64 datablock_size;
  909. s32 ttisstdcnt = detzcode(header.tzh_ttisstdcnt.data());
  910. s32 ttisutcnt = detzcode(header.tzh_ttisutcnt.data());
  911. s32 leapcnt = detzcode(header.tzh_leapcnt.data());
  912. s32 timecnt = detzcode(header.tzh_timecnt.data());
  913. s32 typecnt = detzcode(header.tzh_typecnt.data());
  914. s32 charcnt = detzcode(header.tzh_charcnt.data());
  915. /* Although tzfile(5) currently requires typecnt to be nonzero,
  916. support future formats that may allow zero typecnt
  917. in files that have a TZ string and no transitions. */
  918. if (!(0 <= leapcnt && leapcnt < TZ_MAX_LEAPS && 0 <= typecnt && typecnt < TZ_MAX_TYPES &&
  919. 0 <= timecnt && timecnt < TZ_MAX_TIMES && 0 <= charcnt && charcnt < TZ_MAX_CHARS &&
  920. 0 <= ttisstdcnt && ttisstdcnt < TZ_MAX_TYPES && 0 <= ttisutcnt &&
  921. ttisutcnt < TZ_MAX_TYPES)) {
  922. return EINVAL;
  923. }
  924. datablock_size = (timecnt * stored /* ats */
  925. + timecnt /* types */
  926. + typecnt * 6 /* ttinfos */
  927. + charcnt /* chars */
  928. + leapcnt * (stored + 4) /* lsinfos */
  929. + ttisstdcnt /* ttisstds */
  930. + ttisutcnt); /* ttisuts */
  931. if (static_cast<s32>(local_storage.binary.size_bytes()) < tzheadsize + datablock_size) {
  932. return EINVAL;
  933. }
  934. if (!((ttisstdcnt == typecnt || ttisstdcnt == 0) &&
  935. (ttisutcnt == typecnt || ttisutcnt == 0))) {
  936. return EINVAL;
  937. }
  938. char const* p = (const char*)local_storage.binary.data() + tzheadsize;
  939. sp->timecnt = timecnt;
  940. sp->typecnt = typecnt;
  941. sp->charcnt = charcnt;
  942. /* Read transitions, discarding those out of time_t range.
  943. But pretend the last transition before TIME_T_MIN
  944. occurred at TIME_T_MIN. */
  945. timecnt = 0;
  946. for (i = 0; i < sp->timecnt; ++i) {
  947. int_fast64_t at = stored == 4 ? detzcode(p) : detzcode64(p);
  948. sp->types[i] = at <= TIME_T_MAX;
  949. if (sp->types[i]) {
  950. time_t attime =
  951. ((std::is_signed_v<time_t> ? at < TIME_T_MIN : at < 0) ? TIME_T_MIN : at);
  952. if (timecnt && attime <= sp->ats[timecnt - 1]) {
  953. if (attime < sp->ats[timecnt - 1])
  954. return EINVAL;
  955. sp->types[i - 1] = 0;
  956. timecnt--;
  957. }
  958. sp->ats[timecnt++] = attime;
  959. }
  960. p += stored;
  961. }
  962. timecnt = 0;
  963. for (i = 0; i < sp->timecnt; ++i) {
  964. unsigned char typ = *p++;
  965. if (sp->typecnt <= typ) {
  966. return EINVAL;
  967. }
  968. if (sp->types[i]) {
  969. sp->types[timecnt++] = typ;
  970. }
  971. }
  972. sp->timecnt = timecnt;
  973. for (i = 0; i < sp->typecnt; ++i) {
  974. struct ttinfo* ttisp;
  975. unsigned char isdst, desigidx;
  976. ttisp = &sp->ttis[i];
  977. ttisp->tt_utoff = detzcode(p);
  978. p += 4;
  979. isdst = *p++;
  980. if (!(isdst < 2)) {
  981. return EINVAL;
  982. }
  983. ttisp->tt_isdst = isdst != 0;
  984. desigidx = *p++;
  985. if (!(desigidx < sp->charcnt)) {
  986. return EINVAL;
  987. }
  988. ttisp->tt_desigidx = desigidx;
  989. }
  990. for (i = 0; i < sp->charcnt; ++i) {
  991. sp->chars[i] = *p++;
  992. }
  993. /* Ensure '\0'-terminated, and make it safe to call
  994. ttunspecified later. */
  995. memset(&sp->chars[i], 0, CHARS_EXTRA);
  996. for (i = 0; i < sp->typecnt; ++i) {
  997. struct ttinfo* ttisp;
  998. ttisp = &sp->ttis[i];
  999. if (ttisstdcnt == 0) {
  1000. ttisp->tt_ttisstd = false;
  1001. }
  1002. else {
  1003. if (*(bool*)p != true && *(bool*)p != false) {
  1004. return EINVAL;
  1005. }
  1006. ttisp->tt_ttisstd = *(bool*)p++;
  1007. }
  1008. }
  1009. for (i = 0; i < sp->typecnt; ++i) {
  1010. struct ttinfo* ttisp;
  1011. ttisp = &sp->ttis[i];
  1012. if (ttisutcnt == 0) {
  1013. ttisp->tt_ttisut = false;
  1014. }
  1015. else {
  1016. if (*(bool*)p != true && *(bool*)p != false) {
  1017. return EINVAL;
  1018. }
  1019. ttisp->tt_ttisut = *(bool*)p++;
  1020. }
  1021. }
  1022. nread += (ptrdiff_t)local_storage.binary.data() - (ptrdiff_t)p;
  1023. if (nread < 0) {
  1024. return EINVAL;
  1025. }
  1026. }
  1027. std::array<char, 256> buf{};
  1028. if (nread > buf.size()) {
  1029. //ASSERT(false);
  1030. return EINVAL;
  1031. }
  1032. memmove(buf.data(), &local_storage.binary[local_storage.binary.size_bytes() - nread], nread);
  1033. if (nread > 2 && buf[0] == '\n' && buf[nread - 1] == '\n' && sp->typecnt + 2 <= TZ_MAX_TYPES) {
  1034. Rule* ts = &local_storage.state;
  1035. buf[nread - 1] = '\0';
  1036. if (tzparse(&buf[1], ts) && local_storage.state.typecnt == 2) {
  1037. /* Attempt to reuse existing abbreviations.
  1038. Without this, America/Anchorage would be right on
  1039. the edge after 2037 when TZ_MAX_CHARS is 50, as
  1040. sp->charcnt equals 40 (for LMT AST AWT APT AHST
  1041. AHDT YST AKDT AKST) and ts->charcnt equals 10
  1042. (for AKST AKDT). Reusing means sp->charcnt can
  1043. stay 40 in this example. */
  1044. int gotabbr = 0;
  1045. int charcnt = sp->charcnt;
  1046. for (i = 0; i < ts->typecnt; i++) {
  1047. char* tsabbr = &ts->chars[ts->ttis[i].tt_desigidx];
  1048. int j;
  1049. for (j = 0; j < charcnt; j++)
  1050. if (strcmp(&sp->chars[j], tsabbr) == 0) {
  1051. ts->ttis[i].tt_desigidx = j;
  1052. gotabbr++;
  1053. break;
  1054. }
  1055. if (!(j < charcnt)) {
  1056. int tsabbrlen = static_cast<s32>(strlen(tsabbr));
  1057. if (j + tsabbrlen < TZ_MAX_CHARS) {
  1058. strcpy(&sp->chars[j], tsabbr);
  1059. charcnt = j + tsabbrlen + 1;
  1060. ts->ttis[i].tt_desigidx = j;
  1061. gotabbr++;
  1062. }
  1063. }
  1064. }
  1065. if (gotabbr == ts->typecnt) {
  1066. sp->charcnt = charcnt;
  1067. /* Ignore any trailing, no-op transitions generated
  1068. by zic as they don't help here and can run afoul
  1069. of bugs in zic 2016j or earlier. */
  1070. while (1 < sp->timecnt &&
  1071. (sp->types[sp->timecnt - 1] == sp->types[sp->timecnt - 2])) {
  1072. sp->timecnt--;
  1073. }
  1074. for (i = 0; i < ts->timecnt && sp->timecnt < TZ_MAX_TIMES; i++) {
  1075. time_t t = ts->ats[i];
  1076. if (0 < sp->timecnt && t <= sp->ats[sp->timecnt - 1]) {
  1077. continue;
  1078. }
  1079. sp->ats[sp->timecnt] = t;
  1080. sp->types[sp->timecnt] = static_cast<u8>(sp->typecnt + ts->types[i]);
  1081. sp->timecnt++;
  1082. }
  1083. for (i = 0; i < ts->typecnt; i++) {
  1084. sp->ttis[sp->typecnt++] = ts->ttis[i];
  1085. }
  1086. }
  1087. }
  1088. }
  1089. if (sp->typecnt == 0) {
  1090. return EINVAL;
  1091. }
  1092. if (sp->timecnt > 1) {
  1093. if (sp->ats[0] <= TIME_T_MAX - SECSPERREPEAT) {
  1094. time_t repeatat = sp->ats[0] + SECSPERREPEAT;
  1095. int repeattype = sp->types[0];
  1096. for (i = 1; i < sp->timecnt; ++i) {
  1097. if (sp->ats[i] == repeatat && typesequiv(sp, sp->types[i], repeattype)) {
  1098. sp->goback = true;
  1099. break;
  1100. }
  1101. }
  1102. }
  1103. if (TIME_T_MIN + SECSPERREPEAT <= sp->ats[sp->timecnt - 1]) {
  1104. time_t repeatat = sp->ats[sp->timecnt - 1] - SECSPERREPEAT;
  1105. int repeattype = sp->types[sp->timecnt - 1];
  1106. for (i = sp->timecnt - 2; i >= 0; --i) {
  1107. if (sp->ats[i] == repeatat && typesequiv(sp, sp->types[i], repeattype)) {
  1108. sp->goahead = true;
  1109. break;
  1110. }
  1111. }
  1112. }
  1113. }
  1114. /* Infer sp->defaulttype from the data. Although this default
  1115. type is always zero for data from recent tzdb releases,
  1116. things are trickier for data from tzdb 2018e or earlier.
  1117. The first set of heuristics work around bugs in 32-bit data
  1118. generated by tzdb 2013c or earlier. The workaround is for
  1119. zones like Australia/Macquarie where timestamps before the
  1120. first transition have a time type that is not the earliest
  1121. standard-time type. See:
  1122. https://mm.icann.org/pipermail/tz/2013-May/019368.html */
  1123. /*
  1124. ** If type 0 does not specify local time, or is unused in transitions,
  1125. ** it's the type to use for early times.
  1126. */
  1127. for (i = 0; i < sp->timecnt; ++i) {
  1128. if (sp->types[i] == 0) {
  1129. break;
  1130. }
  1131. }
  1132. i = i < sp->timecnt && !ttunspecified(sp, 0) ? -1 : 0;
  1133. /*
  1134. ** Absent the above,
  1135. ** if there are transition times
  1136. ** and the first transition is to a daylight time
  1137. ** find the standard type less than and closest to
  1138. ** the type of the first transition.
  1139. */
  1140. if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst) {
  1141. i = sp->types[0];
  1142. while (--i >= 0) {
  1143. if (!sp->ttis[i].tt_isdst) {
  1144. break;
  1145. }
  1146. }
  1147. }
  1148. /* The next heuristics are for data generated by tzdb 2018e or
  1149. earlier, for zones like EST5EDT where the first transition
  1150. is to DST. */
  1151. /*
  1152. ** If no result yet, find the first standard type.
  1153. ** If there is none, punt to type zero.
  1154. */
  1155. if (i < 0) {
  1156. i = 0;
  1157. while (sp->ttis[i].tt_isdst) {
  1158. if (++i >= sp->typecnt) {
  1159. i = 0;
  1160. break;
  1161. }
  1162. }
  1163. }
  1164. /* A simple 'sp->defaulttype = 0;' would suffice here if we
  1165. didn't have to worry about 2018e-or-earlier data. Even
  1166. simpler would be to remove the defaulttype member and just
  1167. use 0 in its place. */
  1168. sp->defaulttype = i;
  1169. return 0;
  1170. }
  1171. constexpr int tmcomp(const CalendarTimeInternal* const atmp,
  1172. const CalendarTimeInternal* const btmp) {
  1173. int result;
  1174. if (atmp->tm_year != btmp->tm_year) {
  1175. return atmp->tm_year < btmp->tm_year ? -1 : 1;
  1176. }
  1177. if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
  1178. (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
  1179. (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
  1180. (result = (atmp->tm_min - btmp->tm_min)) == 0) {
  1181. result = atmp->tm_sec - btmp->tm_sec;
  1182. }
  1183. return result;
  1184. }
  1185. /* Copy to *DEST from *SRC. Copy only the members needed for mktime,
  1186. as other members might not be initialized. */
  1187. constexpr void mktmcpy(struct CalendarTimeInternal* dest, struct CalendarTimeInternal const* src) {
  1188. dest->tm_sec = src->tm_sec;
  1189. dest->tm_min = src->tm_min;
  1190. dest->tm_hour = src->tm_hour;
  1191. dest->tm_mday = src->tm_mday;
  1192. dest->tm_mon = src->tm_mon;
  1193. dest->tm_year = src->tm_year;
  1194. dest->tm_isdst = src->tm_isdst;
  1195. dest->tm_zone = src->tm_zone;
  1196. dest->tm_utoff = src->tm_utoff;
  1197. dest->time_index = src->time_index;
  1198. }
  1199. constexpr bool normalize_overflow(int* const tensptr, int* const unitsptr, const int base) {
  1200. int tensdelta;
  1201. tensdelta = (*unitsptr >= 0) ? (*unitsptr / base) : (-1 - (-1 - *unitsptr) / base);
  1202. *unitsptr -= tensdelta * base;
  1203. return increment_overflow(tensptr, tensdelta);
  1204. }
  1205. constexpr bool normalize_overflow32(s64* tensptr, int* unitsptr, int base) {
  1206. int tensdelta;
  1207. tensdelta = (*unitsptr >= 0) ? (*unitsptr / base) : (-1 - (-1 - *unitsptr) / base);
  1208. *unitsptr -= tensdelta * base;
  1209. return increment_overflow32(tensptr, tensdelta);
  1210. }
  1211. int time2sub(time_t* out_time, CalendarTimeInternal* const tmp,
  1212. CalendarTimeInternal* (*funcp)(Rule const*, time_t const*, s64,
  1213. CalendarTimeInternal*),
  1214. Rule const* sp, const s64 offset, bool* okayp, bool do_norm_secs) {
  1215. int dir;
  1216. int i, j;
  1217. int saved_seconds;
  1218. s64 li;
  1219. time_t lo;
  1220. time_t hi;
  1221. s64 y;
  1222. time_t newt;
  1223. time_t t;
  1224. CalendarTimeInternal yourtm, mytm;
  1225. *okayp = false;
  1226. mktmcpy(&yourtm, tmp);
  1227. if (do_norm_secs) {
  1228. if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec, SECSPERMIN)) {
  1229. return 1;
  1230. }
  1231. }
  1232. if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR)) {
  1233. return 1;
  1234. }
  1235. if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) {
  1236. return 1;
  1237. }
  1238. y = yourtm.tm_year;
  1239. if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR)) {
  1240. return 1;
  1241. }
  1242. /*
  1243. ** Turn y into an actual year number for now.
  1244. ** It is converted back to an offset from TM_YEAR_BASE later.
  1245. */
  1246. if (increment_overflow32(&y, TM_YEAR_BASE)) {
  1247. return 1;
  1248. }
  1249. while (yourtm.tm_mday <= 0) {
  1250. if (increment_overflow32(&y, -1)) {
  1251. return 1;
  1252. }
  1253. li = y + (1 < yourtm.tm_mon);
  1254. yourtm.tm_mday += year_lengths[isleap(li)];
  1255. }
  1256. while (yourtm.tm_mday > DAYSPERLYEAR) {
  1257. li = y + (1 < yourtm.tm_mon);
  1258. yourtm.tm_mday -= year_lengths[isleap(li)];
  1259. if (increment_overflow32(&y, 1)) {
  1260. return 1;
  1261. }
  1262. }
  1263. for (;;) {
  1264. i = mon_lengths[isleap(y)][yourtm.tm_mon];
  1265. if (yourtm.tm_mday <= i) {
  1266. break;
  1267. }
  1268. yourtm.tm_mday -= i;
  1269. if (++yourtm.tm_mon >= MONSPERYEAR) {
  1270. yourtm.tm_mon = 0;
  1271. if (increment_overflow32(&y, 1)) {
  1272. return 1;
  1273. }
  1274. }
  1275. }
  1276. if (increment_overflow32(&y, -TM_YEAR_BASE)) {
  1277. return 1;
  1278. }
  1279. if (!(INT_MIN <= y && y <= INT_MAX)) {
  1280. return 1;
  1281. }
  1282. yourtm.tm_year = static_cast<s32>(y);
  1283. if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) {
  1284. saved_seconds = 0;
  1285. }
  1286. else if (yourtm.tm_year < EPOCH_YEAR - TM_YEAR_BASE) {
  1287. /*
  1288. ** We can't set tm_sec to 0, because that might push the
  1289. ** time below the minimum representable time.
  1290. ** Set tm_sec to 59 instead.
  1291. ** This assumes that the minimum representable time is
  1292. ** not in the same minute that a leap second was deleted from,
  1293. ** which is a safer assumption than using 58 would be.
  1294. */
  1295. if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN)) {
  1296. return 1;
  1297. }
  1298. saved_seconds = yourtm.tm_sec;
  1299. yourtm.tm_sec = SECSPERMIN - 1;
  1300. }
  1301. else {
  1302. saved_seconds = yourtm.tm_sec;
  1303. yourtm.tm_sec = 0;
  1304. }
  1305. /*
  1306. ** Do a binary search (this works whatever time_t's type is).
  1307. */
  1308. lo = TIME_T_MIN;
  1309. hi = TIME_T_MAX;
  1310. for (;;) {
  1311. t = lo / 2 + hi / 2;
  1312. if (t < lo) {
  1313. t = lo;
  1314. }
  1315. else if (t > hi) {
  1316. t = hi;
  1317. }
  1318. if (!funcp(sp, &t, offset, &mytm)) {
  1319. /*
  1320. ** Assume that t is too extreme to be represented in
  1321. ** a struct tm; arrange things so that it is less
  1322. ** extreme on the next pass.
  1323. */
  1324. dir = (t > 0) ? 1 : -1;
  1325. }
  1326. else {
  1327. dir = tmcomp(&mytm, &yourtm);
  1328. }
  1329. if (dir != 0) {
  1330. if (t == lo) {
  1331. if (t == TIME_T_MAX) {
  1332. return 2;
  1333. }
  1334. ++t;
  1335. ++lo;
  1336. }
  1337. else if (t == hi) {
  1338. if (t == TIME_T_MIN) {
  1339. return 2;
  1340. }
  1341. --t;
  1342. --hi;
  1343. }
  1344. if (lo > hi) {
  1345. return 2;
  1346. }
  1347. if (dir > 0) {
  1348. hi = t;
  1349. }
  1350. else {
  1351. lo = t;
  1352. }
  1353. continue;
  1354. }
  1355. if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) {
  1356. break;
  1357. }
  1358. /*
  1359. ** Right time, wrong type.
  1360. ** Hunt for right time, right type.
  1361. ** It's okay to guess wrong since the guess
  1362. ** gets checked.
  1363. */
  1364. if (sp == nullptr) {
  1365. return 2;
  1366. }
  1367. for (i = sp->typecnt - 1; i >= 0; --i) {
  1368. if (sp->ttis[i].tt_isdst != static_cast<bool>(yourtm.tm_isdst)) {
  1369. continue;
  1370. }
  1371. for (j = sp->typecnt - 1; j >= 0; --j) {
  1372. if (sp->ttis[j].tt_isdst == static_cast<bool>(yourtm.tm_isdst)) {
  1373. continue;
  1374. }
  1375. if (ttunspecified(sp, j)) {
  1376. continue;
  1377. }
  1378. newt = (t + sp->ttis[j].tt_utoff - sp->ttis[i].tt_utoff);
  1379. if (!funcp(sp, &newt, offset, &mytm)) {
  1380. continue;
  1381. }
  1382. if (tmcomp(&mytm, &yourtm) != 0) {
  1383. continue;
  1384. }
  1385. if (mytm.tm_isdst != yourtm.tm_isdst) {
  1386. continue;
  1387. }
  1388. /*
  1389. ** We have a match.
  1390. */
  1391. t = newt;
  1392. goto label;
  1393. }
  1394. }
  1395. return 2;
  1396. }
  1397. label:
  1398. newt = t + saved_seconds;
  1399. t = newt;
  1400. if (funcp(sp, &t, offset, tmp) || *okayp) {
  1401. *okayp = true;
  1402. *out_time = t;
  1403. return 0;
  1404. }
  1405. return 2;
  1406. }
  1407. int time2(time_t* out_time, struct CalendarTimeInternal* const tmp,
  1408. struct CalendarTimeInternal* (*funcp)(struct Rule const*, time_t const*, s64,
  1409. struct CalendarTimeInternal*),
  1410. struct Rule const* sp, const s64 offset, bool* okayp) {
  1411. int res;
  1412. /*
  1413. ** First try without normalization of seconds
  1414. ** (in case tm_sec contains a value associated with a leap second).
  1415. ** If that fails, try with normalization of seconds.
  1416. */
  1417. res = time2sub(out_time, tmp, funcp, sp, offset, okayp, false);
  1418. return *okayp ? res : time2sub(out_time, tmp, funcp, sp, offset, okayp, true);
  1419. }
  1420. int time1(time_t* out_time, CalendarTimeInternal* const tmp,
  1421. CalendarTimeInternal* (*funcp)(Rule const*, time_t const*, s64,
  1422. CalendarTimeInternal*),
  1423. Rule const* sp, const s64 offset) {
  1424. int samei, otheri;
  1425. int sameind, otherind;
  1426. int i;
  1427. int nseen;
  1428. char seen[TZ_MAX_TYPES];
  1429. unsigned char types[TZ_MAX_TYPES];
  1430. bool okay;
  1431. if (tmp->tm_isdst > 1) {
  1432. tmp->tm_isdst = 1;
  1433. }
  1434. auto res = time2(out_time, tmp, funcp, sp, offset, &okay);
  1435. if (res == 0) {
  1436. return res;
  1437. }
  1438. if (tmp->tm_isdst < 0) {
  1439. return res;
  1440. }
  1441. /*
  1442. ** We're supposed to assume that somebody took a time of one type
  1443. ** and did some math on it that yielded a "struct tm" that's bad.
  1444. ** We try to divine the type they started from and adjust to the
  1445. ** type they need.
  1446. */
  1447. for (i = 0; i < sp->typecnt; ++i) {
  1448. seen[i] = false;
  1449. }
  1450. if (sp->timecnt < 1) {
  1451. return 2;
  1452. }
  1453. nseen = 0;
  1454. for (i = sp->timecnt - 1; i >= 0; --i) {
  1455. if (!seen[sp->types[i]] && !ttunspecified(sp, sp->types[i])) {
  1456. seen[sp->types[i]] = true;
  1457. types[nseen++] = sp->types[i];
  1458. }
  1459. }
  1460. if (nseen < 1) {
  1461. return 2;
  1462. }
  1463. for (sameind = 0; sameind < nseen; ++sameind) {
  1464. samei = types[sameind];
  1465. if (sp->ttis[samei].tt_isdst != static_cast<bool>(tmp->tm_isdst)) {
  1466. continue;
  1467. }
  1468. for (otherind = 0; otherind < nseen; ++otherind) {
  1469. otheri = types[otherind];
  1470. if (sp->ttis[otheri].tt_isdst == static_cast<bool>(tmp->tm_isdst)) {
  1471. continue;
  1472. }
  1473. tmp->tm_sec += (sp->ttis[otheri].tt_utoff - sp->ttis[samei].tt_utoff);
  1474. tmp->tm_isdst = !tmp->tm_isdst;
  1475. res = time2(out_time, tmp, funcp, sp, offset, &okay);
  1476. if (res == 0) {
  1477. return res;
  1478. }
  1479. tmp->tm_sec -= (sp->ttis[otheri].tt_utoff - sp->ttis[samei].tt_utoff);
  1480. tmp->tm_isdst = !tmp->tm_isdst;
  1481. }
  1482. }
  1483. return 2;
  1484. }
  1485. } // namespace
  1486. s32 ParseTimeZoneBinary(Rule& out_rule, std::span<const u8> binary) {
  1487. tzloadbody_local_storage.binary = binary;
  1488. if (tzloadbody(&out_rule, tzloadbody_local_storage)) {
  1489. return 3;
  1490. }
  1491. return 0;
  1492. }
  1493. bool localtime_rz(CalendarTimeInternal* tmp, Rule const* sp, time_t* timep) {
  1494. return localsub(sp, timep, 0, tmp) == nullptr;
  1495. }
  1496. u32 mktime_tzname(time_t* out_time, Rule const* sp, CalendarTimeInternal* tmp) {
  1497. return time1(out_time, tmp, localsub, sp, 0);
  1498. }
  1499. } // namespace Tz