File Coverage

bson/bson-timegm.c
Criterion Covered Total %
statement 0 281 0.0
branch 0 246 0.0
condition n/a
subroutine n/a
pod n/a
total 0 527 0.0


line stmt bran cond sub pod time code
1             /*
2             ** This file is in the public domain, so clarified as of
3             ** 1996-06-05 by Arthur David Olson.
4             */
5              
6             /*
7             ** Leap second handling from Bradley White.
8             ** POSIX-style TZ environment variable handling from Guy Harris.
9             */
10              
11             #include "bson-compat.h"
12             #include "bson-macros.h"
13             #include "bson-timegm-private.h"
14              
15             #ifndef BSON_OS_WIN32
16              
17             #include "errno.h"
18             #include "string.h"
19             #include "limits.h" /* for CHAR_BIT et al. */
20             #include "time.h"
21              
22             /* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */
23             #define is_digit(c) ((unsigned)(c) - '0' <= 9)
24              
25             #ifndef CHAR_BIT
26             #define CHAR_BIT 8
27             #endif
28              
29             #if 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
30             # define ATTRIBUTE_CONST __attribute__ ((const))
31             # define ATTRIBUTE_PURE __attribute__ ((__pure__))
32             # define ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
33             #else
34             # define ATTRIBUTE_CONST /* empty */
35             # define ATTRIBUTE_PURE /* empty */
36             # define ATTRIBUTE_FORMAT(spec) /* empty */
37             #endif
38              
39             #if !defined _Noreturn && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112)
40             # if 2 < __GNUC__ + (8 <= __GNUC_MINOR__)
41             # define _Noreturn __attribute__ ((__noreturn__))
42             # else
43             # define _Noreturn
44             # endif
45             #endif
46              
47             #if (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901) && !defined restrict
48             # define restrict /* empty */
49             #endif
50              
51             #ifndef TYPE_BIT
52             #define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)
53             #endif /* !defined TYPE_BIT */
54              
55             #ifndef TYPE_SIGNED
56             #define TYPE_SIGNED(type) (((type) -1) < 0)
57             #endif /* !defined TYPE_SIGNED */
58              
59             /* The minimum and maximum finite time values. */
60             static time_t const time_t_min =
61             (TYPE_SIGNED(time_t)
62             ? (time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1)
63             : 0);
64             static time_t const time_t_max =
65             (TYPE_SIGNED(time_t)
66             ? - (~ 0 < 0) - ((time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1))
67             : -1);
68              
69              
70             #ifndef TZ_MAX_TIMES
71             #define TZ_MAX_TIMES 2000
72             #endif /* !defined TZ_MAX_TIMES */
73              
74             #ifndef TZ_MAX_TYPES
75             /* This must be at least 17 for Europe/Samara and Europe/Vilnius. */
76             #define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
77             #endif /* !defined TZ_MAX_TYPES */
78              
79             #ifndef TZ_MAX_CHARS
80             #define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
81             /* (limited by what unsigned chars can hold) */
82             #endif /* !defined TZ_MAX_CHARS */
83              
84             #ifndef TZ_MAX_LEAPS
85             #define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
86             #endif /* !defined TZ_MAX_LEAPS */
87              
88             #define SECSPERMIN 60
89             #define MINSPERHOUR 60
90             #define HOURSPERDAY 24
91             #define DAYSPERWEEK 7
92             #define DAYSPERNYEAR 365
93             #define DAYSPERLYEAR 366
94             #define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
95             #define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY)
96             #define MONSPERYEAR 12
97              
98             #define TM_SUNDAY 0
99             #define TM_MONDAY 1
100             #define TM_TUESDAY 2
101             #define TM_WEDNESDAY 3
102             #define TM_THURSDAY 4
103             #define TM_FRIDAY 5
104             #define TM_SATURDAY 6
105              
106             #define TM_JANUARY 0
107             #define TM_FEBRUARY 1
108             #define TM_MARCH 2
109             #define TM_APRIL 3
110             #define TM_MAY 4
111             #define TM_JUNE 5
112             #define TM_JULY 6
113             #define TM_AUGUST 7
114             #define TM_SEPTEMBER 8
115             #define TM_OCTOBER 9
116             #define TM_NOVEMBER 10
117             #define TM_DECEMBER 11
118              
119             #define TM_YEAR_BASE 1900
120              
121             #define EPOCH_YEAR 1970
122             #define EPOCH_WDAY TM_THURSDAY
123              
124             #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
125              
126             /*
127             ** Since everything in isleap is modulo 400 (or a factor of 400), we know that
128             ** isleap(y) == isleap(y % 400)
129             ** and so
130             ** isleap(a + b) == isleap((a + b) % 400)
131             ** or
132             ** isleap(a + b) == isleap(a % 400 + b % 400)
133             ** This is true even if % means modulo rather than Fortran remainder
134             ** (which is allowed by C89 but not C99).
135             ** We use this to avoid addition overflow problems.
136             */
137              
138             #define isleap_sum(a, b) isleap((a) % 400 + (b) % 400)
139              
140             #ifndef TZ_ABBR_MAX_LEN
141             #define TZ_ABBR_MAX_LEN 16
142             #endif /* !defined TZ_ABBR_MAX_LEN */
143              
144             #ifndef TZ_ABBR_CHAR_SET
145             #define TZ_ABBR_CHAR_SET \
146             "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
147             #endif /* !defined TZ_ABBR_CHAR_SET */
148              
149             #ifndef TZ_ABBR_ERR_CHAR
150             #define TZ_ABBR_ERR_CHAR '_'
151             #endif /* !defined TZ_ABBR_ERR_CHAR */
152              
153             #ifndef WILDABBR
154             /*
155             ** Someone might make incorrect use of a time zone abbreviation:
156             ** 1. They might reference tzname[0] before calling tzset (explicitly
157             ** or implicitly).
158             ** 2. They might reference tzname[1] before calling tzset (explicitly
159             ** or implicitly).
160             ** 3. They might reference tzname[1] after setting to a time zone
161             ** in which Daylight Saving Time is never observed.
162             ** 4. They might reference tzname[0] after setting to a time zone
163             ** in which Standard Time is never observed.
164             ** 5. They might reference tm.TM_ZONE after calling offtime.
165             ** What's best to do in the above cases is open to debate;
166             ** for now, we just set things up so that in any of the five cases
167             ** WILDABBR is used. Another possibility: initialize tzname[0] to the
168             ** string "tzname[0] used before set", and similarly for the other cases.
169             ** And another: initialize tzname[0] to "ERA", with an explanation in the
170             ** manual page of what this "time zone abbreviation" means (doing this so
171             ** that tzname[0] has the "normal" length of three characters).
172             */
173             #define WILDABBR " "
174             #endif /* !defined WILDABBR */
175              
176             #ifdef TM_ZONE
177             static const char wildabbr[] = WILDABBR;
178             #endif
179              
180             static const char gmt[] = "GMT";
181              
182             struct ttinfo { /* time type information */
183             int_fast32_t tt_gmtoff; /* UT offset in seconds */
184             int tt_isdst; /* used to set tm_isdst */
185             int tt_abbrind; /* abbreviation list index */
186             int tt_ttisstd; /* true if transition is std time */
187             int tt_ttisgmt; /* true if transition is UT */
188             };
189              
190             struct lsinfo { /* leap second information */
191             time_t ls_trans; /* transition time */
192             int_fast64_t ls_corr; /* correction to apply */
193             };
194              
195             #define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
196              
197             #ifdef TZNAME_MAX
198             #define MY_TZNAME_MAX TZNAME_MAX
199             #endif /* defined TZNAME_MAX */
200             #ifndef TZNAME_MAX
201             #define MY_TZNAME_MAX 255
202             #endif /* !defined TZNAME_MAX */
203              
204             struct state {
205             int leapcnt;
206             int timecnt;
207             int typecnt;
208             int charcnt;
209             int goback;
210             int goahead;
211             time_t ats[TZ_MAX_TIMES];
212             unsigned char types[TZ_MAX_TIMES];
213             struct ttinfo ttis[TZ_MAX_TYPES];
214             char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
215             (2 * (MY_TZNAME_MAX + 1)))];
216             struct lsinfo lsis[TZ_MAX_LEAPS];
217             int defaulttype; /* for early times or if no transitions */
218             };
219              
220             struct rule {
221             int r_type; /* type of rule--see below */
222             int r_day; /* day number of rule */
223             int r_week; /* week number of rule */
224             int r_mon; /* month number of rule */
225             int_fast32_t r_time; /* transition time of rule */
226             };
227              
228             #define JULIAN_DAY 0 /* Jn - Julian day */
229             #define DAY_OF_YEAR 1 /* n - day of year */
230             #define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
231              
232             /*
233             ** Prototypes for static functions.
234             */
235              
236             static void gmtload(struct state * sp);
237             static struct tm * gmtsub(const time_t * timep, int_fast32_t offset,
238             struct tm * tmp);
239             static int increment_overflow(int * number, int delta);
240             static int leaps_thru_end_of(int y) ATTRIBUTE_PURE;
241             static int increment_overflow32(int_fast32_t * number, int delta);
242             static int normalize_overflow32(int_fast32_t * tensptr,
243             int * unitsptr, int base);
244             static int normalize_overflow(int * tensptr, int * unitsptr,
245             int base);
246             static time_t time1(struct tm * tmp,
247             struct tm * (*funcp)(const time_t *,
248             int_fast32_t, struct tm *),
249             int_fast32_t offset);
250             static time_t time2(struct tm *tmp,
251             struct tm * (*funcp)(const time_t *,
252             int_fast32_t, struct tm*),
253             int_fast32_t offset, int * okayp);
254             static time_t time2sub(struct tm *tmp,
255             struct tm * (*funcp)(const time_t *,
256             int_fast32_t, struct tm*),
257             int_fast32_t offset, int * okayp, int do_norm_secs);
258             static struct tm * timesub(const time_t * timep, int_fast32_t offset,
259             const struct state * sp, struct tm * tmp);
260             static int tmcomp(const struct tm * atmp,
261             const struct tm * btmp);
262              
263             static struct state gmtmem;
264             #define gmtptr (&gmtmem)
265              
266             static int gmt_is_set;
267              
268             static const int mon_lengths[2][MONSPERYEAR] = {
269             { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
270             { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
271             };
272              
273             static const int year_lengths[2] = {
274             DAYSPERNYEAR, DAYSPERLYEAR
275             };
276              
277             static void
278 0           gmtload(struct state *const sp)
279             {
280 0           memset(sp, 0, sizeof(struct state));
281 0           sp->typecnt = 1;
282 0           sp->charcnt = 4;
283 0           sp->chars[0] = 'G';
284 0           sp->chars[1] = 'M';
285 0           sp->chars[2] = 'T';
286 0           }
287              
288             /*
289             ** gmtsub is to gmtime as localsub is to localtime.
290             */
291              
292             static struct tm *
293 0           gmtsub(const time_t *const timep, const int_fast32_t offset,
294             struct tm *const tmp)
295             {
296             register struct tm * result;
297              
298 0 0         if (!gmt_is_set) {
299 0           gmt_is_set = true;
300             // if (gmtptr != NULL)
301 0           gmtload(gmtptr);
302             }
303 0           result = timesub(timep, offset, gmtptr, tmp);
304             #ifdef TM_ZONE
305             /*
306             ** Could get fancy here and deliver something such as
307             ** "UT+xxxx" or "UT-xxxx" if offset is non-zero,
308             ** but this is no time for a treasure hunt.
309             */
310             tmp->TM_ZONE = offset ? wildabbr : gmtptr ? gmtptr->chars : gmt;
311             #endif /* defined TM_ZONE */
312 0           return result;
313             }
314              
315             /*
316             ** Return the number of leap years through the end of the given year
317             ** where, to make the math easy, the answer for year zero is defined as zero.
318             */
319              
320             static int
321 0           leaps_thru_end_of(register const int y)
322             {
323 0 0         return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
324 0           -(leaps_thru_end_of(-(y + 1)) + 1);
325             }
326              
327             static struct tm *
328 0           timesub(const time_t *const timep, const int_fast32_t offset,
329             register const struct state *const sp,
330             register struct tm *const tmp)
331             {
332             register const struct lsinfo * lp;
333             register time_t tdays;
334             register int idays; /* unsigned would be so 2003 */
335             register int_fast64_t rem;
336             int y;
337             register const int * ip;
338             register int_fast64_t corr;
339             register int hit;
340             register int i;
341              
342 0           corr = 0;
343 0           hit = 0;
344 0 0         i = (sp == NULL) ? 0 : sp->leapcnt;
345 0 0         while (--i >= 0) {
346 0           lp = &sp->lsis[i];
347 0 0         if (*timep >= lp->ls_trans) {
348 0 0         if (*timep == lp->ls_trans) {
349 0 0         hit = ((i == 0 && lp->ls_corr > 0) ||
    0          
    0          
350 0           lp->ls_corr > sp->lsis[i - 1].ls_corr);
351 0 0         if (hit)
352 0 0         while (i > 0 &&
    0          
353 0           sp->lsis[i].ls_trans ==
354 0 0         sp->lsis[i - 1].ls_trans + 1 &&
355 0           sp->lsis[i].ls_corr ==
356 0           sp->lsis[i - 1].ls_corr + 1) {
357 0           ++hit;
358 0           --i;
359             }
360             }
361 0           corr = lp->ls_corr;
362 0           break;
363             }
364             }
365 0           y = EPOCH_YEAR;
366 0           tdays = *timep / SECSPERDAY;
367 0           rem = *timep - tdays * SECSPERDAY;
368 0 0         while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
    0          
    0          
    0          
    0          
369             int newy;
370             register time_t tdelta;
371             register int idelta;
372             register int leapdays;
373              
374 0           tdelta = tdays / DAYSPERLYEAR;
375 0 0         if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
    0          
376             && tdelta <= INT_MAX))
377 0           return NULL;
378 0           idelta = (int) tdelta;
379 0 0         if (idelta == 0)
380 0 0         idelta = (tdays < 0) ? -1 : 1;
381 0           newy = y;
382 0 0         if (increment_overflow(&newy, idelta))
383 0           return NULL;
384 0           leapdays = leaps_thru_end_of(newy - 1) -
385 0           leaps_thru_end_of(y - 1);
386 0           tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
387 0           tdays -= leapdays;
388 0           y = newy;
389             }
390             {
391             register int_fast32_t seconds;
392              
393 0           seconds = (int_fast32_t) (tdays * SECSPERDAY);
394 0           tdays = seconds / SECSPERDAY;
395 0           rem += seconds - tdays * SECSPERDAY;
396             }
397             /*
398             ** Given the range, we can now fearlessly cast...
399             */
400 0           idays = (int) tdays;
401 0           rem += offset - corr;
402 0 0         while (rem < 0) {
403 0           rem += SECSPERDAY;
404 0           --idays;
405             }
406 0 0         while (rem >= SECSPERDAY) {
407 0           rem -= SECSPERDAY;
408 0           ++idays;
409             }
410 0 0         while (idays < 0) {
411 0 0         if (increment_overflow(&y, -1))
412 0           return NULL;
413 0 0         idays += year_lengths[isleap(y)];
    0          
    0          
414             }
415 0 0         while (idays >= year_lengths[isleap(y)]) {
    0          
    0          
    0          
416 0 0         idays -= year_lengths[isleap(y)];
    0          
    0          
417 0 0         if (increment_overflow(&y, 1))
418 0           return NULL;
419             }
420 0           tmp->tm_year = y;
421 0 0         if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
422 0           return NULL;
423 0           tmp->tm_yday = idays;
424             /*
425             ** The "extra" mods below avoid overflow problems.
426             */
427 0           tmp->tm_wday = EPOCH_WDAY +
428 0           ((y - EPOCH_YEAR) % DAYSPERWEEK) *
429 0           (DAYSPERNYEAR % DAYSPERWEEK) +
430 0           leaps_thru_end_of(y - 1) -
431 0           leaps_thru_end_of(EPOCH_YEAR - 1) +
432             idays;
433 0           tmp->tm_wday %= DAYSPERWEEK;
434 0 0         if (tmp->tm_wday < 0)
435 0           tmp->tm_wday += DAYSPERWEEK;
436 0           tmp->tm_hour = (int) (rem / SECSPERHOUR);
437 0           rem %= SECSPERHOUR;
438 0           tmp->tm_min = (int) (rem / SECSPERMIN);
439             /*
440             ** A positive leap second requires a special
441             ** representation. This uses "... ??:59:60" et seq.
442             */
443 0           tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
444 0 0         ip = mon_lengths[isleap(y)];
    0          
    0          
