maxmind-db 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +13 -2
  3. data/Gemfile +8 -0
  4. data/Gemfile.lock +34 -0
  5. data/README.md +2 -2
  6. data/Rakefile +2 -0
  7. data/bin/mmdb-benchmark.rb +4 -1
  8. data/lib/maxmind/db.rb +49 -27
  9. data/lib/maxmind/db/decoder.rb +26 -26
  10. data/lib/maxmind/db/errors.rb +3 -1
  11. data/lib/maxmind/db/file_reader.rb +5 -3
  12. data/lib/maxmind/db/memory_reader.rb +3 -1
  13. data/lib/maxmind/db/metadata.rb +3 -1
  14. data/maxmind-db.gemspec +5 -2
  15. data/test/mmdb_util.rb +2 -0
  16. data/test/test_decoder.rb +2 -0
  17. data/test/test_reader.rb +117 -6
  18. metadata +7 -64
  19. data/test/data/LICENSE +0 -4
  20. data/test/data/MaxMind-DB-spec.md +0 -558
  21. data/test/data/MaxMind-DB-test-metadata-pointers.mmdb +0 -0
  22. data/test/data/README.md +0 -4
  23. data/test/data/bad-data/README.md +0 -7
  24. data/test/data/bad-data/libmaxminddb/libmaxminddb-offset-integer-overflow.mmdb +0 -0
  25. data/test/data/bad-data/maxminddb-golang/cyclic-data-structure.mmdb +0 -0
  26. data/test/data/bad-data/maxminddb-golang/invalid-bytes-length.mmdb +0 -1
  27. data/test/data/bad-data/maxminddb-golang/invalid-data-record-offset.mmdb +0 -0
  28. data/test/data/bad-data/maxminddb-golang/invalid-map-key-length.mmdb +0 -0
  29. data/test/data/bad-data/maxminddb-golang/invalid-string-length.mmdb +0 -1
  30. data/test/data/bad-data/maxminddb-golang/metadata-is-an-uint128.mmdb +0 -1
  31. data/test/data/bad-data/maxminddb-golang/unexpected-bytes.mmdb +0 -0
  32. data/test/data/perltidyrc +0 -12
  33. data/test/data/source-data/GeoIP2-Anonymous-IP-Test.json +0 -41
  34. data/test/data/source-data/GeoIP2-City-Test.json +0 -12852
  35. data/test/data/source-data/GeoIP2-Connection-Type-Test.json +0 -102
  36. data/test/data/source-data/GeoIP2-Country-Test.json +0 -11347
  37. data/test/data/source-data/GeoIP2-DensityIncome-Test.json +0 -14
  38. data/test/data/source-data/GeoIP2-Domain-Test.json +0 -452
  39. data/test/data/source-data/GeoIP2-Enterprise-Test.json +0 -673
  40. data/test/data/source-data/GeoIP2-ISP-Test.json +0 -12585
  41. data/test/data/source-data/GeoIP2-Precision-Enterprise-Test.json +0 -1598
  42. data/test/data/source-data/GeoIP2-User-Count-Test.json +0 -2824
  43. data/test/data/source-data/GeoLite2-ASN-Test.json +0 -37
  44. data/test/data/source-data/README +0 -15
  45. data/test/data/test-data/GeoIP2-Anonymous-IP-Test.mmdb +0 -0
  46. data/test/data/test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb +0 -0
  47. data/test/data/test-data/GeoIP2-City-Test-Invalid-Node-Count.mmdb +0 -0
  48. data/test/data/test-data/GeoIP2-City-Test.mmdb +0 -0
  49. data/test/data/test-data/GeoIP2-Connection-Type-Test.mmdb +0 -0
  50. data/test/data/test-data/GeoIP2-Country-Test.mmdb +0 -0
  51. data/test/data/test-data/GeoIP2-DensityIncome-Test.mmdb +0 -0
  52. data/test/data/test-data/GeoIP2-Domain-Test.mmdb +0 -0
  53. data/test/data/test-data/GeoIP2-Enterprise-Test.mmdb +0 -0
  54. data/test/data/test-data/GeoIP2-ISP-Test.mmdb +0 -0
  55. data/test/data/test-data/GeoIP2-Precision-Enterprise-Test.mmdb +0 -0
  56. data/test/data/test-data/GeoIP2-User-Count-Test.mmdb +0 -0
  57. data/test/data/test-data/GeoLite2-ASN-Test.mmdb +0 -0
  58. data/test/data/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb +0 -0
  59. data/test/data/test-data/MaxMind-DB-string-value-entries.mmdb +0 -0
  60. data/test/data/test-data/MaxMind-DB-test-broken-pointers-24.mmdb +0 -0
  61. data/test/data/test-data/MaxMind-DB-test-broken-search-tree-24.mmdb +0 -0
  62. data/test/data/test-data/MaxMind-DB-test-decoder.mmdb +0 -0
  63. data/test/data/test-data/MaxMind-DB-test-ipv4-24.mmdb +0 -0
  64. data/test/data/test-data/MaxMind-DB-test-ipv4-28.mmdb +0 -0
  65. data/test/data/test-data/MaxMind-DB-test-ipv4-32.mmdb +0 -0
  66. data/test/data/test-data/MaxMind-DB-test-ipv6-24.mmdb +0 -0
  67. data/test/data/test-data/MaxMind-DB-test-ipv6-28.mmdb +0 -0
  68. data/test/data/test-data/MaxMind-DB-test-ipv6-32.mmdb +0 -0
  69. data/test/data/test-data/MaxMind-DB-test-metadata-pointers.mmdb +0 -0
  70. data/test/data/test-data/MaxMind-DB-test-mixed-24.mmdb +0 -0
  71. data/test/data/test-data/MaxMind-DB-test-mixed-28.mmdb +0 -0
  72. data/test/data/test-data/MaxMind-DB-test-mixed-32.mmdb +0 -0
  73. data/test/data/test-data/MaxMind-DB-test-nested.mmdb +0 -0
  74. data/test/data/test-data/README.md +0 -26
  75. data/test/data/test-data/maps-with-pointers.raw +0 -0
  76. data/test/data/test-data/write-test-data.pl +0 -620
  77. data/test/data/tidyall.ini +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 604697b9d2de00a32fec3ee2b84c53703f532ecf708ca6cfcd4898fa934d830e
