summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Hlubek <christopher.hlubek@networkteam.com>2020-10-26 13:44:44 +0100
committerIan Lance Taylor <iant@golang.org>2020-10-29 23:29:37 +0000
commit592e24a783f7a68ce301f01401d4efb09099b205 (patch)
tree5665c97092aebe74bc3c6c28cf5d981cf3c1e79c
parentcfc89399c9e3c9409efce3d0e88f7cde58cc469d (diff)
downloadgo-git-592e24a783f7a68ce301f01401d4efb09099b205.tar.gz
[release-branch.go1.14] time: fix LoadLocationFromTZData with slim tzdata
The extend information of a time zone file with last transition < now could result in a wrong cached zone because it used the zone of the last transition. This could lead to wrong zones in systems with slim zoneinfo. Fixes #42155 Change-Id: I7c57c35b5cfa58482ac7925b5d86618c52f5444d Reviewed-on: https://go-review.googlesource.com/c/go/+/264939 Trust: Tobias Klauser <tobias.klauser@gmail.com> Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> (cherry picked from commit 70e022e4a83dc996ac4f108e811fbc399ad5565b) Reviewed-on: https://go-review.googlesource.com/c/go/+/266303 Trust: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
-rw-r--r--src/time/zoneinfo_read.go13
-rw-r--r--src/time/zoneinfo_test.go19
2 files changed, 30 insertions, 2 deletions
diff --git a/src/time/zoneinfo_read.go b/src/time/zoneinfo_read.go
index b79bd474c7..698427b779 100644
--- a/src/time/zoneinfo_read.go
+++ b/src/time/zoneinfo_read.go
@@ -311,17 +311,26 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
if tx[i].when <= sec && (i+1 == len(tx) || sec < tx[i+1].when) {
l.cacheStart = tx[i].when
l.cacheEnd = omega
+ zoneIdx := tx[i].index
if i+1 < len(tx) {
l.cacheEnd = tx[i+1].when
} else if l.extend != "" {
// If we're at the end of the known zone transitions,
// try the extend string.
- if _, _, estart, eend, ok := tzset(l.extend, l.cacheEnd, sec); ok {
+ if name, _, estart, eend, ok := tzset(l.extend, l.cacheEnd, sec); ok {
l.cacheStart = estart
l.cacheEnd = eend
+ // Find the zone that is returned by tzset,
+ // the last transition is not always the correct zone.
+ for i, z := range l.zone {
+ if z.name == name {
+ zoneIdx = uint8(i)
+ break
+ }
+ }
}
}
- l.cacheZone = &l.zone[tx[i].index]
+ l.cacheZone = &l.zone[zoneIdx]
break
}
}
diff --git a/src/time/zoneinfo_test.go b/src/time/zoneinfo_test.go
index 72829bc9fb..277b68f798 100644
--- a/src/time/zoneinfo_test.go
+++ b/src/time/zoneinfo_test.go
@@ -183,6 +183,25 @@ func TestMalformedTZData(t *testing.T) {
}
}
+func TestLoadLocationFromTZDataSlim(t *testing.T) {
+ // A 2020b slim tzdata for Europe/Berlin
+ tzData := "TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffo\xa2a\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xffѶ\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xffҡO\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd5g\xe7\x90\xff\xff\xff\xffըs\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\f\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\rLMT\x00CEST\x00CET\x00CEMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\n"
+
+ reference, err := time.LoadLocationFromTZData("Europe/Berlin", []byte(tzData))
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ d := time.Date(2020, time.October, 29, 15, 30, 0, 0, reference)
+ tzName, tzOffset := d.Zone()
+ if want := "CET"; tzName != want {
+ t.Errorf("Zone name == %s, want %s", tzName, want)
+ }
+ if want := 3600; tzOffset != want {
+ t.Errorf("Zone offset == %d, want %d", tzOffset, want)
+ }
+}
+
func TestTzset(t *testing.T) {
for _, test := range []struct {
inStr string