445 0 0         for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
446 0           idays -= ip[tmp->tm_mon];
447 0           tmp->tm_mday = (int) (idays + 1);
448 0           tmp->tm_isdst = 0;
449             #ifdef TM_GMTOFF
450             tmp->TM_GMTOFF = offset;
451             #endif /* defined TM_GMTOFF */
452 0           return tmp;
453             }
454              
455             /*
456             ** Adapted from code provided by Robert Elz, who writes:
457             ** The "best" way to do mktime I think is based on an idea of Bob
458             ** Kridle's (so its said...) from a long time ago.
459             ** It does a binary search of the time_t space. Since time_t's are
460             ** just 32 bits, its a max of 32 iterations (even at 64 bits it
461             ** would still be very reasonable).
462             */
463              
464             #ifndef WRONG
465             #define WRONG (-1)
466             #endif /* !defined WRONG */
467              
468             /*
469             ** Normalize logic courtesy Paul Eggert.
470             */
471              
472             static int
473 0           increment_overflow(int *const ip, int j)
474             {
475 0           register int const i = *ip;
476              
477             /*
478             ** If i >= 0 there can only be overflow if i + j > INT_MAX
479             ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
480             ** If i < 0 there can only be overflow if i + j < INT_MIN
481             ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
482             */
483 0 0         if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
    0          
484 0           return true;
485 0           *ip += j;
486 0           return false;
487             }
488              
489             static int
490 0           increment_overflow32(int_fast32_t *const lp, int const m)
491             {
492 0           register int_fast32_t const l = *lp;
493              
494 0 0         if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l))
    0          
