diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2018-09-19 13:16:14 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2018-09-19 17:09:08 -0700 |
commit | 8e6fd2bdb21efe2cc1ae7571ff8fb2599db6a05a (patch) | |
tree | 16623453ad42c7ad61408a410c312aae747cc4d6 /time/timegm.c | |
parent | 83a552b0bb9fc2a5e80a0ab3723c0a80ce1db9f2 (diff) | |
download | glibc-8e6fd2bdb21efe2cc1ae7571ff8fb2599db6a05a.tar.gz glibc-8e6fd2bdb21efe2cc1ae7571ff8fb2599db6a05a.tar.xz glibc-8e6fd2bdb21efe2cc1ae7571ff8fb2599db6a05a.zip |
Merge mktime, timegm from upstream Gnulib
[BZ #23603][BZ #16346] This fixes some obscure problems with integer overflow. Although it looks scary, it is almost all a byte-for-byte copy from Gnulib, and the Gnulib code has been tested reasonably well. * include/intprops.h: New file, copied from Gnulib. * include/verify.h, time/mktime-internal.h: New tiny files, simplified from Gnulib. * time/mktime.c: Copy from Gnulib. This has the following changes: Do not include config.h if DEBUG_MKTIME is nonzero. Include stdbool.h, intprops.h, verify.h. Include string.h only if needed. Include stdlib.h on MS-Windows. Include mktime-internal.h. (DEBUG_MKTIME): Default to 0, and simplify later uses. (NEED_MKTIME_INTERNAL, NEED_MKTIME_WINDOWS) (NEED_MKTIME_WORKING): Give default values to pacify -Wundef, which glibc uses. Default NEED_MKTIME_WORKING to DEBUG_MKTIME, to simplify later conditionals; default the others to zero. Use these conditionals to express only the code needed on the current platform. In uses of these conditionals, explicitly spell out how _LIBC affects things, so it’s easier to review from a glibc viewpoint. (WRAPV): Remove; no longer needed now that we have systematic overflow checking. (my_tzset, __tzset) [!_LIBC]: New function and macro, to better compartmentalize tzset issues. Move system-dependent tzsettish code here from mktime. (verify): Remove; now done by verify.h. All uses changed. (long_int): Use a more-conservative definition, to avoid integer overflow. (SHR): Remove, replacing with ... (shr): New function, which means we needn’t worry about side effects in args, and conversion analysis is simpler. (TYPE_IS_INTEGER, TYPE_TWOS_COMPLEMENT, TYPE_SIGNED, TYPE_MINIMUM) (TYPE_MAXIMUM, TIME_T_MIN, TIME_T_MAX, TIME_T_MIDPOINT) (time_t_avg, time_t_add_ok): Remove. (mktime_min, mktime_max): New constants. (leapyear, isdst_differ): Use bool for booleans. (ydhms_diff, guess_time_tm, ranged_convert, __mktime_internal): Use long_int, not time_t, for mktime differences. (long_int_avg): New function, replacing time_t_avg. INT_ADD_WRAPV replaces time_t_add_ok. (guess_time_tm): 6th arg is now long_int, not time_t const *. All uses changed. (convert_time): New function. (ranged_convert): Use it. (__mktime_internal): Last arg now points to mktime_offset_t, not time_t. All uses changed. This is a no-op on glibc, where mktime_offset_t is always time_t. Use int, not time_t, for UTC offset guess. Directly check for integer overflow instead of using a heuristic that works only 99.9...% of the time. Access *OFFSET only once, to avoid an unlikely race if the compiler delays a load and if this cascades into a signed integer overflow. (mktime): Move tzsettish code to my_tzset, and move localtime_offset to within mktime so that it doesn’t need a separate ifdef. (main) [DEBUG_MKTIME]: Speed up by using localtime_r instead of localtime. * time/timegm.c: Copy from Gnulib. This has the following changes: Include mktime-internal.h. [!_LIBC]: Include config.h and time.h. Do not include timegm.h or time_r.h. Make __mktime_internal a macro, and include mktime-internal.h to get its declaration. (timegm): Temporary is now mktime_offset_t, not time_t. This affects only Gnulib.
Diffstat (limited to 'time/timegm.c')
-rw-r--r-- | time/timegm.c | 23 |
1 files changed, 5 insertions, 18 deletions
diff --git a/time/timegm.c b/time/timegm.c index fb720e2d7d..229fff23c6 100644 --- a/time/timegm.c +++ b/time/timegm.c @@ -17,31 +17,18 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#ifdef HAVE_CONFIG_H +#ifndef _LIBC # include <config.h> #endif -#ifdef _LIBC -# include <time.h> -#else -# include "timegm.h" - -/* Portable standalone applications should supply a "time_r.h" that - declares a POSIX-compliant gmtime_r, for the benefit of older - implementations that lack gmtime_r or have a nonstandard one. - See the gnulib time_r module for one way to implement this. */ -# include <time_r.h> -# undef __gmtime_r -# define __gmtime_r gmtime_r -time_t __mktime_internal (struct tm *, - struct tm * (*) (time_t const *, struct tm *), - time_t *); -#endif +#include <time.h> + +#include "mktime-internal.h" time_t timegm (struct tm *tmp) { - static time_t gmtime_offset; + static mktime_offset_t gmtime_offset; tmp->tm_isdst = 0; return __mktime_internal (tmp, __gmtime_r, &gmtime_offset); } |