maxmind-db 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -0
  3. data/README.dev.md +13 -5
  4. data/README.md +2 -3
  5. data/bin/mmdb-benchmark.rb +3 -3
  6. data/lib/maxmind/db/decoder.rb +3 -0
  7. data/lib/maxmind/db/file_reader.rb +29 -11
  8. data/lib/maxmind/db.rb +9 -10
  9. data/maxmind-db.gemspec +4 -3
  10. data/test/data/MaxMind-DB-spec.md +15 -11
  11. data/test/data/bad-data/maxminddb-python/bad-unicode-in-map-key.mmdb +0 -0
  12. data/test/data/source-data/GeoIP2-Anonymous-IP-Test.json +1 -0
  13. data/test/data/source-data/GeoIP2-City-Test.json +81 -48
  14. data/test/data/source-data/GeoIP2-Connection-Type-Test.json +20 -0
  15. data/test/data/source-data/GeoIP2-Country-Test.json +46 -58
  16. data/test/data/source-data/GeoIP2-Enterprise-Test.json +78 -6
  17. data/test/data/source-data/GeoIP2-ISP-Test.json +13 -1
  18. data/test/data/source-data/GeoIP2-Precision-Enterprise-Test.json +200 -13
  19. data/test/data/source-data/GeoLite2-ASN-Test.json +4091 -8
  20. data/test/data/source-data/GeoLite2-City-Test.json +12804 -0
  21. data/test/data/source-data/GeoLite2-Country-Test.json +11280 -0
  22. data/test/data/test-data/GeoIP2-Anonymous-IP-Test.mmdb +0 -0
  23. data/test/data/test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb +0 -0
  24. data/test/data/test-data/GeoIP2-City-Test-Invalid-Node-Count.mmdb +0 -0
  25. data/test/data/test-data/GeoIP2-City-Test.mmdb +0 -0
  26. data/test/data/test-data/GeoIP2-Connection-Type-Test.mmdb +0 -0
  27. data/test/data/test-data/GeoIP2-Country-Test.mmdb +0 -0
  28. data/test/data/test-data/GeoIP2-DensityIncome-Test.mmdb +0 -0
  29. data/test/data/test-data/GeoIP2-Domain-Test.mmdb +0 -0
  30. data/test/data/test-data/GeoIP2-Enterprise-Test.mmdb +0 -0
  31. data/test/data/test-data/GeoIP2-ISP-Test.mmdb +0 -0
  32. data/test/data/test-data/GeoIP2-Precision-Enterprise-Test.mmdb +0 -0
  33. data/test/data/test-data/GeoIP2-Static-IP-Score-Test.mmdb +0 -0
  34. data/test/data/test-data/GeoIP2-User-Count-Test.mmdb +0 -0
  35. data/test/data/test-data/GeoLite2-ASN-Test.mmdb +0 -0
  36. data/test/data/test-data/GeoLite2-City-Test.mmdb +0 -0
  37. data/test/data/test-data/GeoLite2-Country-Test.mmdb +0 -0
  38. data/test/data/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb +0 -0
  39. data/test/data/test-data/MaxMind-DB-string-value-entries.mmdb +0 -0
  40. data/test/data/test-data/MaxMind-DB-test-broken-pointers-24.mmdb +0 -0
  41. data/test/data/test-data/MaxMind-DB-test-broken-search-tree-24.mmdb +0 -0
  42. data/test/data/test-data/MaxMind-DB-test-decoder.mmdb +0 -0
  43. data/test/data/test-data/MaxMind-DB-test-ipv4-24.mmdb +0 -0
  44. data/test/data/test-data/MaxMind-DB-test-ipv4-28.mmdb +0 -0
  45. data/test/data/test-data/MaxMind-DB-test-ipv4-32.mmdb +0 -0
  46. data/test/data/test-data/MaxMind-DB-test-ipv6-24.mmdb +0 -0
  47. data/test/data/test-data/MaxMind-DB-test-ipv6-28.mmdb +0 -0
  48. data/test/data/test-data/MaxMind-DB-test-ipv6-32.mmdb +0 -0
  49. data/test/data/test-data/MaxMind-DB-test-metadata-pointers.mmdb +0 -0
  50. data/test/data/test-data/MaxMind-DB-test-mixed-24.mmdb +0 -0
  51. data/test/data/test-data/MaxMind-DB-test-mixed-28.mmdb +0 -0
  52. data/test/data/test-data/MaxMind-DB-test-mixed-32.mmdb +0 -0
  53. data/test/data/test-data/MaxMind-DB-test-nested.mmdb +0 -0
  54. data/test/data/test-data/MaxMind-DB-test-pointer-decoder.mmdb +0 -0
  55. data/test/data/test-data/README.md +3 -3
  56. data/test/data/test-data/write-test-data.pl +77 -22
  57. data/test/test_decoder.rb +6 -6
  58. data/test/test_reader.rb +22 -13
  59. metadata +12 -7
  60. data/test/data/MaxMind-DB-test-metadata-pointers.mmdb +0 -0
