@@ -11,6 +11,9 @@ Version 2.26
transliteration tables are all updated to Unicode 9.0.0, using
generator scripts contributed by Mike FABIAN (Red Hat).
+* The private identifiers __daylight, __isleap, __timezone, __tzname have
+ been removed from the <time.h> header file.
+
Security related changes:
[Add security related changes here]
@@ -3,6 +3,7 @@
#ifndef _ISOMAC
# include <xlocale.h>
+# include <stdbool.h>
__BEGIN_DECLS
@@ -31,8 +32,8 @@ struct tm;
/* Defined in mktime.c. */
extern const unsigned short int __mon_yday[2][13] attribute_hidden;
-/* Defined in localtime.c. */
-extern struct tm _tmbuf attribute_hidden;
+bool __time_isleap (int year) internal_function;
+libc_hidden_proto (__time_isleap)
/* Defined in tzset.c. */
extern char *__tzstring (const char *string);
@@ -26,6 +26,7 @@
#include <wchar.h>
#include <stdint.h>
#include <sys/uio.h>
+#include <time.h>
#include <assert.h>
@@ -353,7 +354,8 @@ No definition for %s category found"), "LC_TIME"));
> days_per_month[time->era_entries[idx].start_date[1]])
|| (time->era_entries[idx].start_date[1] == 2
&& time->era_entries[idx].start_date[2] == 29
- && !__isleap (time->era_entries[idx].start_date[0])))
+ && !__time_isleap (time->era_entries[idx]
+ .start_date[0])))
&& !be_quiet)
WITH_CUR_LOCALE (error (0, 0, _("\
%s: starting date is invalid in string %Zd in `era' field"),
@@ -430,7 +432,8 @@ No definition for %s category found"), "LC_TIME"));
> days_per_month[time->era_entries[idx].stop_date[1]])
|| (time->era_entries[idx].stop_date[1] == 2
&& time->era_entries[idx].stop_date[2] == 29
- && !__isleap (time->era_entries[idx].stop_date[0])))
+ && !__time_isleap (time->era_entries[idx]
+ .stop_date[0])))
&& !be_quiet)
WITH_CUR_LOCALE (error (0, 0, _("\
%s: invalid stopping date in string %Zd in `era' field"),
@@ -19,6 +19,9 @@
#include <time.h>
#include <sys/time.h>
+/* For __tzname, __timezone, __daylight. */
+#include <time/time-variables.h>
+
/* Get the current time of day and timezone information,
putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled.
Returns 0 on success, -1 on errors. */
@@ -36,14 +36,14 @@ routines := offtime asctime clock ctime ctime_r difftime \
stime dysize timegm ftime \
getdate strptime strptime_l \
strftime wcsftime strftime_l wcsftime_l \
- timespec_get
+ timespec_get isleap
aux := era alt_digit lc-time-cleanup
tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \
tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \
tst-strptime3 bug-getdate1 tst-strptime-whitespace tst-ftime \
- tst-tzname
+ tst-tzname tst-isleap
include ../Rules
@@ -1,6 +1,6 @@
libc {
GLIBC_2.0 {
- # global variables
+ # Global variables, exported as compat symbols.
__daylight; __timezone; __tzname;
# functions with special/multiple interfaces
@@ -65,4 +65,7 @@ libc {
GLIBC_2.16 {
timespec_get;
}
+ GLIBC_PRIVATE {
+ __time_isleap;
+ }
}
@@ -20,5 +20,5 @@
int
dysize (int year)
{
- return __isleap (year) ? 366 : 365;
+ return __time_isleap (year) ? 366 : 365;
}
@@ -95,7 +95,7 @@ check_mday (int year, int mon, int mday)
return 1;
break;
case 1:
- if (mday >= 1 && mday <= (__isleap (year) ? 29 : 28))
+ if (mday >= 1 && mday <= (__time_isleap (year) ? 29 : 28))
return 1;
break;
}
@@ -17,6 +17,7 @@
<http://www.gnu.org/licenses/>. */
#include <time.h>
+#include <time/time-variables.h>
/* Return the `struct tm' representation of *T in UTC,
using *TP to store the result. */
new file mode 100644
@@ -0,0 +1,27 @@
+/* Leap year detection.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <time.h>
+
+bool
+internal_function
+__time_isleap (int year)
+{
+ return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
+}
+libc_hidden_def (__time_isleap)
@@ -17,6 +17,7 @@
<http://www.gnu.org/licenses/>. */
#include <time.h>
+#include <time/time-variables.h>
/* The C Standard says that localtime and gmtime return the same pointer. */
struct tm _tmbuf;
@@ -57,7 +57,7 @@ __offtime (const time_t *t, long int offset, struct tm *tp)
#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
- while (days < 0 || days >= (__isleap (y) ? 366 : 365))
+ while (days < 0 || days >= (__time_isleap (y) ? 366 : 365))
{
/* Guess a corrected year, assuming 365 days per year. */
time_t yg = y + days / 365 - (days % 365 < 0);
@@ -76,7 +76,7 @@ __offtime (const time_t *t, long int offset, struct tm *tp)
return 0;
}
tp->tm_yday = days;
- ip = __mon_yday[__isleap(y)];
+ ip = __mon_yday[__time_isleap (y)];
for (y = 11; days < (long int) ip[y]; --y)
continue;
days -= ip[y];
@@ -33,28 +33,30 @@
# define MULTIBYTE_IS_FORMAT_SAFE 1
# define STDC_HEADERS 1
# include "../locale/localeinfo.h"
-#endif
-#if defined emacs && !defined HAVE_BCOPY
-# define HAVE_MEMCPY 1
+# define __isleap(year) __time_isleap (year)
+# include <time.h>
+# include <time/time-variables.h>
#endif
#include <ctype.h>
#include <sys/types.h> /* Some systems define `time_t' here. */
-#ifdef TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# ifdef HAVE_SYS_TIME_H
+#ifndef _LIBC
+# ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
-# else
# include <time.h>
+# else
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
# endif
-#endif
-#if HAVE_TZNAME
+# if HAVE_TZNAME
extern char *tzname[];
-#endif
+# endif
+#endif /* !_LIBC */
/* Do multibyte processing if multibytes are supported, unless
multibyte sequences are safe in formats. Multibyte sequences are
new file mode 100644
@@ -0,0 +1,44 @@
+/* Global variables used by the time subsystem.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This header should only be used within the time subsystem, but
+ there are some historic external references. The global variables
+ declared here cannot be accessed in a thread-safe manner. */
+
+#ifndef TIME_VARIABLES_H
+#define TIME_VARIABLES_H
+
+#include <stdbool.h>
+#include <time.h>
+
+/* Global variables updated by tzset, localtime. These are aliased to
+ their counterparts without the __ prefix.
+
+ Ideally, we should turn __tzname, __daylight, __timezone into
+ compat symbols. However, ld cannot process certain relocations for
+ symbols such as tzname, which have an alias which is a compat
+ symbol. The alias is considered hidden, and ld rejects the link
+ because it assumes that the alias relationship is broken. */
+extern char *__tzname[2];
+extern int __daylight;
+extern long int __timezone;
+
+/* Defined in localtime.c. */
+extern struct tm _tmbuf attribute_hidden;
+
+#endif /* TIME_VARIABLES_H */
@@ -160,16 +160,8 @@ extern char *ctime_r (const time_t *__restrict __timer,
char *__restrict __buf) __THROW;
#endif /* POSIX */
-
-/* Defined in localtime.c. */
-extern char *__tzname[2]; /* Current timezone names. */
-extern int __daylight; /* If daylight-saving time is ever in use. */
-extern long int __timezone; /* Seconds west of UTC. */
-
-
#ifdef __USE_POSIX
-/* Same as above. */
-extern char *tzname[2];
+extern char *tzname[2]; /* Current timezone names. */
/* Set time conversion information from the TZ environment variable.
If TZ is not defined, a locale-dependent default is used. */
@@ -177,8 +169,8 @@ extern void tzset (void) __THROW;
#endif
#if defined __USE_MISC || defined __USE_XOPEN
-extern int daylight;
-extern long int timezone;
+extern int daylight; /* If daylight-saving time is ever in use. */
+extern long int timezone; /* Seconds west of UTC. */
#endif
#ifdef __USE_MISC
@@ -187,13 +179,6 @@ extern long int timezone;
extern int stime (const time_t *__when) __THROW;
#endif
-
-/* Nonzero if YEAR is a leap year (every 4 years,
- except every 100th isn't, and every 400th is). */
-#define __isleap(year) \
- ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
-
-
#ifdef __USE_MISC
/* Miscellaneous functions many Unices inherited from the public domain
localtime package. These are included only for compatibility. */
new file mode 100644
@@ -0,0 +1,40 @@
+/* Test leap year processing.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <time.h>
+#include <support/check.h>
+
+static int
+do_test (void)
+{
+ TEST_VERIFY (!__time_isleap (-100));
+ TEST_VERIFY (__time_isleap (0));
+ TEST_VERIFY (!__time_isleap (100));
+ TEST_VERIFY (!__time_isleap (200));
+ TEST_VERIFY (!__time_isleap (300));
+ TEST_VERIFY (__time_isleap (400));
+ TEST_VERIFY (!__time_isleap (1900));
+ TEST_VERIFY (__time_isleap (1996));
+ TEST_VERIFY (__time_isleap (2000));
+ TEST_VERIFY (__time_isleap (2004));
+ TEST_VERIFY (__time_isleap (2008));
+ TEST_VERIFY (!__time_isleap (2100));
+ return 0;
+}
+
+#include <support/test-driver.c>
@@ -26,6 +26,7 @@
#include <sys/stat.h>
#include <stdint.h>
+#include <time/time-variables.h>
#include <timezone/tzfile.h>
int __use_tzfile;
@@ -24,7 +24,10 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include <libc-symbols.h>
+#include <shlib-compat.h>
+#include <time/time-variables.h>
#include <timezone/tzfile.h>
char *__tzname[2] = { (char *) "GMT", (char *) "GMT" };
@@ -457,7 +460,7 @@ compute_change (tz_rule *rule, int year)
add SECSPERDAY times the day number-1 to the time of
January 1, midnight, to get the day. */
t += (rule->d - 1) * SECSPERDAY;
- if (rule->d >= 60 && __isleap (year))
+ if (rule->d >= 60 && __time_isleap (year))
t += SECSPERDAY;
break;
@@ -473,7 +476,7 @@ compute_change (tz_rule *rule, int year)
unsigned int i;
int d, m1, yy0, yy1, yy2, dow;
const unsigned short int *myday =
- &__mon_yday[__isleap (year)][rule->m];
+ &__mon_yday[__time_isleap (year)][rule->m];
/* First add SECSPERDAY for each day in months before M. */
t += myday[-1] * SECSPERDAY;