495 0           return true;
496 0           *lp += m;
497 0           return false;
498             }
499              
500             static int
501 0           normalize_overflow(int *const tensptr, int *const unitsptr, const int base)
502             {
503             register int tensdelta;
504              
505 0           tensdelta = (*unitsptr >= 0) ?
506 0 0         (*unitsptr / base) :
507 0           (-1 - (-1 - *unitsptr) / base);
508 0           *unitsptr -= tensdelta * base;
509 0           return increment_overflow(tensptr, tensdelta);
510             }
511              
512             static int
513 0           normalize_overflow32(int_fast32_t *const tensptr, int *const unitsptr,
514             const int base)
515             {
516             register int tensdelta;
517              
518 0           tensdelta = (*unitsptr >= 0) ?
519 0 0         (*unitsptr / base) :
520 0           (-1 - (-1 - *unitsptr) / base);
521 0           *unitsptr -= tensdelta * base;
522 0           return increment_overflow32(tensptr, tensdelta);
523             }
524              
525             static int
526 0           tmcomp(register const struct tm *const atmp,
527             register const struct tm *const btmp)
528             {
529             register int result;
530              
531 0 0         if (atmp->tm_year != btmp->tm_year)
532 0 0         return atmp->tm_year < btmp->tm_year ? -1 : 1;
533 0 0         if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
    0          
534 0 0         (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
535 0 0         (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
536 0           (result = (atmp->tm_min - btmp->tm_min)) == 0)
537 0           result = atmp->tm_sec - btmp->tm_sec;
538 0           return result;
539             }
540              
541             static time_t
542 0           time2sub(struct tm *const tmp,
543             struct tm *(*const funcp)(const time_t *, int_fast32_t, struct tm *),
544             const int_fast32_t offset,
545             int *const okayp,
546             const int do_norm_secs)
547             {
548             register const struct state * sp;
549             register int dir;
550             register int i, j;
551             register int saved_seconds;
552             register int_fast32_t li;
553             register time_t lo;
554             register time_t hi;
555             int_fast32_t y;
556             time_t newt;
557             time_t t;
558             struct tm yourtm, mytm;
559              
560 0           *okayp = false;
561 0           yourtm = *tmp;
562 0 0         if (do_norm_secs) {
563 0 0         if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
564             SECSPERMIN))
565 0           return WRONG;
566             }
567 0 0         if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
568 0           return WRONG;
569 0 0         if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
570 0           return WRONG;
571 0           y = yourtm.tm_year;
572 0 0         if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR))
573 0           return WRONG;
574             /*
575             ** Turn y into an actual year number for now.
576             ** It is converted back to an offset from TM_YEAR_BASE later.
577             */
578 0 0         if (increment_overflow32(&y, TM_YEAR_BASE))
579 0           return WRONG;
580 0 0         while (yourtm.tm_mday <= 0) {
581 0 0         if (increment_overflow32(&y, -1))
582 0           return WRONG;
583 0           li = y + (1 < yourtm.tm_mon);
584 0 0         yourtm.tm_mday += year_lengths[isleap(li)];
    0          
    0          
585             }
586 0 0         while (yourtm.tm_mday > DAYSPERLYEAR) {
587 0           li = y + (1 < yourtm.tm_mon);
588 0 0         yourtm.tm_mday -= year_lengths[isleap(li)];
    0          
    0          
589 0 0         if (increment_overflow32(&y, 1))
590 0           return WRONG;
591             }
592             for ( ; ; ) {
593 0 0         i = mon_lengths[isleap(y)][yourtm.tm_mon];
    0          
    0          
594 0 0         if (yourtm.tm_mday <= i)
595 0           break;
596 0           yourtm.tm_mday -= i;
597 0 0         if (++yourtm.tm_mon >= MONSPERYEAR) {
598 0           yourtm.tm_mon = 0;
599 0 0         if (increment_overflow32(&y, 1))
600 0           return WRONG;
601             }
602 0           }
603 0 0         if (increment_overflow32(&y, -TM_YEAR_BASE))
604 0           return WRONG;
605 0           yourtm.tm_year = y;
606 0 0         if (yourtm.tm_year != y)
607 0           return WRONG;
608 0 0         if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
    0          
