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