1
1
package ipdb
2
2
3
3
import (
4
- "os"
5
4
"encoding/binary"
6
- "errors"
7
5
"encoding/json"
6
+ "errors"
8
7
"io/ioutil"
9
8
"net"
10
- "strings "
9
+ "os "
11
10
"reflect"
12
- "unsafe "
11
+ "strings "
13
12
"time"
13
+ "unsafe"
14
14
)
15
15
16
16
const IPv4 = 0x01
@@ -26,25 +26,25 @@ var (
26
26
ErrIPFormat = errors .New ("Query IP Format error." )
27
27
28
28
ErrNoSupportLanguage = errors .New ("language not support" )
29
- ErrNoSupportIPv4 = errors .New ("IPv4 not support" )
30
- ErrNoSupportIPv6 = errors .New ("IPv6 not support" )
29
+ ErrNoSupportIPv4 = errors .New ("IPv4 not support" )
30
+ ErrNoSupportIPv6 = errors .New ("IPv6 not support" )
31
31
32
32
ErrDataNotExists = errors .New ("data is not exists" )
33
33
)
34
34
35
35
type MetaData struct {
36
- Build int64 `json:"build"`
37
- IPVersion uint16 `json:"ip_version"`
38
- Languages map [string ]int `json:"languages"`
39
- NodeCount int `json:"node_count"`
40
- TotalSize int `json:"total_size"`
41
- Fields []string `json:"fields"`
36
+ Build int64 `json:"build"`
37
+ IPVersion uint16 `json:"ip_version"`
38
+ Languages map [string ]int `json:"languages"`
39
+ NodeCount int `json:"node_count"`
40
+ TotalSize int `json:"total_size"`
41
+ Fields []string `json:"fields"`
42
42
}
43
43
44
44
type reader struct {
45
- fileSize int
45
+ fileSize int
46
46
nodeCount int
47
- v4offset int
47
+ v4offset int
48
48
49
49
meta MetaData
50
50
data []byte
@@ -60,20 +60,25 @@ func newReader(name string, obj interface{}) (*reader, error) {
60
60
return nil , err
61
61
}
62
62
fileSize := int (fileInfo .Size ())
63
-
63
+ if fileSize < 4 {
64
+ return nil , ErrFileSize
65
+ }
64
66
body , err := ioutil .ReadFile (name )
65
67
if err != nil {
66
68
return nil , ErrReadFull
67
69
}
68
70
var meta MetaData
69
71
metaLength := int (binary .BigEndian .Uint32 (body [0 :4 ]))
72
+ if fileSize < (4 + metaLength ) {
73
+ return nil , ErrFileSize
74
+ }
70
75
if err := json .Unmarshal (body [4 :4 + metaLength ], & meta ); err != nil {
71
76
return nil , err
72
77
}
73
78
if len (meta .Languages ) == 0 || len (meta .Fields ) == 0 {
74
79
return nil , ErrMetaData
75
80
}
76
- if fileSize != (4 + metaLength + meta .TotalSize ) {
81
+ if fileSize != (4 + metaLength + meta .TotalSize ) {
77
82
return nil , ErrFileSize
78
83
}
79
84
@@ -88,10 +93,10 @@ func newReader(name string, obj interface{}) (*reader, error) {
88
93
}
89
94
90
95
db := & reader {
91
- fileSize : fileSize ,
96
+ fileSize : fileSize ,
92
97
nodeCount : meta .NodeCount ,
93
98
94
- meta :meta ,
99
+ meta : meta ,
95
100
refType : dm ,
96
101
97
102
data : body [4 + metaLength :],
@@ -182,7 +187,7 @@ func (db *reader) find1(addr, language string) ([]string, error) {
182
187
return nil , ErrDatabaseError
183
188
}
184
189
185
- return tmp [off : off + len (db .meta .Fields )], nil
190
+ return tmp [off : off + len (db .meta .Fields )], nil
186
191
}
187
192
188
193
func (db * reader ) search (ip net.IP , bitCount int ) (int , error ) {
@@ -192,15 +197,15 @@ func (db *reader) search(ip net.IP, bitCount int) (int, error) {
192
197
if bitCount == 32 {
193
198
node = db .v4offset
194
199
} else {
195
- node = 0 ;
200
+ node = 0
196
201
}
197
202
198
203
for i := 0 ; i < bitCount ; i ++ {
199
204
if node > db .nodeCount {
200
205
break
201
206
}
202
207
203
- node = db .readNode (node , ((0xFF & int (ip [i >> 3 ])) >> uint (7 - ( i % 8 ))) & 1 )
208
+ node = db .readNode (node , ((0xFF & int (ip [i >> 3 ]))>> uint (7 - ( i % 8 )))& 1 )
204
209
}
205
210
206
211
if node > db .nodeCount {
@@ -211,21 +216,21 @@ func (db *reader) search(ip net.IP, bitCount int) (int, error) {
211
216
}
212
217
213
218
func (db * reader ) readNode (node , index int ) int {
214
- off := node * 8 + index * 4
215
- return int (binary .BigEndian .Uint32 (db .data [off : off + 4 ]))
219
+ off := node * 8 + index * 4
220
+ return int (binary .BigEndian .Uint32 (db .data [off : off + 4 ]))
216
221
}
217
222
218
223
func (db * reader ) resolve (node int ) ([]byte , error ) {
219
- resolved := node - db .nodeCount + db .nodeCount * 8
224
+ resolved := node - db .nodeCount + db .nodeCount * 8
220
225
if resolved >= db .fileSize {
221
226
return nil , ErrDatabaseError
222
227
}
223
228
224
- size := int (binary .BigEndian .Uint16 (db .data [resolved : resolved + 2 ]))
225
- if (resolved + 2 + size ) > len (db .data ) {
229
+ size := int (binary .BigEndian .Uint16 (db .data [resolved : resolved + 2 ]))
230
+ if (resolved + 2 + size ) > len (db .data ) {
226
231
return nil , ErrDatabaseError
227
232
}
228
- bytes := db .data [resolved + 2 : resolved + 2 + size ]
233
+ bytes := db .data [resolved + 2 : resolved + 2 + size ]
229
234
230
235
return bytes , nil
231
236
}
@@ -248,4 +253,4 @@ func (db *reader) Languages() []string {
248
253
ls = append (ls , k )
249
254
}
250
255
return ls
251
- }
256
+ }
0 commit comments