4
- data.tar.gz: cdaeb5d99ca07f8c9f6af0354dc23fb3f8678a40e0ea67fe74b7b7dcaabc7ec5
2
+ SHA1:
3
+ metadata.gz: e8404a64573590d7a01fd9199ae1be5bb1892407
4
+ data.tar.gz: cfdec2ef12cae84fa914784b90c386d1006fdf47
5
5
  SHA512:
6
- metadata.gz: 3939f3025d4a715537d6284ac49cfa691bf733711afd6143ec73e586aec96cbcf717115c340214903fd4a8bcc1c4b8c4973d0fa9517491b2c48c5d710cdc9e87
7
- data.tar.gz: 54dbe0bebe152e151234b0b0026492d38a80858174c3342d12ff665026d858295b29434d3ea7c8ea56b3b7c669b0d2f921c018b7dba9c16aad996143f9c66ede
6
+ metadata.gz: 263eff4235eadc529e14266772c3db95bc17950ebc7d73fbb3f5d20ee76f3b2f50035c97ad2e39454e5dbd65dd6093fc56f3a6dd3b8d91a69037b8e396986366
7
+ data.tar.gz: 8fe05ac4631539293ee2d1485fe7c1908858ef952d76e60e75d9f601f356263bb47928bc8dd670c2989df4437cb0d2a876869c662b1f4aab36d0e8a81ce19552
@@ -1,9 +1,20 @@
1
1
  # Changelog
2
2
 
