]> Cypherpunks repositories - gostls13.git/commitdiff
net/mail: avoid ParseDate confusion if day name includes "T"
authorEmmanuel T Odeke <emmanuel@orijtech.com>
Tue, 26 May 2020 21:14:08 +0000 (14:14 -0700)
committerEmmanuel Odeke <emmanuel@orijtech.com>
Thu, 5 Nov 2020 02:48:05 +0000 (02:48 +0000)
Fixes the check for RFC 5322 "obsolete time zone" to ensure
that we correctly extract the entire date from the "T" of the
implied time zone.

Obsolete Time zones come in the form:
* GMT
* PST
* MDT
etc, as per Section 4.3 of RFC 5322,
https://tools.ietf.org/html/rfc5322#section-4.3.

The prior check from CL 117596 erronenously used strings.Index
which selects the first "T", and that meant that dates containing
days "Tue" or "Thu" could not be parsed.

We also now deal with "T" in the CFWS "Comment Folding White Space".

Thus we'll now accept dates:
* Thu, 20 Nov 1997 09:55:06 MDT
* Thu, 20 Nov 1997 09:55:06 MDT (MDT)
* Fri, 21 Nov 1997 09:55:06 MDT (This comment)
* Fri, 21 Nov 1997 09:55:06 MDT (MDT

Fixes #39260

Change-Id: I6d59d99bc4f05a82582c826b5c5a080a25fd999b
Reviewed-on: https://go-review.googlesource.com/c/go/+/235200
Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Trust: Emmanuel Odeke <emmanuel@orijtech.com>

src/net/mail/message.go
src/net/mail/message_test.go

index 09fb794005a9b06b18b2063417364cc567b82cea..47bbf6ca9771bdcf23f3cd37357d21f721816ef3 100644 (file)
@@ -112,11 +112,25 @@ func ParseDate(date string) (time.Time, error) {
        if ind := strings.IndexAny(p.s, "+-"); ind != -1 && len(p.s) >= ind+5 {
                date = p.s[:ind+5]
                p.s = p.s[ind+5:]
-       } else if ind := strings.Index(p.s, "T"); ind != -1 && len(p.s) >= ind+1 {
-               // The last letter T of the obsolete time zone is checked when no standard time zone is found.
-               // If T is misplaced, the date to parse is garbage.
-               date = p.s[:ind+1]
-               p.s = p.s[ind+1:]
+       } else {
+               ind := strings.Index(p.s, "T")
+               if ind == 0 {
+                       // In this case we have the following date formats:
+                       // * Thu, 20 Nov 1997 09:55:06 MDT
+                       // * Thu, 20 Nov 1997 09:55:06 MDT (MDT)
+                       // * Thu, 20 Nov 1997 09:55:06 MDT (This comment)
+                       ind = strings.Index(p.s[1:], "T")
+                       if ind != -1 {
+                               ind++
+                       }
+               }
+
+               if ind != -1 && len(p.s) >= ind+5 {
+                       // The last letter T of the obsolete time zone is checked when no standard time zone is found.
+                       // If T is misplaced, the date to parse is garbage.
+                       date = p.s[:ind+1]
+                       p.s = p.s[ind+1:]
+               }
        }
        if !p.skipCFWS() {
                return time.Time{}, errors.New("mail: misformatted parenthetical comment")
index 188d0bf76630584a4544aa398542de1b3d5b9dc6..0daa3d6c63298ecdf45af27e7602e986f8efc01f 100644 (file)
@@ -102,6 +102,18 @@ func TestDateParsing(t *testing.T) {
                        "Fri, 21 Nov 1997 09:55:06 -0600 (MDT)",
                        time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)),
                },
+               {
+                       "Thu, 20 Nov 1997 09:55:06 -0600 (MDT)",
+                       time.Date(1997, 11, 20, 9, 55, 6, 0, time.FixedZone("", -6*60*60)),
+               },
+               {
+                       "Thu, 20 Nov 1997 09:55:06 MDT (MDT)",
+                       time.Date(1997, 11, 20, 9, 55, 6, 0, time.FixedZone("MDT", 0)),
+               },
+               {
+                       "Fri, 21 Nov 1997 09:55:06 +1300 (TOT)",
+                       time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", +13*60*60)),
+               },
        }
        for _, test := range tests {
                hdr := Header{
@@ -243,6 +255,33 @@ func TestDateParsingCFWS(t *testing.T) {
                        time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)),
                        false,
                },
+               // Ensure that the presence of "T" in the date
+               // doesn't trip out ParseDate, as per issue 39260.
+               {
+                       "Tue, 26 May 2020 14:04:40 GMT",
+                       time.Date(2020, 05, 26, 14, 04, 40, 0, time.UTC),
+                       true,
+               },
+               {
+                       "Tue, 26 May 2020 14:04:40 UT",
+                       time.Date(2020, 05, 26, 14, 04, 40, 0, time.UTC),
+                       false,
+               },
+               {
+                       "Thu, 21 May 2020 14:04:40 UT",
+                       time.Date(2020, 05, 21, 14, 04, 40, 0, time.UTC),
+                       false,
+               },
+               {
+                       "Thu, 21 May 2020 14:04:40 UTC",
+                       time.Date(2020, 05, 21, 14, 04, 40, 0, time.UTC),
+                       true,
+               },
+               {
+                       "Fri, 21 Nov 1997 09:55:06 MDT (MDT)",
+                       time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("MDT", 0)),
+                       true,
+               },
        }
        for _, test := range tests {
                hdr := Header{