609 0           saved_seconds = 0;
610 0 0         else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
611             /*
612             ** We can't set tm_sec to 0, because that might push the
613             ** time below the minimum representable time.
614             ** Set tm_sec to 59 instead.
615             ** This assumes that the minimum representable time is
616             ** not in the same minute that a leap second was deleted from,
617             ** which is a safer assumption than using 58 would be.
618             */
619 0 0         if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
620 0           return WRONG;
621 0           saved_seconds = yourtm.tm_sec;
622 0           yourtm.tm_sec = SECSPERMIN - 1;
623             } else {
624 0           saved_seconds = yourtm.tm_sec;
625 0           yourtm.tm_sec = 0;
626             }
627             /*
628             ** Do a binary search (this works whatever time_t's type is).
629             */
630             if (!TYPE_SIGNED(time_t)) {
631             lo = 0;
632             hi = lo - 1;
633             } else {
634 0           lo = 1;
635 0 0         for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i)
636 0           lo *= 2;
637 0           hi = -(lo + 1);
638             }
639             for ( ; ; ) {
640 0           t = lo / 2 + hi / 2;
641 0 0         if (t < lo)
642 0           t = lo;
643 0 0         else if (t > hi)
644 0           t = hi;
645 0 0         if ((*funcp)(&t, offset, &mytm) == NULL) {
646             /*
647             ** Assume that t is too extreme to be represented in
648             ** a struct tm; arrange things so that it is less
649             ** extreme on the next pass.
650             */
651 0 0         dir = (t > 0) ? 1 : -1;
652 0           } else dir = tmcomp(&mytm, &yourtm);
653 0 0         if (dir != 0) {
654 0 0         if (t == lo) {
655 0 0         if (t == time_t_max)
656 0           return WRONG;
657 0           ++t;
658 0           ++lo;
659 0 0         } else if (t == hi) {
660 0 0         if (t == time_t_min)
661 0           return WRONG;
662 0           --t;
663 0           --hi;
664             }
665 0 0         if (lo > hi)
666 0           return WRONG;
667 0 0         if (dir > 0)
668 0           hi = t;
669 0           else lo = t;
670 0           continue;
671             }
672 0 0         if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
    0          
673             break;
674             /*
675             ** Right time, wrong type.
676             ** Hunt for right time, right type.
677             ** It's okay to guess wrong since the guess
678             ** gets checked.
679             */
680 0           sp = (const struct state *) gmtptr;
681 0 0         if (sp == NULL)
682 0           return WRONG;
683 0 0         for (i = sp->typecnt - 1; i >= 0; --i) {
684 0 0         if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
685 0           continue;
686 0 0         for (j = sp->typecnt - 1; j >= 0; --j) {
687 0 0         if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
688 0           continue;
689 0           newt = t + sp->ttis[j].tt_gmtoff -
690 0           sp->ttis[i].tt_gmtoff;
691 0 0         if ((*funcp)(&newt, offset, &mytm) == NULL)
692 0           continue;
693 0 0         if (tmcomp(&mytm, &yourtm) != 0)
694 0           continue;
695 0 0         if (mytm.tm_isdst != yourtm.tm_isdst)
696 0           continue;
697             /*
698             ** We have a match.
699             */
700 0           t = newt;
701 0           goto label;
702             }
703             }
704 0           return WRONG;
705 0           }
706             label:
707 0           newt = t + saved_seconds;
708 0 0         if ((newt < t) != (saved_seconds < 0))
709 0           return WRONG;
710 0           t = newt;
711 0 0         if ((*funcp)(&t, offset, tmp))
712 0           *okayp = true;
713 0           return t;
714             }
715              
716             static time_t
717 0           time2(struct tm * const tmp,
718             struct tm * (*const funcp)(const time_t *, int_fast32_t, struct tm *),
719             const int_fast32_t offset,
720             int *const okayp)
721             {
722             time_t t;
723              
724             /*
725             ** First try without normalization of seconds
726             ** (in case tm_sec contains a value associated with a leap second).
727             ** If that fails, try with normalization of seconds.
728             */
729 0           t = time2sub(tmp, funcp, offset, okayp, false);
730 0 0         return *okayp ? t : time2sub(tmp, funcp, offset, okayp, true);
731             }
732              
733             static time_t
734 0           time1(struct tm *const tmp,
735             struct tm *(*const funcp) (const time_t *, int_fast32_t, struct tm *),
736             const int_fast32_t offset)
737             {
738             register time_t t;
739             register const struct state * sp;
740             register int samei, otheri;
741             register int sameind, otherind;
742             register int i;
743             register int nseen;
744             int seen[TZ_MAX_TYPES];
745             int types[TZ_MAX_TYPES];
746             int okay;
747              
748 0 0         if (tmp == NULL) {
749 0           errno = EINVAL;
750 0           return WRONG;
751             }
752 0 0         if (tmp->tm_isdst > 1)
753 0           tmp->tm_isdst = 1;
754 0           t = time2(tmp, funcp, offset, &okay);
755 0 0         if (okay)
756 0           return t;
757 0 0         if (tmp->tm_isdst < 0)
758             #ifdef PCTS
759             /*
760             ** POSIX Conformance Test Suite code courtesy Grant Sullivan.
761             */
762             tmp->tm_isdst = 0; /* reset to std and try again */
763             #else
764 0           return t;
765             #endif /* !defined PCTS */
766             /*
767             ** We're supposed to assume that somebody took a time of one type
768             ** and did some math on it that yielded a "struct tm" that's bad.
769             ** We try to divine the type they started from and adjust to the
770             ** type they need.
771             */
772 0           sp = (const struct state *) gmtptr;
773 0 0         if (sp == NULL)
774 0           return WRONG;
775 0 0         for (i = 0; i < sp->typecnt; ++i)
776 0           seen[i] = false;
777 0           nseen = 0;
778 0 0         for (i = sp->timecnt - 1; i >= 0; --i)
779 0 0         if (!seen[sp->types[i]]) {
780 0           seen[sp->types[i]] = true;
781 0           types[nseen++] = sp->types[i];
782             }
783 0 0         for (sameind = 0; sameind < nseen; ++sameind) {
784 0           samei = types[sameind];
785 0 0         if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
786 0           continue;
787 0 0         for (otherind = 0; otherind < nseen; ++otherind) {
788 0           otheri = types[otherind];
789 0 0         if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
790 0           continue;
791 0           tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
792 0           sp->ttis[samei].tt_gmtoff;
793 0           tmp->tm_isdst = !tmp->tm_isdst;
794 0           t = time2(tmp, funcp, offset, &okay);
795 0 0         if (okay)
796 0           return t;
797 0           tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
798 0           sp->ttis[samei].tt_gmtoff;
799 0           tmp->tm_isdst = !tmp->tm_isdst;
800             }
801             }
802 0           return WRONG;
803             }
804              
805             time_t
806 0           _bson_timegm(struct tm *const tmp)
807             {
808 0 0         if (tmp != NULL)
809 0           tmp->tm_isdst = 0;
810 0           return time1(tmp, gmtsub, 0L);
811             }
812              
813             #endif