From owner-svn-src-stable@freebsd.org Wed Sep 28 20:54:48 2016 Return-Path: Delivered-To: svn-src-stable@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 42DF9C013E2; Wed, 28 Sep 2016 20:54:48 +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 20E48283; Wed, 28 Sep 2016 20:54:48 +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 u8SKslRR036550; Wed, 28 Sep 2016 20:54:47 GMT (envelope-from ache@FreeBSD.org) Received: (from ache@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u8SKslxN036549; Wed, 28 Sep 2016 20:54:47 GMT (envelope-from ache@FreeBSD.org) Message-Id: <201609282054.u8SKslxN036549@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:54:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r306416 - stable/9/lib/libc/stdtime X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Sep 2016 20:54:48 -0000 Author: ache Date: Wed Sep 28 20:54:47 2016 New Revision: 306416 URL: https://svnweb.freebsd.org/changeset/base/306416 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/9/lib/libc/stdtime/strptime.c Directory Properties: stable/9/ (props changed) stable/9/lib/ (props changed) stable/9/lib/libc/ (props changed) stable/9/lib/libc/stdtime/ (props changed) Modified: stable/9/lib/libc/stdtime/strptime.c ============================================================================== --- stable/9/lib/libc/stdtime/strptime.c Wed Sep 28 20:52:58 2016 (r306415) +++ stable/9/lib/libc/stdtime/strptime.c Wed Sep 28 20:54:47 2016 (r306416) @@ -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; } }