From: Rob Pike Date: Thu, 10 Dec 2015 18:41:08 +0000 (-0800) Subject: time: reject invalid day of month in Parse X-Git-Tag: go1.6beta1~125 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=5ef899111e581b1e57aa1546caa204d48bdf5503;p=gostls13.git time: reject invalid day of month in Parse There was back-and-forth on this but it has been decided to fix the original complaint, which was easy. Fixes #7268. Change-Id: I6b607c49ad44579086aba2c4f4c5424b97fbed64 Reviewed-on: https://go-review.googlesource.com/17710 Reviewed-by: Brad Fitzpatrick Reviewed-by: Russ Cox --- diff --git a/src/time/format.go b/src/time/format.go index 949390196a..552887609b 100644 --- a/src/time/format.go +++ b/src/time/format.go @@ -993,6 +993,11 @@ func parse(layout, value string, defaultLocation, local *Location) (Time, error) hour = 0 } + // Validate the day of the month. + if day > daysIn(Month(month), year) { + return Time{}, &ParseError{alayout, avalue, "", value, ": day of month out of range"} + } + if z != nil { return Date(year, Month(month), day, hour, min, sec, nsec, z), nil } diff --git a/src/time/format_test.go b/src/time/format_test.go index 976c1df5f7..b6ea9afe75 100644 --- a/src/time/format_test.go +++ b/src/time/format_test.go @@ -164,9 +164,6 @@ var parseTests = []ParseTest{ // GMT with offset. {"GMT-8", UnixDate, "Fri Feb 5 05:00:57 GMT-8 2010", true, true, 1, 0}, - // Day of month can be out of range. - {"Jan 36", UnixDate, "Fri Jan 36 05:00:57 GMT-8 2010", true, true, 1, 0}, - // Accept any number of fractional second digits (including none) for .999... // In Go 1, .999... was completely ignored in the format, meaning the first two // cases would succeed, but the next four would not. Go 1.1 accepts all six. @@ -196,6 +193,57 @@ func TestParse(t *testing.T) { } } +// All parsed with ANSIC. +var dayOutOfRangeTests = []struct { + date string + ok bool +}{ + {"Thu Jan 99 21:00:57 2010", false}, + {"Thu Jan 31 21:00:57 2010", true}, + {"Thu Jan 32 21:00:57 2010", false}, + {"Thu Feb 28 21:00:57 2012", true}, + {"Thu Feb 29 21:00:57 2012", true}, + {"Thu Feb 29 21:00:57 2010", false}, + {"Thu Mar 31 21:00:57 2010", true}, + {"Thu Mar 32 21:00:57 2010", false}, + {"Thu Apr 30 21:00:57 2010", true}, + {"Thu Apr 31 21:00:57 2010", false}, + {"Thu May 31 21:00:57 2010", true}, + {"Thu May 32 21:00:57 2010", false}, + {"Thu Jun 30 21:00:57 2010", true}, + {"Thu Jun 31 21:00:57 2010", false}, + {"Thu Jul 31 21:00:57 2010", true}, + {"Thu Jul 32 21:00:57 2010", false}, + {"Thu Aug 31 21:00:57 2010", true}, + {"Thu Aug 32 21:00:57 2010", false}, + {"Thu Sep 30 21:00:57 2010", true}, + {"Thu Sep 31 21:00:57 2010", false}, + {"Thu Oct 31 21:00:57 2010", true}, + {"Thu Oct 32 21:00:57 2010", false}, + {"Thu Nov 30 21:00:57 2010", true}, + {"Thu Nov 31 21:00:57 2010", false}, + {"Thu Dec 31 21:00:57 2010", true}, + {"Thu Dec 32 21:00:57 2010", false}, +} + +func TestParseDayOutOfRange(t *testing.T) { + for _, test := range dayOutOfRangeTests { + _, err := Parse(ANSIC, test.date) + switch { + case test.ok && err == nil: + // OK + case !test.ok && err != nil: + if !strings.Contains(err.Error(), "day of month out of range") { + t.Errorf("%q: expected 'day of month' error, got %v", test.date, err) + } + case test.ok && err != nil: + t.Errorf("%q: unexpected error: %v", test.date, err) + case !test.ok && err == nil: + t.Errorf("%q: expected 'day of month' error, got none", test.date) + } + } +} + func TestParseInLocation(t *testing.T) { // Check that Parse (and ParseInLocation) understand that // Feb 01 AST (Arabia Standard Time) and Feb 01 AST (Atlantic Standard Time)