From 2ce8411239212b80a0d266dc123bb5b1ec84d211 Mon Sep 17 00:00:00 2001 From: Alberto Donizetti Date: Sun, 24 Jun 2018 13:42:59 +0200 Subject: [PATCH] time: accept anything between -23 and 23 as offset namezone name time.Parse currently rejects numeric timezones names with UTC offsets bigger than +12, but this is incorrect: there's a +13 timezone and a +14 timezone: $ zdump Pacific/Kiritimati Pacific/Kiritimati Mon Jun 25 02:15:03 2018 +14 For convenience, this cl changes the ranges of accepted offsets from -14..+12 to -23..+23 (zero still excluded), i.e. every possible offset that makes sense. We don't validate three-letter abbreviations for the timezones names, so there's no need to be too strict on numeric names. This change also fixes a bug in the parseTimeZone, that is currently unconditionally returning true (i.e. valid timezone), without checking the value returned by parseSignedOffset. This fixes 5 of 17 time.Parse() failures listed in Issue #26032. Updates #26032 Change-Id: I2f08ca9aa41ea4c6149ed35ed2dd8f23eeb42bff Reviewed-on: https://go-review.googlesource.com/120558 Reviewed-by: Rob Pike --- src/time/format.go | 9 +++++---- src/time/format_test.go | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/time/format.go b/src/time/format.go index 237f28738b..f9cdbab3b8 100644 --- a/src/time/format.go +++ b/src/time/format.go @@ -1120,7 +1120,8 @@ func parseTimeZone(value string) (length int, ok bool) { // Special Case 3: Some time zones are not named, but have +/-00 format if value[0] == '+' || value[0] == '-' { length = parseSignedOffset(value) - return length, true + ok := length > 0 // parseSignedOffset returns 0 in case of bad input + return length, ok } // How many upper-case letters are there? Need at least three, at most five. var nUpper int @@ -1152,7 +1153,7 @@ func parseTimeZone(value string) (length int, ok bool) { // parseGMT parses a GMT time zone. The input string is known to start "GMT". // The function checks whether that is followed by a sign and a number in the -// range -14 through 12 excluding zero. +// range -23 through +23 excluding zero. func parseGMT(value string) int { value = value[3:] if len(value) == 0 { @@ -1163,7 +1164,7 @@ func parseGMT(value string) int { } // parseSignedOffset parses a signed timezone offset (e.g. "+03" or "-04"). -// The function checks for a signed number in the range -14 through +12 excluding zero. +// The function checks for a signed number in the range -23 through +23 excluding zero. // Returns length of the found offset string or 0 otherwise func parseSignedOffset(value string) int { sign := value[0] @@ -1177,7 +1178,7 @@ func parseSignedOffset(value string) int { if sign == '-' { x = -x } - if x == 0 || x < -14 || 12 < x { + if x == 0 || x < -23 || 23 < x { return 0 } return len(value) - len(rem) diff --git a/src/time/format_test.go b/src/time/format_test.go index 68a4d3ddb0..c3552f4161 100644 --- a/src/time/format_test.go +++ b/src/time/format_test.go @@ -427,8 +427,18 @@ var parseTimeZoneTests = []ParseTimeZoneTest{ {"ESASTT hi", 0, false}, // run of upper-case letters too long. {"ESATY hi", 0, false}, // five letters must end in T. {"WITA hi", 4, true}, // Issue #18251 - {"+03 hi", 3, true}, // Issue #24071 - {"-04 hi", 3, true}, // Issue #24071 + // Issue #24071 + {"+03 hi", 3, true}, + {"-04 hi", 3, true}, + // Issue #26032 + {"-11", 3, true}, + {"-12", 3, true}, + {"-23", 3, true}, + {"-24", 0, false}, + {"+13", 3, true}, + {"+14", 3, true}, + {"+23", 3, true}, + {"+24", 0, false}, } func TestParseTimeZone(t *testing.T) { -- 2.50.0