Skip to content

Commit 5b023e6

Browse files
hlubekianlancetaylor
authored andcommitted
[release-branch.go1.15] 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. For #42216 Fixes #42138 Change-Id: I7c57c35b5cfa58482ac7925b5d86618c52f5444d Reviewed-on: https://go-review.googlesource.com/c/go/+/264939 Trust: Tobias Klauser <[email protected]> Run-TryBot: Tobias Klauser <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> (cherry picked from commit 70e022e) Reviewed-on: https://go-review.googlesource.com/c/go/+/266299 Trust: Ian Lance Taylor <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]> Reviewed-by: Tobias Klauser <[email protected]>
1 parent 414668c commit 5b023e6

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

src/time/zoneinfo_read.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,17 +323,26 @@ func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
323323
if tx[i].when <= sec && (i+1 == len(tx) || sec < tx[i+1].when) {
324324
l.cacheStart = tx[i].when
325325
l.cacheEnd = omega
326+
zoneIdx := tx[i].index
326327
if i+1 < len(tx) {
327328
l.cacheEnd = tx[i+1].when
328329
} else if l.extend != "" {
329330
// If we're at the end of the known zone transitions,
330331
// try the extend string.
331-
if _, _, estart, eend, ok := tzset(l.extend, l.cacheEnd, sec); ok {
332+
if name, _, estart, eend, ok := tzset(l.extend, l.cacheEnd, sec); ok {
332333
l.cacheStart = estart
333334
l.cacheEnd = eend
335+
// Find the zone that is returned by tzset,
336+
// the last transition is not always the correct zone.
337+
for i, z := range l.zone {
338+
if z.name == name {
339+
zoneIdx = uint8(i)
340+
break
341+
}
342+
}
334343
}
335344
}
336-
l.cacheZone = &l.zone[tx[i].index]
345+
l.cacheZone = &l.zone[zoneIdx]
337346
break
338347
}
339348
}

src/time/zoneinfo_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,25 @@ func TestMalformedTZData(t *testing.T) {
183183
}
184184
}
185185

186+
func TestLoadLocationFromTZDataSlim(t *testing.T) {
187+
// A 2020b slim tzdata for Europe/Berlin
188+
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"
189+
190+
reference, err := time.LoadLocationFromTZData("Europe/Berlin", []byte(tzData))
191+
if err != nil {
192+
t.Fatal(err)
193+
}
194+
195+
d := time.Date(2020, time.October, 29, 15, 30, 0, 0, reference)
196+
tzName, tzOffset := d.Zone()
197+
if want := "CET"; tzName != want {
198+
t.Errorf("Zone name == %s, want %s", tzName, want)
199+
}
200+
if want := 3600; tzOffset != want {
201+
t.Errorf("Zone offset == %d, want %d", tzOffset, want)
202+
}
203+
}
204+
186205
func TestTzset(t *testing.T) {
187206
for _, test := range []struct {
188207
inStr string

0 commit comments

Comments
 (0)