]> Cypherpunks repositories - gostls13.git/commitdiff
time: fix misleading error with the leading zero format
authorLE Manh Cuong <cuong.manhle.vn@gmail.com>
Wed, 30 Jan 2019 05:38:15 +0000 (12:38 +0700)
committerIan Lance Taylor <iant@golang.org>
Fri, 26 Apr 2019 14:01:55 +0000 (14:01 +0000)
When the leading zero format is used, we currently don't handle the
month and year properly.

For the month, we were reporting an out of range error when getnum
returns zero of its own, as it also returns the month 0. That's
confusing, so only check the range when getnum returns a nil error.

For the year, we don't restore the value when parsing error occurs. For
example, with the incorrect input "111-01", "01" will be used to report
an error. So restore the value when an error occurs fix the problem.

Fixes #29918
Fixes #29916

Change-Id: I3145f8c46813a0457766b7c302482e6b56f94ed6
Reviewed-on: https://go-review.googlesource.com/c/go/+/160338
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/time/format.go
src/time/format_test.go

index d8e295f696e436e9e659ffdf2b833efbf130bfbd..b531cb47604f04a83399d8cbd22e96c8126af140 100644 (file)
@@ -865,9 +865,12 @@ func parse(layout, value string, defaultLocation, local *Location) (Time, error)
                                err = errBad
                                break
                        }
+                       hold := value
                        p, value = value[0:2], value[2:]
                        year, err = atoi(p)
-                       if year >= 69 { // Unix time starts Dec 31 1969 in some time zones
+                       if err != nil {
+                               value = hold
+                       } else if year >= 69 { // Unix time starts Dec 31 1969 in some time zones
                                year += 1900
                        } else {
                                year += 2000
@@ -887,7 +890,7 @@ func parse(layout, value string, defaultLocation, local *Location) (Time, error)
                        month++
                case stdNumMonth, stdZeroMonth:
                        month, value, err = getnum(value, std == stdZeroMonth)
-                       if month <= 0 || 12 < month {
+                       if err == nil && (month <= 0 || 12 < month) {
                                rangeErrString = "month"
                        }
                case stdWeekDay:
index 516099266c8f2d58d5e4327f69505de2618b4506..c08ff87d10064dd5865057df158002dc060e649a 100644 (file)
@@ -710,3 +710,49 @@ func TestUnderscoreTwoThousand(t *testing.T) {
                t.Errorf("Incorrect minute, got %d", m)
        }
 }
+
+// Issue 29918, 29916
+func TestStd0xParseError(t *testing.T) {
+       tests := []struct {
+               format, value, valueElemPrefix string
+       }{
+               {"01 MST", "0 MST", "0"},
+               {"01 MST", "1 MST", "1"},
+               {RFC850, "Thursday, 04-Feb-1 21:00:57 PST", "1"},
+       }
+       for _, tt := range tests {
+               _, err := Parse(tt.format, tt.value)
+               if err == nil {
+                       t.Errorf("Parse(%q, %q) did not fail as expected", tt.format, tt.value)
+               } else if perr, ok := err.(*ParseError); !ok {
+                       t.Errorf("Parse(%q, %q) returned error type %T, expected ParseError", tt.format, tt.value, perr)
+               } else if !strings.Contains(perr.Error(), "cannot parse") || !strings.HasPrefix(perr.ValueElem, tt.valueElemPrefix) {
+                       t.Errorf("Parse(%q, %q) returned wrong parsing error message: %v", tt.format, tt.value, perr)
+               }
+       }
+}
+
+var monthOutOfRangeTests = []struct {
+       value string
+       ok    bool
+}{
+       {"00-01", false},
+       {"13-01", false},
+       {"01-01", true},
+}
+
+func TestParseMonthOutOfRange(t *testing.T) {
+       for _, test := range monthOutOfRangeTests {
+               _, err := Parse("01-02", test.value)
+               switch {
+               case !test.ok && err != nil:
+                       if !strings.Contains(err.Error(), "month out of range") {
+                               t.Errorf("%q: expected 'month' error, got %v", test.value, err)
+                       }
+               case test.ok && err != nil:
+                       t.Errorf("%q: unexpected error: %v", test.value, err)
+               case !test.ok && err == nil:
+                       t.Errorf("%q: expected 'month' error, got none", test.value)
+               }
+       }
+}