3
- ## 1.0.0 - 2019-01-04
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 - 2018-12-24
18
+ ## 1.0.0.beta (2018-12-24)
19
+
9
20
  * Initial implementation.
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'minitest', group: :development
6
+ gem 'rake', group: :development
7
+ gem 'rubocop', group: :development
8
+ gem 'rubocop-performance', group: :development
@@ -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.3 or higher. Older versions may work, but
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 - 2019 by MaxMind, Inc.
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rake/testtask'
2
4
  require 'rubocop/rake_task'
3
5
 
@@ -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
- STDERR.puts "Usage: #{$PROGRAM_NAME} <MMDB file> [IP file]"
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)
@@ -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}[http://maxmind.github.io/MaxMind-DB/].
12
+ # files}[https://maxmind.github.io/MaxMind-DB/].
11
13
  #
12
- # {MaxMind DB}[http://maxmind.github.io/MaxMind-DB/] is a binary file format
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".freeze.b.freeze
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}[http://maxmind.github.io/MaxMind-DB/] as a Metadata object.
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}[http://maxmind.github.io/MaxMind-DB/]. If you're performing
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}[http://maxmind.github.io/MaxMind-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'.freeze
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}[http://maxmind.github.io/MaxMind-DB/]. The record can be one of
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
- c = packed[i >> 3].ord
172
- bit = 1 & (c >> 7 - (i % 8))
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'.freeze
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".freeze.b << buf
209
- # When we support only Ruby 2.4+, we can change String#unpack calls
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.unpack('N'.freeze)[0]
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.unpack('N'.freeze)[0] & 0x0fffffff
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.unpack('N'.freeze)[0]
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'.freeze
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?'.freeze
282
+ 'Metadata section not found. Is this a valid MaxMind DB file?'
261
283
  end
262
284
 
263
285
  def at_metadata?(index)
@@ -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}[http://maxmind.github.io/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.unpack('G'.freeze)[0], offset + 8]
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.unpack('g'.freeze)[0], offset + 4]
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)'.freeze
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>'.freeze, 4, size, offset)
69
+ decode_int('l>', 4, size, offset)
68
70
  end
69
71
 
70
72
  def decode_uint16(size, offset)
71
- decode_int('n'.freeze, 2, size, offset)
73
+ decode_int('n', 2, size, offset)
72
74
  end
73
75
 
74
76
  def decode_uint32(size, offset)
75
- decode_int('N'.freeze, 4, size, offset)
77
+ decode_int('N', 4, size, offset)
76
78
  end
77
79
 
78
80
  def decode_uint64(size, offset)
79
- decode_int('Q>'.freeze, 8, size, offset)
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".freeze) if size != type_size
87
- [buf.unpack(type_code)[0], offset + size]
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".freeze)
97
- return buf.unpack('Q>'.freeze)[0], offset + size
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".freeze)
102
+ a_bytes = buf[0...-8].rjust(8, "\x00")
101
103
  b_bytes = buf[-8...buf.length]
102
- a = a_bytes.unpack('Q>'.freeze)[0]
103
- b = b_bytes.unpack('Q>'.freeze)[0]
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.unpack('n'.freeze)[0] + @pointer_base
127
+ pointer = buf.unpack1('n') + @pointer_base
126
128
  when 1
127
129
  new_offset = offset + 2
128
- buf = "\x00".freeze.b << (size & 0x7).chr << @io.read(offset, 2)
129
- pointer = buf.unpack('N'.freeze)[0] + 2048 + @pointer_base
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.unpack('N'.freeze)[0] + 526_336 + @pointer_base
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.unpack('N'.freeze)[0] + @pointer_base
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.unpack('n'.freeze)[0]
223
+ size = 285 + size_bytes.unpack1('n')
224
224
  return size, offset + 2
225
225
  end
226
226
 
227
- size_bytes = "\x00".freeze.b << @io.read(offset, 3)
228
- size = 65_821 + size_bytes.unpack('N'.freeze)[0]
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
@@ -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}[http://maxmind.github.io/MaxMind-DB/] file is corrupt or invalid.
6
+ # DB}[https://maxmind.github.io/MaxMind-DB/] file is corrupt or invalid.
5
7
  class InvalidDatabaseError < RuntimeError
6
8
  end
7
9
  end