1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package tzdata
22
23
24
25 import (
26 "errors"
27 "syscall"
28 _ "unsafe"
29 )
30
31
32
33
34 func registerLoadFromEmbeddedTZData(func(string) (string, error))
35
36 func init() {
37 registerLoadFromEmbeddedTZData(loadFromEmbeddedTZData)
38 }
39
40
41 func get4s(s string) int {
42 if len(s) < 4 {
43 return 0
44 }
45 return int(s[0]) | int(s[1])<<8 | int(s[2])<<16 | int(s[3])<<24
46 }
47
48
49 func get2s(s string) int {
50 if len(s) < 2 {
51 return 0
52 }
53 return int(s[0]) | int(s[1])<<8
54 }
55
56
57
58
59
60 func loadFromEmbeddedTZData(name string) (string, error) {
61 const (
62 zecheader = 0x06054b50
63 zcheader = 0x02014b50
64 ztailsize = 22
65
66 zheadersize = 30
67 zheader = 0x04034b50
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