1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package tzdata
20
21
22
23 import (
24 "errors"
25 "syscall"
26 _ "unsafe"
27 )
28
29
30
31
32 func registerLoadFromEmbeddedTZData(func(string) (string, error))
33
34 func init() {
35 registerLoadFromEmbeddedTZData(loadFromEmbeddedTZData)
36 }
37
38
39 func get4s(s string) int {
40 if len(s) < 4 {
41 return 0
42 }
43 return int(s[0]) | int(s[1])<<8 | int(s[2])<<16 | int(s[3])<<24
44 }
45
46
47 func get2s(s string) int {
48 if len(s) < 2 {
49 return 0
50 }
51 return int(s[0]) | int(s[1])<<8
52 }
53
54
55
56
57
58 func loadFromEmbeddedTZData(name string) (string, error) {
59 const (
60 zecheader = 0x06054b50
61 zcheader = 0x02014b50
62 ztailsize = 22
63
64 zheadersize = 30
65 zheader = 0x04034b50
66 )
67
68
69
70 z := zipdata
71
72 idx := len(z) - ztailsize
73 n := get2s(z[idx+10:])
74 idx = get4s(z[idx+16:])
75
76 for i := 0; i < n; i++ {
77
78 if get4s(z[idx:]) != zcheader {
79 break
80 }
81 meth := get2s(z[idx+10:])
82 size := get4s(z[idx+24:])
83 namelen := get2s(z[idx+28:])
84 xlen := get2s(z[idx+30:])
85 fclen := get2s(z[idx+32:])
86 off := get4s(z[idx+42:])
87 zname := z[idx+46 : idx+46+namelen]
88 idx += 46 + namelen + xlen + fclen
89 if zname != name {
90 continue
91 }
92 if meth != 0 {
93 return "", errors.New("unsupported compression for " + name + " in embedded tzdata")
94 }
95
96
97 idx = off
98 if get4s(z[idx:]) != zheader ||
99 get2s(z[idx+8:]) != meth ||
100 get2s(z[idx+26:]) != namelen ||
101 z[idx+30:idx+30+namelen] != name {
102 return "", errors.New("corrupt embedded tzdata")
103 }
104 xlen = get2s(z[idx+28:])
105 idx += 30 + namelen + xlen
106 return z[idx : idx+size], nil
107 }
108
109 return "", syscall.ENOENT
110 }
111
View as plain text