(root)/
tar-1.35/
gnu/
mktime.c
       1  /* Convert a 'struct tm' to a time_t value.
       2     Copyright (C) 1993-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4     Contributed by Paul Eggert <eggert@twinsun.com>.
       5  
       6     The GNU C Library is free software; you can redistribute it and/or
       7     modify it under the terms of the GNU Lesser General Public
       8     License as published by the Free Software Foundation; either
       9     version 2.1 of the License, or (at your option) any later version.
      10  
      11     The GNU C Library is distributed in the hope that it will be useful,
      12     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14     Lesser General Public License for more details.
      15  
      16     You should have received a copy of the GNU Lesser General Public
      17     License along with the GNU C Library; if not, see
      18     <https://www.gnu.org/licenses/>.  */
      19  
      20  /* The following macros influence what gets defined when this file is compiled:
      21  
      22     Macro/expression            Which gnulib module    This compilation unit
      23                                                        should define
      24  
      25     _LIBC                       (glibc proper)         mktime
      26  
      27     NEED_MKTIME_WORKING         mktime                 rpl_mktime
      28     || NEED_MKTIME_WINDOWS
      29  
      30     NEED_MKTIME_INTERNAL        mktime-internal        mktime_internal
      31   */
      32  
      33  #ifndef _LIBC
      34  # include <libc-config.h>
      35  #endif
      36  
      37  /* Assume that leap seconds are possible, unless told otherwise.
      38     If the host has a 'zic' command with a '-L leapsecondfilename' option,
      39     then it supports leap seconds; otherwise it probably doesn't.  */
      40  #ifndef LEAP_SECONDS_POSSIBLE
      41  # define LEAP_SECONDS_POSSIBLE 1
      42  #endif
      43  
      44  #include <time.h>
      45  
      46  #include <errno.h>
      47  #include <limits.h>
      48  #include <stdbool.h>
      49  #include <stdckdint.h>
      50  #include <stdlib.h>
      51  #include <string.h>
      52  
      53  #include <intprops.h>
      54  #include <verify.h>
      55  
      56  #ifndef NEED_MKTIME_INTERNAL
      57  # define NEED_MKTIME_INTERNAL 0
      58  #endif
      59  #ifndef NEED_MKTIME_WINDOWS
      60  # define NEED_MKTIME_WINDOWS 0
      61  #endif
      62  #ifndef NEED_MKTIME_WORKING
      63  # define NEED_MKTIME_WORKING 0
      64  #endif
      65  
      66  #include "mktime-internal.h"
      67  
      68  #if !defined _LIBC && (NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS)
      69  static void
      70  my_tzset (void)
      71  {
      72  # if NEED_MKTIME_WINDOWS
      73    /* Rectify the value of the environment variable TZ.
      74       There are four possible kinds of such values:
      75         - Traditional US time zone names, e.g. "PST8PDT".  Syntax: see
      76           <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/tzset>
      77         - Time zone names based on geography, that contain one or more
      78           slashes, e.g. "Europe/Moscow".
      79         - Time zone names based on geography, without slashes, e.g.
      80           "Singapore".
      81         - Time zone names that contain explicit DST rules.  Syntax: see
      82           <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03>
      83       The Microsoft CRT understands only the first kind.  It produces incorrect
      84       results if the value of TZ is of the other kinds.
      85       But in a Cygwin environment, /etc/profile.d/tzset.sh sets TZ to a value
      86       of the second kind for most geographies, or of the first kind in a few
      87       other geographies.  If it is of the second kind, neutralize it.  For the
      88       Microsoft CRT, an absent or empty TZ means the time zone that the user
      89       has set in the Windows Control Panel.
      90       If the value of TZ is of the third or fourth kind -- Cygwin programs
      91       understand these syntaxes as well --, it does not matter whether we
      92       neutralize it or not, since these values occur only when a Cygwin user
      93       has set TZ explicitly; this case is 1. rare and 2. under the user's
      94       responsibility.  */
      95    const char *tz = getenv ("TZ");
      96    if (tz != NULL && strchr (tz, '/') != NULL)
      97      _putenv ("TZ=");
      98  # else
      99    tzset ();
     100  # endif
     101  }
     102  # undef __tzset
     103  # define __tzset() my_tzset ()
     104  #endif
     105  
     106  #if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL
     107  
     108  /* A signed type that can represent an integer number of years
     109     multiplied by four times the number of seconds in a year.  It is
     110     needed when converting a tm_year value times the number of seconds
     111     in a year.  The factor of four comes because these products need
     112     to be subtracted from each other, and sometimes with an offset
     113     added to them, and then with another timestamp added, without
     114     worrying about overflow.
     115  
     116     Much of the code uses long_int to represent __time64_t values, to
     117     lessen the hassle of dealing with platforms where __time64_t is
     118     unsigned, and because long_int should suffice to represent all
     119     __time64_t values that mktime can generate even on platforms where
     120     __time64_t is wider than the int components of struct tm.  */
     121  
     122  #if INT_MAX <= LONG_MAX / 4 / 366 / 24 / 60 / 60
     123  typedef long int long_int;
     124  #else
     125  typedef long long int long_int;
     126  #endif
     127  verify (INT_MAX <= TYPE_MAXIMUM (long_int) / 4 / 366 / 24 / 60 / 60);
     128  
     129  /* Shift A right by B bits portably, by dividing A by 2**B and
     130     truncating towards minus infinity.  B should be in the range 0 <= B
     131     <= LONG_INT_BITS - 2, where LONG_INT_BITS is the number of useful
     132     bits in a long_int.  LONG_INT_BITS is at least 32.
     133  
     134     ISO C99 says that A >> B is implementation-defined if A < 0.  Some
     135     implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
     136     right in the usual way when A < 0, so SHR falls back on division if
     137     ordinary A >> B doesn't seem to be the usual signed shift.  */
     138  
     139  static long_int
     140  shr (long_int a, int b)
     141  {
     142    long_int one = 1;
     143    return (-one >> 1 == -1
     144  	  ? a >> b
     145  	  : (a + (a < 0)) / (one << b) - (a < 0));
     146  }
     147  
     148  /* Bounds for the intersection of __time64_t and long_int.  */
     149  
     150  static long_int const mktime_min
     151    = ((TYPE_SIGNED (__time64_t)
     152        && TYPE_MINIMUM (__time64_t) < TYPE_MINIMUM (long_int))
     153       ? TYPE_MINIMUM (long_int) : TYPE_MINIMUM (__time64_t));
     154  static long_int const mktime_max
     155    = (TYPE_MAXIMUM (long_int) < TYPE_MAXIMUM (__time64_t)
     156       ? TYPE_MAXIMUM (long_int) : TYPE_MAXIMUM (__time64_t));
     157  
     158  #define EPOCH_YEAR 1970
     159  #define TM_YEAR_BASE 1900
     160  verify (TM_YEAR_BASE % 100 == 0);
     161  
     162  /* Is YEAR + TM_YEAR_BASE a leap year?  */
     163  static bool
     164  leapyear (long_int year)
     165  {
     166    /* Don't add YEAR to TM_YEAR_BASE, as that might overflow.
     167       Also, work even if YEAR is negative.  */
     168    return
     169      ((year & 3) == 0
     170       && (year % 100 != 0
     171  	 || ((year / 100) & 3) == (- (TM_YEAR_BASE / 100) & 3)));
     172  }
     173  
     174  /* How many days come before each month (0-12).  */
     175  #ifndef _LIBC
     176  static
     177  #endif
     178  const unsigned short int __mon_yday[2][13] =
     179    {
     180      /* Normal years.  */
     181      { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
     182      /* Leap years.  */
     183      { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
     184    };
     185  
     186  
     187  /* Do the values A and B differ according to the rules for tm_isdst?
     188     A and B differ if one is zero and the other positive.  */
     189  static bool
     190  isdst_differ (int a, int b)
     191  {
     192    return (!a != !b) && (0 <= a) && (0 <= b);
     193  }
     194  
     195  /* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) -
     196     (YEAR0-YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks
     197     were not adjusted between the timestamps.
     198  
     199     The YEAR values uses the same numbering as TP->tm_year.  Values
     200     need not be in the usual range.  However, YEAR1 - YEAR0 must not
     201     overflow even when multiplied by three times the number of seconds
     202     in a year, and likewise for YDAY1 - YDAY0 and three times the
     203     number of seconds in a day.  */
     204  
     205  static long_int
     206  ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1,
     207  	    int year0, int yday0, int hour0, int min0, int sec0)
     208  {
     209    verify (-1 / 2 == 0);
     210  
     211    /* Compute intervening leap days correctly even if year is negative.
     212       Take care to avoid integer overflow here.  */
     213    int a4 = shr (year1, 2) + shr (TM_YEAR_BASE, 2) - ! (year1 & 3);
     214    int b4 = shr (year0, 2) + shr (TM_YEAR_BASE, 2) - ! (year0 & 3);
     215    int a100 = (a4 + (a4 < 0)) / 25 - (a4 < 0);
     216    int b100 = (b4 + (b4 < 0)) / 25 - (b4 < 0);
     217    int a400 = shr (a100, 2);
     218    int b400 = shr (b100, 2);
     219    int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
     220  
     221    /* Compute the desired time without overflowing.  */
     222    long_int years = year1 - year0;
     223    long_int days = 365 * years + yday1 - yday0 + intervening_leap_days;
     224    long_int hours = 24 * days + hour1 - hour0;
     225    long_int minutes = 60 * hours + min1 - min0;
     226    long_int seconds = 60 * minutes + sec1 - sec0;
     227    return seconds;
     228  }
     229  
     230  /* Return the average of A and B, even if A + B would overflow.
     231     Round toward positive infinity.  */
     232  static long_int
     233  long_int_avg (long_int a, long_int b)
     234  {
     235    return shr (a, 1) + shr (b, 1) + ((a | b) & 1);
     236  }
     237  
     238  /* Return a long_int value corresponding to (YEAR-YDAY HOUR:MIN:SEC)
     239     minus *TP seconds, assuming no clock adjustments occurred between
     240     the two timestamps.
     241  
     242     YEAR and YDAY must not be so large that multiplying them by three times the
     243     number of seconds in a year (or day, respectively) would overflow long_int.
     244     *TP should be in the usual range.  */
     245  static long_int
     246  tm_diff (long_int year, long_int yday, int hour, int min, int sec,
     247  	 struct tm const *tp)
     248  {
     249    return ydhms_diff (year, yday, hour, min, sec,
     250  		     tp->tm_year, tp->tm_yday,
     251  		     tp->tm_hour, tp->tm_min, tp->tm_sec);
     252  }
     253  
     254  /* Use CONVERT to convert T to a struct tm value in *TM.  T must be in
     255     range for __time64_t.  Return TM if successful, NULL (setting errno) on
     256     failure.  */
     257  static struct tm *
     258  convert_time (struct tm *(*convert) (const __time64_t *, struct tm *),
     259  	      long_int t, struct tm *tm)
     260  {
     261    __time64_t x = t;
     262    return convert (&x, tm);
     263  }
     264  
     265  /* Use CONVERT to convert *T to a broken down time in *TP.
     266     If *T is out of range for conversion, adjust it so that
     267     it is the nearest in-range value and then convert that.
     268     A value is in range if it fits in both __time64_t and long_int.
     269     Return TP on success, NULL (setting errno) on failure.  */
     270  static struct tm *
     271  ranged_convert (struct tm *(*convert) (const __time64_t *, struct tm *),
     272  		long_int *t, struct tm *tp)
     273  {
     274    long_int t1 = (*t < mktime_min ? mktime_min
     275  		 : *t <= mktime_max ? *t : mktime_max);
     276    struct tm *r = convert_time (convert, t1, tp);
     277    if (r)
     278      {
     279        *t = t1;
     280        return r;
     281      }
     282    if (errno != EOVERFLOW)
     283      return NULL;
     284  
     285    long_int bad = t1;
     286    long_int ok = 0;
     287    struct tm oktm; oktm.tm_sec = -1;
     288  
     289    /* BAD is a known out-of-range value, and OK is a known in-range one.
     290       Use binary search to narrow the range between BAD and OK until
     291       they differ by 1.  */
     292    while (true)
     293      {
     294        long_int mid = long_int_avg (ok, bad);
     295        if (mid == ok || mid == bad)
     296  	break;
     297        if (convert_time (convert, mid, tp))
     298  	ok = mid, oktm = *tp;
     299        else if (errno != EOVERFLOW)
     300  	return NULL;
     301        else
     302  	bad = mid;
     303      }
     304  
     305    if (oktm.tm_sec < 0)
     306      return NULL;
     307    *t = ok;
     308    *tp = oktm;
     309    return tp;
     310  }
     311  
     312  
     313  /* Convert *TP to a __time64_t value, inverting
     314     the monotonic and mostly-unit-linear conversion function CONVERT.
     315     Use *OFFSET to keep track of a guess at the offset of the result,
     316     compared to what the result would be for UTC without leap seconds.
     317     If *OFFSET's guess is correct, only one CONVERT call is needed.
     318     If successful, set *TP to the canonicalized struct tm;
     319     otherwise leave *TP alone, return ((time_t) -1) and set errno.
     320     This function is external because it is used also by timegm.c.  */
     321  __time64_t
     322  __mktime_internal (struct tm *tp,
     323  		   struct tm *(*convert) (const __time64_t *, struct tm *),
     324  		   mktime_offset_t *offset)
     325  {
     326    struct tm tm;
     327  
     328    /* The maximum number of probes (calls to CONVERT) should be enough
     329       to handle any combinations of time zone rule changes, solar time,
     330       leap seconds, and oscillations around a spring-forward gap.
     331       POSIX.1 prohibits leap seconds, but some hosts have them anyway.  */
     332    int remaining_probes = 6;
     333  
     334    /* Time requested.  Copy it in case CONVERT modifies *TP; this can
     335       occur if TP is localtime's returned value and CONVERT is localtime.  */
     336    int sec = tp->tm_sec;
     337    int min = tp->tm_min;
     338    int hour = tp->tm_hour;
     339    int mday = tp->tm_mday;
     340    int mon = tp->tm_mon;
     341    int year_requested = tp->tm_year;
     342    int isdst = tp->tm_isdst;
     343  
     344    /* 1 if the previous probe was DST.  */
     345    int dst2 = 0;
     346  
     347    /* Ensure that mon is in range, and set year accordingly.  */
     348    int mon_remainder = mon % 12;
     349    int negative_mon_remainder = mon_remainder < 0;
     350    int mon_years = mon / 12 - negative_mon_remainder;
     351    long_int lyear_requested = year_requested;
     352    long_int year = lyear_requested + mon_years;
     353  
     354    /* The other values need not be in range:
     355       the remaining code handles overflows correctly.  */
     356  
     357    /* Calculate day of year from year, month, and day of month.
     358       The result need not be in range.  */
     359    int mon_yday = ((__mon_yday[leapyear (year)]
     360  		   [mon_remainder + 12 * negative_mon_remainder])
     361  		  - 1);
     362    long_int lmday = mday;
     363    long_int yday = mon_yday + lmday;
     364  
     365    mktime_offset_t off = *offset;
     366    int negative_offset_guess;
     367  
     368    int sec_requested = sec;
     369  
     370    if (LEAP_SECONDS_POSSIBLE)
     371      {
     372        /* Handle out-of-range seconds specially,
     373  	 since ydhms_diff assumes every minute has 60 seconds.  */
     374        if (sec < 0)
     375  	sec = 0;
     376        if (59 < sec)
     377  	sec = 59;
     378      }
     379  
     380    /* Invert CONVERT by probing.  First assume the same offset as last
     381       time.  */
     382  
     383    ckd_sub (&negative_offset_guess, 0, off);
     384    long_int t0 = ydhms_diff (year, yday, hour, min, sec,
     385  			    EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0,
     386  			    negative_offset_guess);
     387    long_int t = t0, t1 = t0, t2 = t0;
     388  
     389    /* Repeatedly use the error to improve the guess.  */
     390  
     391    while (true)
     392      {
     393        if (! ranged_convert (convert, &t, &tm))
     394  	return -1;
     395        long_int dt = tm_diff (year, yday, hour, min, sec, &tm);
     396        if (dt == 0)
     397  	break;
     398  
     399        if (t == t1 && t != t2
     400  	  && (tm.tm_isdst < 0
     401  	      || (isdst < 0
     402  		  ? dst2 <= (tm.tm_isdst != 0)
     403  		  : (isdst != 0) != (tm.tm_isdst != 0))))
     404  	/* We can't possibly find a match, as we are oscillating
     405  	   between two values.  The requested time probably falls
     406  	   within a spring-forward gap of size DT.  Follow the common
     407  	   practice in this case, which is to return a time that is DT
     408  	   away from the requested time, preferring a time whose
     409  	   tm_isdst differs from the requested value.  (If no tm_isdst
     410  	   was requested and only one of the two values has a nonzero
     411  	   tm_isdst, prefer that value.)  In practice, this is more
     412  	   useful than returning -1.  */
     413  	goto offset_found;
     414  
     415        remaining_probes--;
     416        if (remaining_probes == 0)
     417  	{
     418  	  __set_errno (EOVERFLOW);
     419  	  return -1;
     420  	}
     421  
     422        t1 = t2, t2 = t, t += dt, dst2 = tm.tm_isdst != 0;
     423      }
     424  
     425    /* We have a match.  Check whether tm.tm_isdst has the requested
     426       value, if any.  */
     427    if (isdst_differ (isdst, tm.tm_isdst))
     428      {
     429        /* tm.tm_isdst has the wrong value.  Look for a neighboring
     430  	 time with the right value, and use its UTC offset.
     431  
     432  	 Heuristic: probe the adjacent timestamps in both directions,
     433  	 looking for the desired isdst.  If none is found within a
     434  	 reasonable duration bound, assume a one-hour DST difference.
     435  	 This should work for all real time zone histories in the tz
     436  	 database.  */
     437  
     438        /* +1 if we wanted standard time but got DST, -1 if the reverse.  */
     439        int dst_difference = (isdst == 0) - (tm.tm_isdst == 0);
     440  
     441        /* Distance between probes when looking for a DST boundary.  In
     442  	 tzdata2003a, the shortest period of DST is 601200 seconds
     443  	 (e.g., America/Recife starting 2000-10-08 01:00), and the
     444  	 shortest period of non-DST surrounded by DST is 694800
     445  	 seconds (Africa/Tunis starting 1943-04-17 01:00).  Use the
     446  	 minimum of these two values, so we don't miss these short
     447  	 periods when probing.  */
     448        int stride = 601200;
     449  
     450        /* In TZDB 2021e, the longest period of DST (or of non-DST), in
     451  	 which the DST (or adjacent DST) difference is not one hour,
     452  	 is 457243209 seconds: e.g., America/Cambridge_Bay with leap
     453  	 seconds, starting 1965-10-31 00:00 in a switch from
     454  	 double-daylight time (-05) to standard time (-07), and
     455  	 continuing to 1980-04-27 02:00 in a switch from standard time
     456  	 (-07) to daylight time (-06).  */
     457        int duration_max = 457243209;
     458  
     459        /* Search in both directions, so the maximum distance is half
     460  	 the duration; add the stride to avoid off-by-1 problems.  */
     461        int delta_bound = duration_max / 2 + stride;
     462  
     463        int delta, direction;
     464  
     465        for (delta = stride; delta < delta_bound; delta += stride)
     466  	for (direction = -1; direction <= 1; direction += 2)
     467  	  {
     468  	    long_int ot;
     469  	    if (! ckd_add (&ot, t, delta * direction))
     470  	      {
     471  		struct tm otm;
     472  		if (! ranged_convert (convert, &ot, &otm))
     473  		  return -1;
     474  		if (! isdst_differ (isdst, otm.tm_isdst))
     475  		  {
     476  		    /* We found the desired tm_isdst.
     477  		       Extrapolate back to the desired time.  */
     478  		    long_int gt = ot + tm_diff (year, yday, hour, min, sec,
     479  						&otm);
     480  		    if (mktime_min <= gt && gt <= mktime_max)
     481  		      {
     482  			if (convert_time (convert, gt, &tm))
     483  			  {
     484  			    t = gt;
     485  			    goto offset_found;
     486  			  }
     487  			if (errno != EOVERFLOW)
     488  			  return -1;
     489  		      }
     490  		  }
     491  	      }
     492  	  }
     493  
     494        /* No unusual DST offset was found nearby.  Assume one-hour DST.  */
     495        t += 60 * 60 * dst_difference;
     496        if (mktime_min <= t && t <= mktime_max && convert_time (convert, t, &tm))
     497  	goto offset_found;
     498  
     499        __set_errno (EOVERFLOW);
     500        return -1;
     501      }
     502  
     503   offset_found:
     504    /* Set *OFFSET to the low-order bits of T - T0 - NEGATIVE_OFFSET_GUESS.
     505       This is just a heuristic to speed up the next mktime call, and
     506       correctness is unaffected if integer overflow occurs here.  */
     507    ckd_sub (offset, t, t0);
     508    ckd_sub (offset, *offset, negative_offset_guess);
     509  
     510    if (LEAP_SECONDS_POSSIBLE && sec_requested != tm.tm_sec)
     511      {
     512        /* Adjust time to reflect the tm_sec requested, not the normalized value.
     513  	 Also, repair any damage from a false match due to a leap second.  */
     514        long_int sec_adjustment = sec == 0 && tm.tm_sec == 60;
     515        sec_adjustment -= sec;
     516        sec_adjustment += sec_requested;
     517        if (ckd_add (&t, t, sec_adjustment)
     518  	  || ! (mktime_min <= t && t <= mktime_max))
     519  	{
     520  	  __set_errno (EOVERFLOW);
     521  	  return -1;
     522  	}
     523        if (! convert_time (convert, t, &tm))
     524  	return -1;
     525      }
     526  
     527    *tp = tm;
     528    return t;
     529  }
     530  
     531  #endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_INTERNAL */
     532  
     533  #if defined _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS
     534  
     535  /* Convert *TP to a __time64_t value.  */
     536  __time64_t
     537  __mktime64 (struct tm *tp)
     538  {
     539    /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
     540       time zone names contained in the external variable 'tzname' shall
     541       be set as if the tzset() function had been called.  */
     542    __tzset ();
     543  
     544  # if defined _LIBC || NEED_MKTIME_WORKING
     545    static mktime_offset_t localtime_offset;
     546    return __mktime_internal (tp, __localtime64_r, &localtime_offset);
     547  # else
     548  #  undef mktime
     549    return mktime (tp);
     550  # endif
     551  }
     552  #endif /* _LIBC || NEED_MKTIME_WORKING || NEED_MKTIME_WINDOWS */
     553  
     554  #if defined _LIBC && __TIMESIZE != 64
     555  
     556  libc_hidden_def (__mktime64)
     557  
     558  time_t
     559  mktime (struct tm *tp)
     560  {
     561    struct tm tm = *tp;
     562    __time64_t t = __mktime64 (&tm);
     563    if (in_time_t_range (t))
     564      {
     565        *tp = tm;
     566        return t;
     567      }
     568    else
     569      {
     570        __set_errno (EOVERFLOW);
     571        return -1;
     572      }
     573  }
     574  
     575  #endif
     576  
     577  weak_alias (mktime, timelocal)
     578  libc_hidden_def (mktime)
     579  libc_hidden_weak (timelocal)