From owner-svn-src-stable-11@freebsd.org Wed Sep 28 20:53:00 2016 Return-Path: Delivered-To: svn-src-stable-11@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 1FC44C01361; Wed, 28 Sep 2016 20:53:00 +0000 (UTC) (envelope-from ache@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id EC7A09E; Wed, 28 Sep 2016 20:52:59 +0000 (UTC) (envelope-from ache@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u8SKqxeK036405; Wed, 28 Sep 2016 20:52:59 GMT (envelope-from ache@FreeBSD.org) Received: (from ache@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u8SKqxYx036404; Wed, 28 Sep 2016 20:52:59 GMT (envelope-from ache@FreeBSD.org) Message-Id: <201609282052.u8SKqxYx036404@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ache set sender to ache@FreeBSD.org using -f From: "Andrey A. Chernov" Date: Wed, 28 Sep 2016 20:52:59 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r306415 - stable/11/lib/libc/stdtime X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-11@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 11-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Sep 2016 20:53:00 -0000 Author: ache Date: Wed Sep 28 20:52:58 2016 New Revision: 306415 URL: https://svnweb.freebsd.org/changeset/base/306415 Log: MFC r306075,r306109 1) Microoptimize %p case. 2) Implememt %u for GNU compatibility. 3) Don't forget to advance buf for %w/%u. 4) Fail with incomplete week (week 0) request and no such week in the year. 5) Fix yday formula when Sunday requested and the week started from Monday. 6) Fail with impossible yday for incomplete week (week 0) and direct %w/%u request. 7) Shift yday/wday to the first day of the year, if incomplete week (week 0) requested and no %w/%u used. 8) For already non-standard %z extension implement GNU compatible formats: +hh and -hh. 9) Check for incorrect values for %z. PR: 212983 (case 3 only) Modified: stable/11/lib/libc/stdtime/strptime.c Directory Properties: stable/11/ (props changed) Modified: stable/11/lib/libc/stdtime/strptime.c ============================================================================== --- stable/11/lib/libc/stdtime/strptime.c Wed Sep 28 20:49:33 2016 (r306414) +++ stable/11/lib/libc/stdtime/strptime.c Wed Sep 28 20:52:58 2016 (r306415) @@ -301,10 +301,11 @@ label: * XXX This is bogus if parsed before hour-related * specifiers. */ + if (tm->tm_hour > 12) + return (NULL); + len = strlen(tptr->am); if (strncasecmp_l(buf, tptr->am, len, locale) == 0) { - if (tm->tm_hour > 12) - return (NULL); if (tm->tm_hour == 12) tm->tm_hour = 0; buf += len; @@ -313,8 +314,6 @@ label: len = strlen(tptr->pm); if (strncasecmp_l(buf, tptr->pm, len, locale) == 0) { - if (tm->tm_hour > 12) - return (NULL); if (tm->tm_hour != 12) tm->tm_hour += 12; buf += len; @@ -374,15 +373,17 @@ label: break; + case 'u': case 'w': if (!isdigit_l((unsigned char)*buf, locale)) return (NULL); - i = *buf - '0'; - if (i > 6) + i = *buf++ - '0'; + if (i < 0 || i > 7 || (c == 'u' && i < 1) || + (c == 'w' && i > 6)) return (NULL); - tm->tm_wday = i; + tm->tm_wday = i % 7; flags |= FLAG_WDAY; break; @@ -581,10 +582,16 @@ label: i *= 10; i += *buf - '0'; buf++; + } else if (len == 2) { + i *= 100; + break; } else return (NULL); } + if (i > 1400 || (sign == -1 && i > 1200) || + (i % 100) >= 60) + return (NULL); tm->tm_hour -= sign * (i / 100); tm->tm_min -= sign * (i % 100); *GMTp = 1; @@ -609,17 +616,28 @@ label: TM_YEAR_BASE)][tm->tm_mon] + (tm->tm_mday - 1); flags |= FLAG_YDAY; } else if (day_offset != -1) { + int tmpwday, tmpyday, fwo; + + fwo = first_wday_of(tm->tm_year + TM_YEAR_BASE); + /* No incomplete week (week 0). */ + if (week_offset == 0 && fwo == day_offset) + return (NULL); + /* Set the date to the first Sunday (or Monday) * of the specified week of the year. */ - if (!(flags & FLAG_WDAY)) { - tm->tm_wday = day_offset; - flags |= FLAG_WDAY; - } - tm->tm_yday = (7 - - first_wday_of(tm->tm_year + TM_YEAR_BASE) + - day_offset) % 7 + (week_offset - 1) * 7 + - tm->tm_wday - day_offset; + tmpwday = (flags & FLAG_WDAY) ? tm->tm_wday : + day_offset; + tmpyday = (7 - fwo + day_offset) % 7 + + (week_offset - 1) * 7 + + (tmpwday - day_offset + 7) % 7; + /* Impossible yday for incomplete week (week 0). */ + if (tmpyday < 0) { + if (flags & FLAG_WDAY) + return (NULL); + tmpyday = 0; + } + tm->tm_yday = tmpyday; flags |= FLAG_YDAY; } }