maxmind-db 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +13 -2
- data/Gemfile +8 -0
- data/Gemfile.lock +34 -0
- data/README.md +2 -2
- data/Rakefile +2 -0
- data/bin/mmdb-benchmark.rb +4 -1
- data/lib/maxmind/db.rb +49 -27
- data/lib/maxmind/db/decoder.rb +26 -26
- data/lib/maxmind/db/errors.rb +3 -1
- data/lib/maxmind/db/file_reader.rb +5 -3
- data/lib/maxmind/db/memory_reader.rb +3 -1
- data/lib/maxmind/db/metadata.rb +3 -1
- data/maxmind-db.gemspec +5 -2
- data/test/mmdb_util.rb +2 -0
- data/test/test_decoder.rb +2 -0
- data/test/test_reader.rb +117 -6
- metadata +7 -64
- data/test/data/LICENSE +0 -4
- data/test/data/MaxMind-DB-spec.md +0 -558
- data/test/data/MaxMind-DB-test-metadata-pointers.mmdb +0 -0
- data/test/data/README.md +0 -4
- data/test/data/bad-data/README.md +0 -7
- data/test/data/bad-data/libmaxminddb/libmaxminddb-offset-integer-overflow.mmdb +0 -0
- data/test/data/bad-data/maxminddb-golang/cyclic-data-structure.mmdb +0 -0
- data/test/data/bad-data/maxminddb-golang/invalid-bytes-length.mmdb +0 -1
- data/test/data/bad-data/maxminddb-golang/invalid-data-record-offset.mmdb +0 -0
- data/test/data/bad-data/maxminddb-golang/invalid-map-key-length.mmdb +0 -0
- data/test/data/bad-data/maxminddb-golang/invalid-string-length.mmdb +0 -1
- data/test/data/bad-data/maxminddb-golang/metadata-is-an-uint128.mmdb +0 -1
- data/test/data/bad-data/maxminddb-golang/unexpected-bytes.mmdb +0 -0
- data/test/data/perltidyrc +0 -12
- data/test/data/source-data/GeoIP2-Anonymous-IP-Test.json +0 -41
- data/test/data/source-data/GeoIP2-City-Test.json +0 -12852
- data/test/data/source-data/GeoIP2-Connection-Type-Test.json +0 -102
- data/test/data/source-data/GeoIP2-Country-Test.json +0 -11347
- data/test/data/source-data/GeoIP2-DensityIncome-Test.json +0 -14
- data/test/data/source-data/GeoIP2-Domain-Test.json +0 -452
- data/test/data/source-data/GeoIP2-Enterprise-Test.json +0 -673
- data/test/data/source-data/GeoIP2-ISP-Test.json +0 -12585
- data/test/data/source-data/GeoIP2-Precision-Enterprise-Test.json +0 -1598
- data/test/data/source-data/GeoIP2-User-Count-Test.json +0 -2824
- data/test/data/source-data/GeoLite2-ASN-Test.json +0 -37
- data/test/data/source-data/README +0 -15
- data/test/data/test-data/GeoIP2-Anonymous-IP-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb +0 -0
- data/test/data/test-data/GeoIP2-City-Test-Invalid-Node-Count.mmdb +0 -0
- data/test/data/test-data/GeoIP2-City-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-Connection-Type-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-Country-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-DensityIncome-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-Domain-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-Enterprise-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-ISP-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-Precision-Enterprise-Test.mmdb +0 -0
- data/test/data/test-data/GeoIP2-User-Count-Test.mmdb +0 -0
- data/test/data/test-data/GeoLite2-ASN-Test.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-string-value-entries.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-broken-pointers-24.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-broken-search-tree-24.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-decoder.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-ipv4-24.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-ipv4-28.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-ipv4-32.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-ipv6-24.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-ipv6-28.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-ipv6-32.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-metadata-pointers.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-mixed-24.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-mixed-28.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-mixed-32.mmdb +0 -0
- data/test/data/test-data/MaxMind-DB-test-nested.mmdb +0 -0
- data/test/data/test-data/README.md +0 -26
- data/test/data/test-data/maps-with-pointers.raw +0 -0
- data/test/data/test-data/write-test-data.pl +0 -620
- data/test/data/tidyall.ini +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e8404a64573590d7a01fd9199ae1be5bb1892407
|
4
|
+
data.tar.gz: cfdec2ef12cae84fa914784b90c386d1006fdf47
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 263eff4235eadc529e14266772c3db95bc17950ebc7d73fbb3f5d20ee76f3b2f50035c97ad2e39454e5dbd65dd6093fc56f3a6dd3b8d91a69037b8e396986366
|
7
|
+
data.tar.gz: 8fe05ac4631539293ee2d1485fe7c1908858ef952d76e60e75d9f601f356263bb47928bc8dd670c2989df4437cb0d2a876869c662b1f4aab36d0e8a81ce19552
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,20 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
## 1.
|
3
|
+
## 1.1.0 (2020-01-08)
|
4
|
+
|
5
|
+
* The method `get_with_prefix_length` was added. This method returns both
|
6
|
+
the record and the network prefix length associated with the record in
|
7
|
+
the database.
|
8
|
+
* Simplified a check for whether to return early in the decoder. Pull
|
9
|
+
request by Ivan Palamarchuk. GitHub #12.
|
10
|
+
* Support for Ruby 2.3 was dropped since it is now end of life.
|
11
|
+
|
12
|
+
## 1.0.0 (2019-01-04)
|
13
|
+
|
4
14
|
* We no longer include the database's buffer in inspect output. This avoids
|
5
15
|
showing excessive output when creating a memory reader in irb. Reported
|
6
16
|
by Wojciech Wnętrzak. GitHub #6.
|
7
17
|
|
8
|
-
## 1.0.0.beta
|
18
|
+
## 1.0.0.beta (2018-12-24)
|
19
|
+
|
9
20
|
* Initial implementation.
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
ast (2.4.0)
|
5
|
+
jaro_winkler (1.5.4)
|
6
|
+
minitest (5.13.0)
|
7
|
+
parallel (1.19.1)
|
8
|
+
parser (2.7.0.1)
|
9
|
+
ast (~> 2.4.0)
|
10
|
+
rainbow (3.0.0)
|
11
|
+
rake (13.0.1)
|
12
|
+
rubocop (0.79.0)
|
13
|
+
jaro_winkler (~> 1.5.1)
|
14
|
+
parallel (~> 1.10)
|
15
|
+
parser (>= 2.7.0.1)
|
16
|
+
rainbow (>= 2.2.2, < 4.0)
|
17
|
+
ruby-progressbar (~> 1.7)
|
18
|
+
unicode-display_width (>= 1.4.0, < 1.7)
|
19
|
+
rubocop-performance (1.5.2)
|
20
|
+
rubocop (>= 0.71.0)
|
21
|
+
ruby-progressbar (1.10.1)
|
22
|
+
unicode-display_width (1.6.0)
|
23
|
+
|
24
|
+
PLATFORMS
|
25
|
+
ruby
|
26
|
+
|
27
|
+
DEPENDENCIES
|
28
|
+
minitest
|
29
|
+
rake
|
30
|
+
rubocop
|
31
|
+
rubocop-performance
|
32
|
+
|
33
|
+
BUNDLED WITH
|
34
|
+
2.0.1
|
data/README.md
CHANGED
@@ -43,7 +43,7 @@ For more information see the
|
|
43
43
|
|
44
44
|
## Requirements
|
45
45
|
|
46
|
-
This code requires Ruby version 2.
|
46
|
+
This code requires Ruby version 2.4 or higher. Older versions may work, but
|
47
47
|
are not supported.
|
48
48
|
|
49
49
|
## Contributing
|
@@ -65,7 +65,7 @@ This library uses [Semantic Versioning](https://semver.org/).
|
|
65
65
|
|
66
66
|
## Copyright and License
|
67
67
|
|
68
|
-
This software is Copyright (c) 2018 -
|
68
|
+
This software is Copyright (c) 2018 - 2020 by MaxMind, Inc.
|
69
69
|
|
70
70
|
This is free software, licensed under the [Apache License, Version
|
71
71
|
2.0](LICENSE-APACHE) or the [MIT License](LICENSE-MIT), at your option.
|
data/Rakefile
CHANGED
data/bin/mmdb-benchmark.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'maxmind/db'
|
4
5
|
|
@@ -27,9 +28,11 @@ def parse_args
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def print_usage
|
30
|
-
|
31
|
+
# rubocop:disable Style/StderrPuts
|
32
|
+
STDERR.puts "Usage: #{$PROGRAM_NAME} <MMDB file> <IP file>"
|
31
33
|
STDERR.puts
|
32
34
|
STDERR.puts 'Benchmark by reading IPs from the IP file and looking up each one in the MMDB file.'
|
35
|
+
# rubocop:enable Style/StderrPuts
|
33
36
|
end
|
34
37
|
|
35
38
|
def benchmark(reader, file)
|
data/lib/maxmind/db.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'ipaddr'
|
2
4
|
require 'maxmind/db/decoder'
|
3
5
|
require 'maxmind/db/errors'
|
@@ -7,9 +9,9 @@ require 'maxmind/db/metadata.rb'
|
|
7
9
|
|
8
10
|
module MaxMind # :nodoc:
|
9
11
|
# DB provides a way to read {MaxMind DB
|
10
|
-
# files}[
|
12
|
+
# files}[https://maxmind.github.io/MaxMind-DB/].
|
11
13
|
#
|
12
|
-
# {MaxMind DB}[
|
14
|
+
# {MaxMind DB}[https://maxmind.github.io/MaxMind-DB/] is a binary file format
|
13
15
|
# that stores data indexed by IP address subnets (IPv4 or IPv6).
|
14
16
|
#
|
15
17
|
# This class is a pure Ruby implementation of a reader for the format.
|
@@ -49,7 +51,7 @@ module MaxMind # :nodoc:
|
|
49
51
|
|
50
52
|
DATA_SECTION_SEPARATOR_SIZE = 16
|
51
53
|
private_constant :DATA_SECTION_SEPARATOR_SIZE
|
52
|
-
METADATA_START_MARKER = "\xAB\xCD\xEFMaxMind.com".
|
54
|
+
METADATA_START_MARKER = "\xAB\xCD\xEFMaxMind.com".b.freeze
|
53
55
|
private_constant :METADATA_START_MARKER
|
54
56
|
METADATA_START_MARKER_LENGTH = 14
|
55
57
|
private_constant :METADATA_START_MARKER_LENGTH
|
@@ -57,11 +59,11 @@ module MaxMind # :nodoc:
|
|
57
59
|
private_constant :METADATA_MAX_SIZE
|
58
60
|
|
59
61
|
# Return the metadata associated with the {MaxMind
|
60
|
-
# DB}[
|
62
|
+
# DB}[https://maxmind.github.io/MaxMind-DB/] as a Metadata object.
|
61
63
|
attr_reader :metadata
|
62
64
|
|
63
65
|
# Create a DB. A DB provides a way to read {MaxMind DB
|
64
|
-
# files}[
|
66
|
+
# files}[https://maxmind.github.io/MaxMind-DB/]. If you're performing
|
65
67
|
# multiple lookups, it's most efficient to create one DB and reuse it.
|
66
68
|
#
|
67
69
|
# Once created, the DB is safe to use for lookups from multiple threads. It
|
@@ -71,7 +73,7 @@ module MaxMind # :nodoc:
|
|
71
73
|
# Creating the DB may raise an exception if initialization fails.
|
72
74
|
#
|
73
75
|
# +database+ is a path to a {MaxMind
|
74
|
-
# DB}[
|
76
|
+
# DB}[https://maxmind.github.io/MaxMind-DB/].
|
75
77
|
#
|
76
78
|
# +options+ is an option hash where each key is a symbol. The options
|
77
79
|
# control the behaviour of the DB.
|
@@ -93,7 +95,7 @@ module MaxMind # :nodoc:
|
|
93
95
|
when MODE_PARAM_IS_BUFFER
|
94
96
|
@io = MemoryReader.new(database, is_buffer: true)
|
95
97
|
else
|
96
|
-
raise ArgumentError, 'Invalid mode'
|
98
|
+
raise ArgumentError, 'Invalid mode'
|
97
99
|
end
|
98
100
|
|
99
101
|
begin
|
@@ -124,7 +126,7 @@ module MaxMind # :nodoc:
|
|
124
126
|
end
|
125
127
|
|
126
128
|
# Return the record for the +ip_address+ in the {MaxMind
|
127
|
-
# DB}[
|
129
|
+
# DB}[https://maxmind.github.io/MaxMind-DB/]. The record can be one of
|
128
130
|
# several types and depends on the contents of the database.
|
129
131
|
#
|
130
132
|
# If no record is found for +ip_address+, +get+ returns +nil+.
|
@@ -134,6 +136,25 @@ module MaxMind # :nodoc:
|
|
134
136
|
# +ip_address+ is a string in the standard notation. It may be IPv4 or
|
135
137
|
# IPv6.
|
136
138
|
def get(ip_address)
|
139
|
+
record, = get_with_prefix_length(ip_address)
|
140
|
+
|
141
|
+
record
|
142
|
+
end
|
143
|
+
|
144
|
+
# Return an array containing the record for the +ip_address+ in the
|
145
|
+
# {MaxMind DB}[https://maxmind.github.io/MaxMind-DB/] and its associated
|
146
|
+
# network prefix length. The record can be one of several types and
|
147
|
+
# depends on the contents of the database.
|
148
|
+
#
|
149
|
+
# If no record is found for +ip_address+, the record will be +nil+ and
|
150
|
+
# the prefix length will be the value for the missing network.
|
151
|
+
#
|
152
|
+
# +get_with_prefix_length+ raises an exception if there is an error
|
153
|
+
# performing the lookup.
|
154
|
+
#
|
155
|
+
# +ip_address+ is a string in the standard notation. It may be IPv4 or
|
156
|
+
# IPv6.
|
157
|
+
def get_with_prefix_length(ip_address)
|
137
158
|
ip = IPAddr.new(ip_address)
|
138
159
|
# We could check the IP has the correct prefix (32 or 128) but I do not
|
139
160
|
# for performance reasons.
|
@@ -144,10 +165,10 @@ module MaxMind # :nodoc:
|
|
144
165
|
"Error looking up #{ip}. You attempted to look up an IPv6 address in an IPv4-only database."
|
145
166
|
end
|
146
167
|
|
147
|
-
pointer = find_address_in_tree(ip, ip_version)
|
148
|
-
return nil if pointer == 0
|
168
|
+
pointer, depth = find_address_in_tree(ip, ip_version)
|
169
|
+
return nil, depth if pointer == 0
|
149
170
|
|
150
|
-
resolve_data_pointer(pointer)
|
171
|
+
[resolve_data_pointer(pointer), depth]
|
151
172
|
end
|
152
173
|
|
153
174
|
private
|
@@ -165,19 +186,22 @@ module MaxMind # :nodoc:
|
|
165
186
|
node = start_node(bit_count)
|
166
187
|
|
167
188
|
node_count = @node_count
|
168
|
-
bit_count.times do |i|
|
169
|
-
break if node >= node_count
|
170
189
|
|
171
|
-
|
172
|
-
|
190
|
+
depth = 0
|
191
|
+
loop do
|
192
|
+
break if depth >= bit_count || node >= node_count
|
193
|
+
|
194
|
+
c = packed[depth >> 3].ord
|
195
|
+
bit = 1 & (c >> 7 - (depth % 8))
|
173
196
|
node = read_node(node, bit)
|
197
|
+
depth += 1
|
174
198
|
end
|
175
199
|
|
176
|
-
return 0 if node == node_count
|
200
|
+
return 0, depth if node == node_count
|
177
201
|
|
178
|
-
return node if node > node_count
|
202
|
+
return node, depth if node > node_count
|
179
203
|
|
180
|
-
raise InvalidDatabaseError, 'Invalid node in search tree'
|
204
|
+
raise InvalidDatabaseError, 'Invalid node in search tree'
|
181
205
|
end
|
182
206
|
|
183
207
|
def start_node(length)
|
@@ -205,28 +229,26 @@ module MaxMind # :nodoc:
|
|
205
229
|
if @record_size == 24
|
206
230
|
offset = index == 0 ? base_offset : base_offset + 3
|
207
231
|
buf = @io.read(offset, 3)
|
208
|
-
node_bytes = "\x00".
|
209
|
-
|
210
|
-
# that take the first element to String#unpack1.
|
211
|
-
return node_bytes.unpack('N'.freeze)[0]
|
232
|
+
node_bytes = "\x00".b << buf
|
233
|
+
return node_bytes.unpack1('N')
|
212
234
|
end
|
213
235
|
|
214
236
|
if @record_size == 28
|
215
237
|
if index == 0
|
216
238
|
buf = @io.read(base_offset, 4)
|
217
|
-
n = buf.
|
239
|
+
n = buf.unpack1('N')
|
218
240
|
last24 = n >> 8
|
219
241
|
first4 = (n & 0xf0) << 20
|
220
242
|
return first4 | last24
|
221
243
|
end
|
222
244
|
buf = @io.read(base_offset + 3, 4)
|
223
|
-
return buf.
|
245
|
+
return buf.unpack1('N') & 0x0fffffff
|
224
246
|
end
|
225
247
|
|
226
248
|
if @record_size == 32
|
227
249
|
offset = index == 0 ? base_offset : base_offset + 4
|
228
250
|
node_bytes = @io.read(offset, 4)
|
229
|
-
return node_bytes.
|
251
|
+
return node_bytes.unpack1('N')
|
230
252
|
end
|
231
253
|
|
232
254
|
raise InvalidDatabaseError, "Unsupported record size: #{@record_size}"
|
@@ -238,7 +260,7 @@ module MaxMind # :nodoc:
|
|
238
260
|
|
239
261
|
if offset_in_file >= @size
|
240
262
|
raise InvalidDatabaseError,
|
241
|
-
'The MaxMind DB file\'s search tree is corrupt'
|
263
|
+
'The MaxMind DB file\'s search tree is corrupt'
|
242
264
|
end
|
243
265
|
|
244
266
|
data, = @decoder.decode(offset_in_file)
|
@@ -257,7 +279,7 @@ module MaxMind # :nodoc:
|
|
257
279
|
end
|
258
280
|
|
259
281
|
raise InvalidDatabaseError,
|
260
|
-
'Metadata section not found. Is this a valid MaxMind DB file?'
|
282
|
+
'Metadata section not found. Is this a valid MaxMind DB file?'
|
261
283
|
end
|
262
284
|
|
263
285
|
def at_metadata?(index)
|
data/lib/maxmind/db/decoder.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'maxmind/db/errors'
|
2
4
|
|
3
5
|
module MaxMind # :nodoc:
|
4
6
|
class DB
|
5
|
-
# +Decoder+ decodes a {MaxMind DB}[
|
7
|
+
# +Decoder+ decodes a {MaxMind DB}[https://maxmind.github.io/MaxMind-DB/]
|
6
8
|
# data section.
|
7
9
|
#
|
8
10
|
# Typically you will interact with this class through a Reader rather than
|
@@ -47,44 +49,44 @@ module MaxMind # :nodoc:
|
|
47
49
|
def decode_double(size, offset)
|
48
50
|
verify_size(8, size)
|
49
51
|
buf = @io.read(offset, 8)
|
50
|
-
[buf.
|
52
|
+
[buf.unpack1('G'), offset + 8]
|
51
53
|
end
|
52
54
|
|
53
55
|
def decode_float(size, offset)
|
54
56
|
verify_size(4, size)
|
55
57
|
buf = @io.read(offset, 4)
|
56
|
-
[buf.
|
58
|
+
[buf.unpack1('g'), offset + 4]
|
57
59
|
end
|
58
60
|
|
59
61
|
def verify_size(expected, actual)
|
60
62
|
return if expected == actual
|
61
63
|
|
62
64
|
raise InvalidDatabaseError,
|
63
|
-
'The MaxMind DB file\'s data section contains bad data (unknown data type or corrupt data)'
|
65
|
+
'The MaxMind DB file\'s data section contains bad data (unknown data type or corrupt data)'
|
64
66
|
end
|
65
67
|
|
66
68
|
def decode_int32(size, offset)
|
67
|
-
decode_int('l>'
|
69
|
+
decode_int('l>', 4, size, offset)
|
68
70
|
end
|
69
71
|
|
70
72
|
def decode_uint16(size, offset)
|
71
|
-
decode_int('n'
|
73
|
+
decode_int('n', 2, size, offset)
|
72
74
|
end
|
73
75
|
|
74
76
|
def decode_uint32(size, offset)
|
75
|
-
decode_int('N'
|
77
|
+
decode_int('N', 4, size, offset)
|
76
78
|
end
|
77
79
|
|
78
80
|
def decode_uint64(size, offset)
|
79
|
-
decode_int('Q>'
|
81
|
+
decode_int('Q>', 8, size, offset)
|
80
82
|
end
|
81
83
|
|
82
84
|
def decode_int(type_code, type_size, size, offset)
|
83
85
|
return 0, offset if size == 0
|
84
86
|
|
85
87
|
buf = @io.read(offset, size)
|
86
|
-
buf = buf.rjust(type_size, "\x00"
|
87
|
-
[buf.
|
88
|
+
buf = buf.rjust(type_size, "\x00") if size != type_size
|
89
|
+
[buf.unpack1(type_code), offset + size]
|
88
90
|
end
|
89
91
|
|
90
92
|
def decode_uint128(size, offset)
|
@@ -93,14 +95,14 @@ module MaxMind # :nodoc:
|
|
93
95
|
buf = @io.read(offset, size)
|
94
96
|
|
95
97
|
if size <= 8
|
96
|
-
buf = buf.rjust(8, "\x00"
|
97
|
-
return buf.
|
98
|
+
buf = buf.rjust(8, "\x00")
|
99
|
+
return buf.unpack1('Q>'), offset + size
|
98
100
|
end
|
99
101
|
|
100
|
-
a_bytes = buf[0...-8].rjust(8, "\x00"
|
102
|
+
a_bytes = buf[0...-8].rjust(8, "\x00")
|
101
103
|
b_bytes = buf[-8...buf.length]
|
102
|
-
a = a_bytes.
|
103
|
-
b = b_bytes.
|
104
|
+
a = a_bytes.unpack1('Q>')
|
105
|
+
b = b_bytes.unpack1('Q>')
|
104
106
|
a <<= 64
|
105
107
|
[a | b, offset + size]
|
106
108
|
end
|
@@ -122,19 +124,19 @@ module MaxMind # :nodoc:
|
|
122
124
|
when 0
|
123
125
|
new_offset = offset + 1
|
124
126
|
buf = (size & 0x7).chr << @io.read(offset, 1)
|
125
|
-
pointer = buf.
|
127
|
+
pointer = buf.unpack1('n') + @pointer_base
|
126
128
|
when 1
|
127
129
|
new_offset = offset + 2
|
128
|
-
buf = "\x00".
|
129
|
-
pointer = buf.
|
130
|
+
buf = "\x00".b << (size & 0x7).chr << @io.read(offset, 2)
|
131
|
+
pointer = buf.unpack1('N') + 2048 + @pointer_base
|
130
132
|
when 2
|
131
133
|
new_offset = offset + 3
|
132
134
|
buf = (size & 0x7).chr << @io.read(offset, 3)
|
133
|
-
pointer = buf.
|
135
|
+
pointer = buf.unpack1('N') + 526_336 + @pointer_base
|
134
136
|
else
|
135
137
|
new_offset = offset + 4
|
136
138
|
buf = @io.read(offset, 4)
|
137
|
-
pointer = buf.
|
139
|
+
pointer = buf.unpack1('N') + @pointer_base
|
138
140
|
end
|
139
141
|
|
140
142
|
return pointer, new_offset if @pointer_test
|
@@ -208,9 +210,7 @@ module MaxMind # :nodoc:
|
|
208
210
|
def size_from_ctrl_byte(ctrl_byte, offset, type_num)
|
209
211
|
size = ctrl_byte & 0x1f
|
210
212
|
|
211
|
-
return size, offset if type_num == 1
|
212
|
-
|
213
|
-
return size, offset if size < 29
|
213
|
+
return size, offset if type_num == 1 || size < 29
|
214
214
|
|
215
215
|
if size == 29
|
216
216
|
size_bytes = @io.read(offset, 1)
|
@@ -220,12 +220,12 @@ module MaxMind # :nodoc:
|
|
220
220
|
|
221
221
|
if size == 30
|
222
222
|
size_bytes = @io.read(offset, 2)
|
223
|
-
size = 285 + size_bytes.
|
223
|
+
size = 285 + size_bytes.unpack1('n')
|
224
224
|
return size, offset + 2
|
225
225
|
end
|
226
226
|
|
227
|
-
size_bytes = "\x00".
|
228
|
-
size = 65_821 + size_bytes.
|
227
|
+
size_bytes = "\x00".b << @io.read(offset, 3)
|
228
|
+
size = 65_821 + size_bytes.unpack1('N')
|
229
229
|
[size, offset + 3]
|
230
230
|
end
|
231
231
|
end
|
data/lib/maxmind/db/errors.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module MaxMind # :nodoc:
|
2
4
|
class DB
|
3
5
|
# An InvalidDatabaseError means the {MaxMind
|
4
|
-
# DB}[
|
6
|
+
# DB}[https://maxmind.github.io/MaxMind-DB/] file is corrupt or invalid.
|
5
7
|
class InvalidDatabaseError < RuntimeError
|
6
8
|
end
|
7
9
|
end
|