Source file
src/net/netip/slow_test.go
1
2
3
4
5 package netip_test
6
7 import (
8 "fmt"
9 . "net/netip"
10 "strconv"
11 "strings"
12 )
13
14
15
16
17 var zeros = []string{"0", "0", "0", "0", "0", "0", "0", "0"}
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 func parseIPSlow(s string) (Addr, error) {
41
42
43 var zone string
44 fs := strings.Split(s, "%")
45 switch len(fs) {
46 case 1:
47
48 case 2:
49 s, zone = fs[0], fs[1]
50 if zone == "" {
51 return Addr{}, fmt.Errorf("netaddr.ParseIP(%q): no zone after zone specifier", s)
52 }
53 default:
54 return Addr{}, fmt.Errorf("netaddr.ParseIP(%q): too many zone specifiers", s)
55 }
56
57
58 if strings.Count(s, ":") == 0 {
59 if zone != "" {
60 return Addr{}, fmt.Errorf("netaddr.ParseIP(%q): IPv4 addresses cannot have a zone", s)
61 }
62 return parseIPv4Slow(s)
63 }
64
65 normal, err := normalizeIPv6Slow(s)
66 if err != nil {
67 return Addr{}, err
68 }
69
70
71
72 fs = strings.Split(normal, ":")
73 if len(fs) != 8 {
74 return Addr{}, fmt.Errorf("netaddr.ParseIP(%q): wrong size address", s)
75 }
76 var ret [16]byte
77 for i, f := range fs {
78 a, b, err := parseWord(f)
79 if err != nil {
80 return Addr{}, err
81 }
82 ret[i*2] = a
83 ret[i*2+1] = b
84 }
85
86 return AddrFrom16(ret).WithZone(zone), nil
87 }
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107 func normalizeIPv6Slow(orig string) (string, error) {
108 s := orig
109
110
111 i := strings.LastIndex(s, ":")
112 if i == -1 {
113 return "", fmt.Errorf("netaddr.ParseIP(%q): invalid IP address", orig)
114 }
115 if strings.Contains(s[i+1:], ".") {
116 ip, err := parseIPv4Slow(s[i+1:])
117 if err != nil {
118 return "", err
119 }
120 a4 := ip.As4()
121 s = fmt.Sprintf("%s:%02x%02x:%02x%02x", s[:i], a4[0], a4[1], a4[2], a4[3])
122 }
123
124
125 fs := strings.Split(s, "::")
126 switch len(fs) {
127 case 1:
128
129 case 2:
130 lhs, rhs := fs[0], fs[1]
131
132
133 nblocks := strings.Count(lhs, ":") + strings.Count(rhs, ":")
134 if lhs != "" {
135 nblocks++
136 }
137 if rhs != "" {
138 nblocks++
139 }
140 if nblocks > 7 {
141 return "", fmt.Errorf("netaddr.ParseIP(%q): address too long", orig)
142 }
143 fs = nil
144
145
146 if lhs != "" {
147 fs = append(fs, lhs)
148 }
149 fs = append(fs, zeros[:8-nblocks]...)
150 if rhs != "" {
151 fs = append(fs, rhs)
152 }
153 s = strings.Join(fs, ":")
154 default:
155
156 return "", fmt.Errorf("netaddr.ParseIP(%q): invalid IP address", orig)
157 }
158
159 return s, nil
160 }
161
162
163
164
165
166 func parseIPv4Slow(s string) (Addr, error) {
167 fs := strings.Split(s, ".")
168 if len(fs) != 4 {
169 return Addr{}, fmt.Errorf("netaddr.ParseIP(%q): invalid IP address", s)
170 }
171 var ret [4]byte
172 for i := range ret {
173 val, err := strconv.ParseUint(fs[i], 10, 8)
174 if err != nil {
175 return Addr{}, err
176 }
177 ret[i] = uint8(val)
178 }
179 return AddrFrom4([4]byte{ret[0], ret[1], ret[2], ret[3]}), nil
180 }
181
182
183
184 func parseWord(s string) (byte, byte, error) {
185 if len(s) > 4 {
186 return 0, 0, fmt.Errorf("parseWord(%q): invalid word", s)
187 }
188 ret, err := strconv.ParseUint(s, 16, 16)
189 if err != nil {
190 return 0, 0, err
191 }
192 return uint8(ret >> 8), uint8(ret), nil
193 }
194
View as plain text