@@ -10,17 +10,17 @@ pointers to map keys and values, as well as to the whole map.
10
10
 
11
11
  There are several ways to figure out what IP addresses are actually in the
12
12
  test databases. You can take a look at the
13
- [source-data directory](https://github.com/maxmind/MaxMind-DB/tree/master/source-data)
13
+ [source-data directory](https://github.com/maxmind/MaxMind-DB/tree/main/source-data)
14
14
  in this repository. This directory contains JSON files which are used to
15
15
  generate many (but not all) of the database files.
16
16
 
17
17
  You can also use the
18
- [mmdb-dump-database script](https://github.com/maxmind/MaxMind-DB-Reader-perl/blob/master/eg/mmdb-dump-database)
18
+ [mmdb-dump-database script](https://github.com/maxmind/MaxMind-DB-Reader-perl/blob/main/eg/mmdb-dump-database)
19
19
  in the
20
20
  [MaxMind-DB-Reader-perl repository](https://github.com/maxmind/MaxMind-DB-Reader-perl).
21
21
 
22
22
  Some databases are intentionally broken and cannot be dumped. You can look at
23
23
  the
24
- [script which generates these databases](https://github.com/maxmind/MaxMind-DB/blob/master/test-data/write-test-data.pl)
24
+ [script which generates these databases](https://github.com/maxmind/MaxMind-DB/blob/main/test-data/write-test-data.pl)
25
25
  to see what IP addresses they include, which will be necessary for those
26
26
  databases which cannot be dumped because they contain intentional errors.
@@ -19,7 +19,7 @@ use Test::MaxMind::DB::Common::Util qw( standard_test_metadata );
19
19
  my $Dir = dirname( abs_path($0) );
20
20
 
21
21
  sub main {
22
- my @sizes = ( 24, 28, 32 );
22
+ my @sizes = ( 24, 28, 32 );
23
23
  my @ipv4_range = ( '1.1.1.1', '1.1.1.32' );
24
24
 
25
25
  my @ipv4_subnets = Net::Works::Network->range_as_subnets(@ipv4_range);
@@ -71,6 +71,7 @@ sub main {
71
71
  }
72
72
 
73
73
  write_decoder_test_db();
74
+ write_pointer_decoder_test_db();
74
75
  write_deeply_nested_structures_db();
75
76
 
76
77
  write_geoip2_dbs();
@@ -231,23 +232,7 @@ sub write_test_db {
231
232
  );
232
233
 
233
234
  sub write_decoder_test_db {
234
- my $writer = MaxMind::DB::Writer::Tree->new(
235
- ip_version => 6,
236
- record_size => 24,
237
- database_type => 'MaxMind DB Decoder Test',
238
- languages => ['en'],
239
- description => {
240
- en =>
241
- 'MaxMind DB Decoder Test database - contains every MaxMind DB data type',
242
- },
243
- alias_ipv6_to_ipv4 => 1,
244
- remove_reserved_networks => 0,
245
- map_key_type_callback => sub {
246
- my $key = $_[0];
247
- $key =~ s/X$//;
248
- return $key eq 'array' ? [ 'array', 'uint32' ] : $key;
249
- },
250
- );
235
+ my $writer = _decoder_writer();
251
236
 
252
237
  my @subnets
253
238
  = map { Net::Works::Network->new_from_string( string => $_ ) }
@@ -258,7 +243,7 @@ sub write_test_db {
258
243
  ::4.5.6.7/128
259
244
  abcd::/64
260
245
  1000::1234:0000/112
261
- );
246
+ );
262
247
 
263
248
  for my $subnet (@subnets) {
264
249
  $writer->insert_network(
@@ -285,6 +270,70 @@ sub write_test_db {
285
270
 
286
271
  return;
287
272
  }
273
+
274
+ sub write_pointer_decoder_test_db {
275
+
276
+ # We want to create a database where most values are pointers
277
+ no warnings 'redefine';
278
+ local *MaxMind::DB::Writer::Serializer::_should_cache_value
279
+ = sub { 1 };
280
+ my $writer = _decoder_writer();
281
+
282
+ # We add these slightly different records so that we end up with
283
+ # pointers for the individual values in the maps, not just pointers
284
+ # to the map
285
+ $writer->insert_network(
286
+ '1.0.0.0/32',
287
+ {
288
+ %all_types,
289
+ booleanX => 0,
290
+ arrayX => [ 1, 2, 3, 4, ],
291
+ mapXX => {
292
+ utf8_stringX => 'hello',
293
+ arrayX => [ 7, 8, 9, 10 ],
294
+ booleanX => 0,
295
+ },
296
+ },
297
+ );
298
+
299
+ $writer->insert_network(
300
+ '1.1.1.0/32',
301
+ {
302
+ %all_types,
303
+
304
+ # This has to be 0 rather than 1 as otherwise the buggy
305
+ # Perl writer will think it is the same as an uint32 value of
306
+ # 1 and make a pointer to a value of a different type.
307
+ boolean => 0,
308
+ },
309
+ );
310
+
311
+ open my $fh, '>', "$Dir/MaxMind-DB-test-pointer-decoder.mmdb";
312
+ $writer->write_tree($fh);
313
+ close $fh;
314
+
315
+ return;
316
+ }
317
+
318
+ sub _decoder_writer {
319
+ return MaxMind::DB::Writer::Tree->new(
320
+ ip_version => 6,
321
+ record_size => 24,
322
+ database_type => 'MaxMind DB Decoder Test',
323
+ languages => ['en'],
324
+ description => {
325
+ en =>
326
+ 'MaxMind DB Decoder Test database - contains every MaxMind DB data type',
327
+ },
328
+ alias_ipv6_to_ipv4 => 1,
329
+ remove_reserved_networks => 0,
330
+ map_key_type_callback => sub {
331
+ my $key = $_[0];
332
+ $key =~ s/X*$//;
333
+ return $key eq 'array' ? [ 'array', 'uint32' ] : $key;
334
+ },
335
+ );
336
+ }
288
337
  }
289
338
 
290
339
  {
@@ -330,7 +379,7 @@ sub write_test_db {
330
379
  ::4.5.6.7/128
331
380
  abcd::/64
332
381
  1000::1234:0000/112
333
- );
382
+ );
334
383
 
335
384
  for my $subnet (@subnets) {
336
385
  $writer->insert_network(
@@ -362,6 +411,8 @@ sub write_geoip2_dbs {
362
411
  ['GeoIP2-Static-IP-Score'],
363
412
  ['GeoIP2-User-Count'],
364
413
  ['GeoLite2-ASN'],
414
+ ['GeoLite2-City'],
415
+ ['GeoLite2-Country'],
365
416
  );
366
417
  }
367
418
 
@@ -427,6 +478,7 @@ sub _universal_map_key_type_callback {
427
478
  is_in_european_union => 'boolean',
428
479
  is_legitimate_proxy => 'boolean',
429
480
  is_public_proxy => 'boolean',
481
+ is_residential_proxy => 'boolean',
430
482
  is_satellite_provider => 'boolean',
431
483
  is_tor_exit_node => 'boolean',
432
484
  iso_code => 'utf8_string',
@@ -435,6 +487,8 @@ sub _universal_map_key_type_callback {
435
487
  location => 'map',
436
488
  longitude => 'double',
437
489
  metro_code => 'uint16',
490
+ mobile_country_code => 'utf8_string',
491
+ mobile_network_code => 'utf8_string',
438
492
  names => 'map',
439
493
  organization => 'utf8_string',
440
494
  population_density => 'uint32',
@@ -442,6 +496,7 @@ sub _universal_map_key_type_callback {
442
496
  registered_country => 'map',
443
497
  represented_country => 'map',
444
498
  score => 'double',
499
+ static_ip_score => 'double',
445
500
  subdivisions => [ 'array', 'map' ],
446
501
  time_zone => 'utf8_string',
447
502
  traits => 'map',
@@ -604,7 +659,7 @@ sub write_test_serialization_data {
604
659
  $serializer->store_data( map => { long_key => 'long_value1' } );
605
660
  $serializer->store_data( map => { long_key2 => 'long_value2' } );
606
661
 
607
- open my $fh, '>', 'maps-with-pointers.raw';
662
+ open my $fh, '>', "$Dir/maps-with-pointers.raw";
608
663
  print {$fh} ${ $serializer->buffer() }
609
664
  or die "Cannot write to maps-with-pointers.raw: $!";
610
665
  close $fh;
@@ -630,7 +685,7 @@ sub write_db_with_metadata_pointers {
630
685
 
631
686
  _populate_all_networks( $writer, {} );
632
687
 
633
- open my $fh, '>', 'MaxMind-DB-test-metadata-pointers.mmdb';
688
+ open my $fh, '>', "$Dir/MaxMind-DB-test-metadata-pointers.mmdb";
634
689
 
635
690
  $writer->write_tree($fh);
636
691
 
data/test/test_decoder.rb CHANGED
@@ -150,9 +150,9 @@ class DecoderTest < Minitest::Test
150
150
  "\x34\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34".b +
151
151
  "\x35\x36\x37\x38\x39\x30\x31\x32\x33\x34\x35".b +
152
152
  "\x36\x37\x38\x39\x30".b => '123456789012345678901234567890',
153
- "\x5e\x00\xd7".b + "\x78".b * 500 => 'x' * 500,
154
- "\x5e\x06\xb3".b + "\x78".b * 2000 => 'x' * 2000,
155
- "\x5f\x00\x10\x53".b + "\x78".b * 70_000 => 'x' * 70_000,
153
+ "\x5e\x00\xd7".b + ("\x78".b * 500) => 'x' * 500,
154
+ "\x5e\x06\xb3".b + ("\x78".b * 2000) => 'x' * 2000,
155
+ "\x5f\x00\x10\x53".b + ("\x78".b * 70_000) => 'x' * 70_000,
156
156
  }
157
157
  # rubocop:enable Style/ClassVars
158
158
 
@@ -194,9 +194,9 @@ class DecoderTest < Minitest::Test
194
194
  "\x02".b + ctrl_byte + "\x01\xf4".b => 500,
195
195
  "\x02".b + ctrl_byte + "\x2a\x78".b => 10_872,
196
196
  }
197
- (bits / 8 + 1).times do |power|
198
- expected = 2**(8 * power) - 1
199
- input = [power].pack('C') + ctrl_byte + "\xff".b * power
197
+ ((bits / 8) + 1).times do |power|
198
+ expected = (2**(8 * power)) - 1
199
+ input = [power].pack('C') + ctrl_byte + ("\xff".b * power)
200
200
  uints[input] = expected
201
201
  end
202
202
  uints
data/test/test_reader.rb CHANGED
@@ -12,10 +12,11 @@ class ReaderTest < Minitest::Test
12
12
  ]
13
13
 
14
14
  modes.each do |mode|
15
- [24, 28, 32].each do |record_size|
16
- [4, 6].each do |ip_version|
17
- filename = 'test/data/test-data/MaxMind-DB-test-ipv' +
18
- ip_version.to_s + '-' + record_size.to_s + '.mmdb'
15
+ record_sizes = [24, 28, 32]
16
+ record_sizes.each do |record_size|
17
+ ip_versions = [4, 6]
18
+ ip_versions.each do |ip_version|
19
+ filename = "test/data/test-data/MaxMind-DB-test-ipv#{ip_version}-#{record_size}.mmdb"
19
20
  reader = MaxMind::DB.new(filename, mode: mode)
20
21
  check_metadata(reader, ip_version, record_size)
21
22
  if ip_version == 4
@@ -134,7 +135,7 @@ class ReaderTest < Minitest::Test
134
135
  }]
135
136
 
136
137
  tests.each do |test|
137
- reader = MaxMind::DB.new('test/data/test-data/' + test['file_name'])
138
+ reader = MaxMind::DB.new("test/data/test-data/#{test['file_name']}")
138
139
  record, prefix_length = reader.get_with_prefix_length(test['ip'])
139
140
 
140
141
  assert_equal(test['expected_prefix_length'], prefix_length,
@@ -179,6 +180,14 @@ class ReaderTest < Minitest::Test
179
180
  reader.close
180
181
  end
181
182
 
183
+ def test_metadata_pointers
184
+ reader = MaxMind::DB.new(
185
+ 'test/data/test-data/MaxMind-DB-test-metadata-pointers.mmdb'
186
+ )
187
+ assert_equal('Lots of pointers in metadata', reader.metadata.database_type)
188
+ reader.close
189
+ end
190
+
182
191
  def test_no_ipv4_search_tree
183
192
  reader = MaxMind::DB.new(
184
193
  'test/data/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb'
@@ -235,7 +244,7 @@ class ReaderTest < Minitest::Test
235
244
  e = assert_raises ArgumentError do
236
245
  reader.get('not_ip')
237
246
  end
238
- assert(e.message.match(/invalid address/))
247
+ assert(e.message.include?('invalid address'))
239
248
  reader.close
240
249
  end
241
250
 
@@ -243,7 +252,7 @@ class ReaderTest < Minitest::Test
243
252
  e = assert_raises SystemCallError do
244
253
  MaxMind::DB.new('file-does-not-exist.mmdb')
245
254
  end
246
- assert(e.message.match(/No such file or directory/))
255
+ assert(e.message.include?('No such file or directory'))
247
256
  end
248
257
 
249
258
  def test_nondatabase
@@ -260,14 +269,14 @@ class ReaderTest < Minitest::Test
260
269
  e = assert_raises ArgumentError do
261
270
  MaxMind::DB.new('README.md', {}, 'blah')
262
271
  end
263
- assert(e.message.match(/wrong number of arguments/))
272
+ assert(e.message.include?('wrong number of arguments'))
264
273
  end
265
274
 
266
275
  def test_no_constructor_args
267
276
  e = assert_raises ArgumentError do
268
277
  MaxMind::DB.new
269
278
  end
270
- assert(e.message.match(/wrong number of arguments/))
279
+ assert(e.message.include?('wrong number of arguments'))
271
280
  end
272
281
 
273
282
  def test_too_many_get_args
@@ -277,7 +286,7 @@ class ReaderTest < Minitest::Test
277
286
  e = assert_raises ArgumentError do
278
287
  reader.get('1.1.1.1', 'blah')
279
288
  end
280
- assert(e.message.match(/wrong number of arguments/))
289
+ assert(e.message.include?('wrong number of arguments'))
281
290
  reader.close
282
291
  end
283
292
 
@@ -288,7 +297,7 @@ class ReaderTest < Minitest::Test
288
297
  e = assert_raises ArgumentError do
289
298
  reader.get
290
299
  end
291
- assert(e.message.match(/wrong number of arguments/))
300
+ assert(e.message.include?('wrong number of arguments'))
292
301
  reader.close
293
302
  end
294
303
 
@@ -299,7 +308,7 @@ class ReaderTest < Minitest::Test
299
308
  e = assert_raises ArgumentError do
300
309
  reader.metadata('hi')
301
310
  end
302
- assert(e.message.match(/wrong number of arguments/))
311
+ assert(e.message.include?('wrong number of arguments'))
303
312
  reader.close
304
313
  end
305
314
 
@@ -310,7 +319,7 @@ class ReaderTest < Minitest::Test
310
319
  e = assert_raises NoMethodError do
311
320
  reader.metadata.what
312
321
  end
313
- assert(e.message.match(/undefined method `what'/))
322
+ assert(e.message.include?('undefined method `what\''))
314
323
  reader.close
315
324
  end
316
325
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maxmind-db
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Storey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-23 00:00:00.000000000 Z
11
+ date: 2023-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -90,7 +90,6 @@ files:
90
90
  - maxmind-db.gemspec
91
91
  - test/data/LICENSE
92
92
  - test/data/MaxMind-DB-spec.md
93
- - test/data/MaxMind-DB-test-metadata-pointers.mmdb
94
93
  - test/data/README.md
95
94
  - test/data/bad-data/README.md
96
95
  - test/data/bad-data/libmaxminddb/libmaxminddb-offset-integer-overflow.mmdb
@@ -101,6 +100,7 @@ files:
101
100
  - test/data/bad-data/maxminddb-golang/invalid-string-length.mmdb
102
101
  - test/data/bad-data/maxminddb-golang/metadata-is-an-uint128.mmdb
103
102
  - test/data/bad-data/maxminddb-golang/unexpected-bytes.mmdb
103
+ - test/data/bad-data/maxminddb-python/bad-unicode-in-map-key.mmdb
104
104
  - test/data/perltidyrc
105
105
  - test/data/source-data/GeoIP2-Anonymous-IP-Test.json
106
106
  - test/data/source-data/GeoIP2-City-Test.json
@@ -114,6 +114,8 @@ files:
114
114
  - test/data/source-data/GeoIP2-Static-IP-Score-Test.json
115
115
  - test/data/source-data/GeoIP2-User-Count-Test.json
116
116
  - test/data/source-data/GeoLite2-ASN-Test.json
117
+ - test/data/source-data/GeoLite2-City-Test.json
118
+ - test/data/source-data/GeoLite2-Country-Test.json
117
119
  - test/data/source-data/README
118
120
  - test/data/test-data/GeoIP2-Anonymous-IP-Test.mmdb
119
121
  - test/data/test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb
@@ -129,6 +131,8 @@ files:
129
131
  - test/data/test-data/GeoIP2-Static-IP-Score-Test.mmdb
130
132
  - test/data/test-data/GeoIP2-User-Count-Test.mmdb
131
133
  - test/data/test-data/GeoLite2-ASN-Test.mmdb
134
+ - test/data/test-data/GeoLite2-City-Test.mmdb
135
+ - test/data/test-data/GeoLite2-Country-Test.mmdb
132
136
  - test/data/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb
133
137
  - test/data/test-data/MaxMind-DB-string-value-entries.mmdb
134
138
  - test/data/test-data/MaxMind-DB-test-broken-pointers-24.mmdb
@@ -145,6 +149,7 @@ files:
145
149
  - test/data/test-data/MaxMind-DB-test-mixed-28.mmdb
146
150
  - test/data/test-data/MaxMind-DB-test-mixed-32.mmdb
147
151
  - test/data/test-data/MaxMind-DB-test-nested.mmdb
152
+ - test/data/test-data/MaxMind-DB-test-pointer-decoder.mmdb
148
153
  - test/data/test-data/README.md
149
154
  - test/data/test-data/maps-with-pointers.raw
150
155
  - test/data/test-data/write-test-data.pl
@@ -158,10 +163,11 @@ licenses:
158
163
  - MIT
159
164
  metadata:
160
165
  bug_tracker_uri: https://github.com/maxmind/MaxMind-DB-Reader-ruby/issues
161
- changelog_uri: https://github.com/maxmind/MaxMind-DB-Reader-ruby/blob/master/CHANGELOG.md
166
+ changelog_uri: https://github.com/maxmind/MaxMind-DB-Reader-ruby/blob/main/CHANGELOG.md
162
167
  documentation_uri: https://www.rubydoc.info/gems/maxmind-db
163
168
  homepage_uri: https://github.com/maxmind/MaxMind-DB-Reader-ruby
164
169
  source_code_uri: https://github.com/maxmind/MaxMind-DB-Reader-ruby
170
+ rubygems_mfa_required: 'true'
165
171
  post_install_message:
166
172
  rdoc_options: []
167
173
  require_paths:
@@ -170,15 +176,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
170
176
  requirements:
171
177
  - - ">="
172
178
  - !ruby/object:Gem::Version
173
- version: 2.4.0
179
+ version: 2.5.0
174
180
  required_rubygems_version: !ruby/object:Gem::Requirement
175
181
  requirements:
176
182
  - - ">="
177
183
  - !ruby/object:Gem::Version
178
184
  version: '0'
179
185
  requirements: []
180
- rubyforge_project:
181
- rubygems_version: 2.7.6.2
186
+ rubygems_version: 3.4.18
182
187
  signing_key:
183
188
  specification_version: 4
184
189
  summary: A gem for reading MaxMind DB files.