From patchwork Fri Dec 17 00:57:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans-Peter Nilsson X-Patchwork-Id: 49033 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 15B493858430 for ; Fri, 17 Dec 2021 00:58:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 15B493858430 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1639702696; bh=ZJpPqyqUMVXfUmBcLhWE/pthI4oEkcyGu4M3mvlzmr8=; h=To:In-Reply-To:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=wN3S5fk6Sjbmuj98hK25kedGwI+34QmiY8AUk6+uWbJ0gX6V/xNXYYgP29w+UQ59u G7/uK7YEXfZA7oXv4Lt+H+VaQREqN5sRTJouZ9iSGGPXpbfeKFnPVU9JAg8ud86D6q KT0HB3CGGGRGzenNcC+PGbdPCjvedju4LXpen9wc= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from smtp2.axis.com (smtp2.axis.com [195.60.68.18]) by sourceware.org (Postfix) with ESMTPS id 43EC2385842C for ; Fri, 17 Dec 2021 00:57:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 43EC2385842C To: In-Reply-To: <87mtldojl3.fsf@oldenburg.str.redhat.com> Subject: [PATCH v2] timezone: handle truncated timezones from tzcode-2021d and later (BZ #28707) MIME-Version: 1.0 Message-ID: <20211217005744.E099F203C8@pchp3.se.axis.com> Date: Fri, 17 Dec 2021 01:57:44 +0100 X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Hans-Peter Nilsson via Libc-alpha From: Hans-Peter Nilsson Reply-To: Hans-Peter Nilsson Cc: Christopher.Wong@axis.com Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" I'm assisting Christopher, who sent the first version; this one includes a test-case and a bugzilla report reference. We're both covered by Axis' copyright assignment. Tested on x86_64-linux (Debian 9). brgds, H-P 8< ------------------------------------------------------ >8 When using a timezone file generated by the zic in IANA tzcode-2021d a.k.a. tzlib-2021d (also in tzlib-2021e; current as of this writing), glibc asserts in __tzfile_read (on e.g. tzset() for this file) and you may find lines matching "tzfile.c:435: __tzfile_read: Assertion `num_types == 1' failed" in your syslog. Attached is a test-case including the tzfile for Asuncion generated by tzlib-2021e as follows, using the tzlib-2021e zic: "zic -d DEST -r @1546300800 -L /dev/null -b slim SOURCE/southamerica". Note that in its type 2 header, it has two entries in its "time-types" array (types), but only one entry in its "transition types" array (type_idxs). This is valid and expected already in the published RFC8536, and not even frowned upon: "Local time for timestamps before the first transition is specified by the first time type (time type 0)" ... "every nonzero local time type index SHOULD appear at least once in the transition type array". Note the "nonzero ... index". Until the 2021d zic, index 0 has been shared by the first valid transition but with 2021d it's separate, set apart as a placeholder and only "implicitly" indexed. (A draft update of the RFC mandates that the entry at index 0 is a placeholder in this case, hence can no longer be shared.) * time/tzfile.c: Don't assert when no transitions are found. * timezone/Makefile, timezone/tst-pr28707.c, timezone/testdata/XT5: New test. Co-authored-by: Christopher Wong --- time/tzfile.c | 4 ++-- timezone/Makefile | 4 +++- timezone/testdata/XT5 | Bin 0 -> 156 bytes timezone/tst-bz28707.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 timezone/testdata/XT5 create mode 100644 timezone/tst-bz28707.c diff --git a/time/tzfile.c b/time/tzfile.c index 190a777152b3..8668392ad387 100644 --- a/time/tzfile.c +++ b/time/tzfile.c @@ -431,8 +431,8 @@ __tzfile_read (const char *file, size_t extra, char **extrap) if (__tzname[0] == NULL) { /* This should only happen if there are no transition rules. - In this case there should be only one single type. */ - assert (num_types == 1); + In this case there's usually only one single type, unless + e.g. the data file has a truncated time-range. */ __tzname[0] = __tzstring (zone_names); } if (__tzname[1] == NULL) diff --git a/timezone/Makefile b/timezone/Makefile index c624a189b322..369b3e1698ba 100644 --- a/timezone/Makefile +++ b/timezone/Makefile @@ -23,7 +23,7 @@ subdir := timezone include ../Makeconfig others := zdump zic -tests := test-tz tst-timezone tst-tzset +tests := test-tz tst-timezone tst-tzset tst-bz28707 generated-dirs += testdata @@ -85,10 +85,12 @@ $(objpfx)tst-timezone.out: $(addprefix $(testdata)/, \ America/Sao_Paulo Asia/Tokyo \ Europe/London) $(objpfx)tst-tzset.out: $(addprefix $(testdata)/XT, 1 2 3 4) +$(objpfx)tst-bz28707.out: $(testdata)/XT5 test-tz-ENV = TZDIR=$(testdata) tst-timezone-ENV = TZDIR=$(testdata) tst-tzset-ENV = TZDIR=$(testdata) +tst-bz28707-ENV = TZDIR=$(testdata) # Note this must come second in the deps list for $(built-program-cmd) to work. zic-deps = $(objpfx)zic $(leapseconds) yearistype diff --git a/timezone/testdata/XT5 b/timezone/testdata/XT5 new file mode 100644 index 0000000000000000000000000000000000000000..aadcd6dccab37d1177d2c0ca725ea56c5dc7ca48 GIT binary patch literal 156 zcmWHE%1kq2AP5+NDnJ+nLI`UCDP;m;4v_j7t+fqMz5oATy}-z#Yhb{jYhcX4Wut3g cVrK#*jqP-N4Gr`R^$he4bbO8VOh61S07fYg0{{R3 literal 0 HcmV?d00001 diff --git a/timezone/tst-bz28707.c b/timezone/tst-bz28707.c new file mode 100644 index 000000000000..0a9df1e9a094 --- /dev/null +++ b/timezone/tst-bz28707.c @@ -0,0 +1,46 @@ +/* Copyright (C) 2021 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 + . */ + +#include +#include +#include +#include + +/* Test that we can use a truncated timezone-file, where the time-type + at index 0 is not indexed by the transition-types array (and the + transition-types array does not contain at least both one DST and one + normal time members). */ + +static int +do_test (void) +{ + if (setenv ("TZ", "XT5", 1)) + { + puts ("setenv failed."); + return 1; + } + + tzset (); + + return + /* Sanity-check that we got the right timezone-name for DST. For + normal time, we're likely to get "-00" (the "unspecified" marker), + even though the POSIX timezone string says "-04". Let's not test + that. */ + !(strcmp (tzname[1], "-03") == 0); +} +#include