Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-7-0]: src/lib/libc/time Pull up following revision(s) (requested ...
details: https://anonhg.NetBSD.org/src/rev/568dfd0ba203
branches: netbsd-7-0
changeset: 801253:568dfd0ba203
user: snj <snj%NetBSD.org@localhost>
date: Tue Dec 13 06:41:29 2016 +0000
description:
Pull up following revision(s) (requested by kre in ticket #1323):
lib/libc/time/private.h: patch
lib/libc/time/zic.c: patch
Make zic properly parse newer tzdata files.
diffstat:
lib/libc/time/private.h | 13 +-
lib/libc/time/zic.c | 342 +++++++++++++++++++++++++++++++----------------
2 files changed, 238 insertions(+), 117 deletions(-)
diffs (truncated from 770 to 300 lines):
diff -r 6af791b556bd -r 568dfd0ba203 lib/libc/time/private.h
--- a/lib/libc/time/private.h Mon Dec 12 07:56:11 2016 +0000
+++ b/lib/libc/time/private.h Tue Dec 13 06:41:29 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: private.h,v 1.33.2.1 2015/01/25 09:11:03 martin Exp $ */
+/* $NetBSD: private.h,v 1.33.2.1.2.1 2016/12/13 06:41:29 snj Exp $ */
#ifndef PRIVATE_H
#define PRIVATE_H
@@ -477,6 +477,17 @@
#define TYPE_SIGNED(type) (/*CONSTCOND*/((type) -1) < 0)
#endif /* !defined TYPE_SIGNED */
+#define TWOS_COMPLEMENT(t) (/*CONSTCOND*/(t) ~ (t) 0 < 0)
+
+/* Max and min values of the integer type T, of which only the bottom
+ B bits are used, and where the highest-order used bit is considered
+ to be a sign bit if T is signed. */
+#define MAXVAL(t, b) /*LINTED*/ \
+ ((t) (((t) 1 << ((b) - 1 - TYPE_SIGNED(t))) \
+ - 1 + ((t) 1 << ((b) - 1 - TYPE_SIGNED(t)))))
+#define MINVAL(t, b) \
+ ((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0))
+
#ifdef LOCALTIME_IMPLEMENTATION
/* The minimum and maximum finite time values. */
static time_t const time_t_min =
diff -r 6af791b556bd -r 568dfd0ba203 lib/libc/time/zic.c
--- a/lib/libc/time/zic.c Mon Dec 12 07:56:11 2016 +0000
+++ b/lib/libc/time/zic.c Tue Dec 13 06:41:29 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: zic.c,v 1.46.2.1 2015/01/25 09:11:03 martin Exp $ */
+/* $NetBSD: zic.c,v 1.46.2.1.2.1 2016/12/13 06:41:29 snj Exp $ */
/*
** This file is in the public domain, so clarified as of
** 2006-07-17 by Arthur David Olson.
@@ -10,7 +10,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: zic.c,v 1.46.2.1 2015/01/25 09:11:03 martin Exp $");
+__RCSID("$NetBSD: zic.c,v 1.46.2.1.2.1 2016/12/13 06:41:29 snj Exp $");
#endif /* !defined lint */
#include "private.h"
@@ -88,6 +88,7 @@
zic_t z_gmtoff;
const char * z_rule;
const char * z_format;
+ char z_format_specifier;
zic_t z_stdoff;
@@ -145,6 +146,16 @@
static int atcomp(const void *avp, const void *bvp);
static void updateminmax(zic_t x);
+/* Bound on length of what %z can expand to. */
+enum { PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1 };
+
+/* If true, work around a bug in Qt 5.6.1 and earlier, which mishandles
+ tz binary files whose POSIX-TZ-style strings contain '<'; see
+ QTBUG-53071 <https://bugreports.qt.io/browse/QTBUG-53071>. This
+ workaround will no longer be needed when Qt 5.6.1 and earlier are
+ obsolete, say in the year 2021. */
+enum { WORK_AROUND_QTBUG_53071 = 1 };
+
static int charcnt;
static bool errors;
static bool warnings;
@@ -154,7 +165,7 @@
static zic_t leapminyear;
static zic_t leapmaxyear;
static int linenum;
-static size_t max_abbrvar_len;
+static size_t max_abbrvar_len = PERCENT_Z_LEN_BOUND;
static size_t max_format_len;
static zic_t max_year;
static zic_t min_year;
@@ -350,6 +361,7 @@
static struct attype {
zic_t at;
+ bool dontmerge;
unsigned char type;
} * attypes;
static zic_t gmtoffs[TZ_MAX_TYPES];
@@ -588,7 +600,7 @@
noise = true;
break;
case 's':
- warning(_("-s ignored\n"));
+ warning(_("-s ignored"));
break;
}
if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)
@@ -641,31 +653,44 @@
return errors ? EXIT_FAILURE : EXIT_SUCCESS;
}
-static void
+static bool
componentcheck(char const *name, char const *component,
char const *component_end)
{
enum { component_len_max = 14 };
- size_t component_len = component_end - component;
+ ptrdiff_t component_len = component_end - component;
+ if (component_len == 0) {
+ if (!*name)
+ error (_("empty file name"));
+ else
+ error (_(component == name
+ ? "file name '%s' begins with '/'"
+ : *component_end
+ ? "file name '%s' contains '//'"
+ : "file name '%s' ends with '/'"),
+ name);
+ return false;
+ }
if (0 < component_len && component_len <= 2
&& component[0] == '.' && component_end[-1] == '.') {
- fprintf(stderr, _("%s: file name '%s' contains"
- " '%.*s' component"),
- progname, name, (int) component_len, component);
- exit(EXIT_FAILURE);
+ int len = component_len;
+ error(_("file name '%s' contains '%.*s' component"),
+ name, len, component);
+ return false;
}
- if (!noise)
- return;
- if (0 < component_len && component[0] == '-')
- warning(_("file name '%s' component contains leading '-'"),
- name);
- if (component_len_max < component_len)
- warning(_("file name '%s' contains overlength component"
- " '%.*s...'"),
- name, component_len_max, component);
+ if (noise) {
+ if (0 < component_len && component[0] == '-')
+ warning(_("file name '%s' component contains leading '-'"),
+ name);
+ if (component_len_max < component_len)
+ warning(_("file name '%s' contains overlength component"
+ " '%.*s...'"),
+ name, component_len_max, component);
+ }
+ return true;
}
-static void
+static bool
namecheck(const char *name)
{
char const *cp;
@@ -689,14 +714,14 @@
? _("file name '%s' contains byte '%c'")
: _("file name '%s' contains byte '\\%o'")),
name, c);
- return;
}
if (c == '/') {
- componentcheck(name, component, cp);
+ if(!componentcheck(name, component, cp))
+ return false;
component = cp + 1;
}
}
- componentcheck(name, component, cp);
+ return componentcheck(name, component, cp);
}
static void
@@ -827,7 +852,19 @@
#define BIG_BANG (- (1LL << 59))
#endif
-static const zic_t big_bang_time = BIG_BANG;
+/* If true, work around GNOME bug 730332
+ <https://bugzilla.gnome.org/show_bug.cgi?id=730332>
+ by refusing to output time stamps before BIG_BANG.
+ Such time stamps are physically suspect anyway.
+
+ The GNOME bug is scheduled to be fixed in GNOME 3.22, and if so
+ this workaround will no longer be needed when GNOME 3.21 and
+ earlier are obsolete, say in the year 2021. */
+enum { WORK_AROUND_GNOME_BUG_730332 = true };
+
+static const zic_t early_time = (WORK_AROUND_GNOME_BUG_730332
+ ? BIG_BANG
+ : MINVAL(zic_t, TIME_T_BITS_IN_FILE));
/* Return 1 if NAME is a directory, 0 if it's something else, -1 if trouble. */
static int
@@ -931,7 +968,7 @@
** Note, though, that if there's no rule,
** a '%s' in the format is a bad thing.
*/
- if (strchr(zp->z_format, '%') != 0)
+ if (zp->z_format_specifier == 's')
error("%s", _("%s in ruleless zone"));
}
}
@@ -1004,7 +1041,7 @@
case LC_LEAP:
if (name != leapsec)
warning(
-_("%s: Leap line in non leap seconds file %s\n"),
+_("%s: Leap line in non leap seconds file %s"),
progname, name);
else inleap(fields, nfields);
wantcont = false;
@@ -1145,6 +1182,7 @@
inzsub(char **const fields, const int nfields, const int iscont)
{
char * cp;
+ char * cp1;
static struct zone z;
int i_gmtoff, i_rule, i_format;
int i_untilyear, i_untilmonth;
@@ -1160,7 +1198,9 @@
i_untilday = ZFC_TILDAY;
i_untiltime = ZFC_TILTIME;
z.z_name = NULL;
- } else {
+ } else if (!namecheck(fields[ZF_NAME]))
+ return false;
+ else {
i_gmtoff = ZF_GMTOFF;
i_rule = ZF_RULE;
i_format = ZF_FORMAT;
@@ -1174,13 +1214,21 @@
z.z_linenum = linenum;
z.z_gmtoff = gethms(fields[i_gmtoff], _("invalid UT offset"), true);
if ((cp = strchr(fields[i_format], '%')) != 0) {
- if (*++cp != 's' || strchr(cp, '%') != 0) {
+ if ((*++cp != 's' && *cp != 'z') || strchr(cp, '%')
+ || strchr(fields[i_format], '/')) {
error(_("invalid abbreviation format"));
return false;
}
}
z.z_rule = ecpyalloc(fields[i_rule]);
- z.z_format = ecpyalloc(fields[i_format]);
+ z.z_format = cp1 = ecpyalloc(fields[i_format]);
+ z.z_format_specifier = cp ? *cp : '\0';
+ if (z.z_format_specifier == 'z') {
+ if (noise)
+ warning(_("format '%s' not handled by pre-2015 versions of zic"),
+ z.z_format);
+ cp1[cp - fields[i_format]] = 's';
+ }
if (max_format_len < strlen(z.z_format))
max_format_len = strlen(z.z_format);
hasuntil = nfields > i_untilyear;
@@ -1314,7 +1362,7 @@
return;
}
t = tadd(t, tod);
- if (t < big_bang_time) {
+ if (t < early_time) {
error(_("leap second precedes Big Bang"));
return;
}
@@ -1335,10 +1383,8 @@
error(_("blank FROM field on Link line"));
return;
}
- if (*fields[LF_TO] == '\0') {
- error(_("blank TO field on Link line"));
+ if (! namecheck(fields[LF_TO]))
return;
- }
l.l_filename = filename;
l.l_linenum = linenum;
l.l_from = ecpyalloc(fields[LF_FROM]);
@@ -1559,11 +1605,13 @@
static char * fullname;
static const struct tzhead tzh0;
static struct tzhead tzh;
- zic_t *ats = emalloc(size_product(timecnt, sizeof *ats + 1));
- void *typesptr = ats + timecnt;
+ zic_t one = 1;
+ zic_t y2038_boundary = one << 31;
+ ptrdiff_t nats = timecnt + WORK_AROUND_QTBUG_53071;
+ zic_t *ats = emalloc(size_product(nats, sizeof *ats + 1));
+ void *typesptr = ats + nats;
unsigned char *types = typesptr;
- namecheck(name);
/*
** Sort.
*/
@@ -1579,7 +1627,7 @@
toi = 0;
fromi = 0;
- while (fromi < timecnt && attypes[fromi].at < big_bang_time)
Home |
Main Index |
Thread Index |
Old Index