Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 Sep 2016 20:54:47 +0000 (UTC)
From:      "Andrey A. Chernov" <ache@FreeBSD.org>
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
Message-ID:  <201609282054.u8SKslxN036549@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;
 		}
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201609282054.u8SKslxN036549>