@@ -4,7 +4,7 @@ var bigInt = require("big-integer");
4
4
var https = require ( "https" ) ;
5
5
6
6
// For BIN queries
7
- const VERSION = "9.2 .0" ;
7
+ const VERSION = "9.3 .0" ;
8
8
const MAX_INDEX = 65536 ;
9
9
const COUNTRY_POSITION = [
10
10
0 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,
@@ -269,6 +269,11 @@ class IP2Location {
269
269
return this . readBin ( readBytes , position - 1 , "int8" ) ;
270
270
}
271
271
272
+ // Read 8 bits integer in the buffer
273
+ read8Row ( position , buffer ) {
274
+ return buffer . readUInt8 ( position ) ;
275
+ }
276
+
272
277
// Read 32 bits integer in the database
273
278
read32 ( position , isBigInt ) {
274
279
let readBytes = 4 ;
@@ -280,6 +285,29 @@ class IP2Location {
280
285
return buffer . readUInt32LE ( position ) ;
281
286
}
282
287
288
+ // Read 128 bits integer in the buffer
289
+ read128Row ( position , buffer ) {
290
+ let myBig = bigInt ( ) ; // zero
291
+ let bitShift = 8 ;
292
+ for ( let x = 0 ; x < 16 ; x ++ ) {
293
+ let pos = position + x ;
294
+ myBig = myBig . add (
295
+ bigInt ( this . read8Row ( pos , buffer ) ) . shiftLeft ( bitShift * x )
296
+ ) ;
297
+ }
298
+ return myBig ;
299
+ }
300
+
301
+ read32Or128Row ( position , buffer , len ) {
302
+ if ( len == 4 ) {
303
+ return this . read32Row ( position , buffer ) ;
304
+ } else if ( len == 16 ) {
305
+ return this . read128Row ( position , buffer ) ;
306
+ } else {
307
+ return 0 ;
308
+ }
309
+ }
310
+
283
311
read32Or128 ( position , ipType ) {
284
312
if ( ipType == 4 ) {
285
313
return this . read32 ( position , true ) ;
@@ -303,12 +331,10 @@ class IP2Location {
303
331
304
332
// Read strings in the database
305
333
readStr ( position ) {
306
- let readBytes = 1 ;
307
- return this . readBin (
308
- this . readBin ( readBytes , position , "int8" ) ,
309
- position + 1 ,
310
- "str"
311
- ) ;
334
+ let readBytes = 256 ; // max size of string field + 1 byte for the length
335
+ let row = this . readRow ( readBytes , position + 1 ) ;
336
+ let len = this . read8Row ( 0 , row ) ;
337
+ return row . toString ( "utf8" , 1 , len + 1 ) ;
312
338
}
313
339
314
340
// Read metadata and indexes
@@ -319,21 +345,24 @@ class IP2Location {
319
345
if ( this . #binFile && this . #binFile != "" ) {
320
346
this . #fd = fs . openSync ( this . #binFile, "r" ) ;
321
347
322
- this . #myDB. dbType = this . read8 ( 1 ) ;
323
- this . #myDB. dbColumn = this . read8 ( 2 ) ;
324
- this . #myDB. dbYear = this . read8 ( 3 ) ;
325
- this . #myDB. dbMonth = this . read8 ( 4 ) ;
326
- this . #myDB. dbDay = this . read8 ( 5 ) ;
327
- this . #myDB. dbCount = this . read32 ( 6 ) ;
328
- this . #myDB. baseAddress = this . read32 ( 10 ) ;
329
- this . #myDB. dbCountIPV6 = this . read32 ( 14 ) ;
330
- this . #myDB. baseAddressIPV6 = this . read32 ( 18 ) ;
331
- this . #myDB. indexBaseAddress = this . read32 ( 22 ) ;
332
- this . #myDB. indexBaseAddressIPV6 = this . read32 ( 26 ) ;
333
- this . #myDB. productCode = this . read8 ( 30 ) ;
348
+ let len = 64 ; // 64-byte header
349
+ let row = this . readRow ( len , 1 ) ;
350
+
351
+ this . #myDB. dbType = this . read8Row ( 0 , row ) ;
352
+ this . #myDB. dbColumn = this . read8Row ( 1 , row ) ;
353
+ this . #myDB. dbYear = this . read8Row ( 2 , row ) ;
354
+ this . #myDB. dbMonth = this . read8Row ( 3 , row ) ;
355
+ this . #myDB. dbDay = this . read8Row ( 4 , row ) ;
356
+ this . #myDB. dbCount = this . read32Row ( 5 , row ) ;
357
+ this . #myDB. baseAddress = this . read32Row ( 9 , row ) ;
358
+ this . #myDB. dbCountIPV6 = this . read32Row ( 13 , row ) ;
359
+ this . #myDB. baseAddressIPV6 = this . read32Row ( 17 , row ) ;
360
+ this . #myDB. indexBaseAddress = this . read32Row ( 21 , row ) ;
361
+ this . #myDB. indexBaseAddressIPV6 = this . read32Row ( 25 , row ) ;
362
+ this . #myDB. productCode = this . read8Row ( 29 , row ) ;
334
363
// below 2 fields just read for now, not being used yet
335
- this . #myDB. productType = this . read8 ( 31 ) ;
336
- this . #myDB. fileSize = this . read32 ( 32 ) ;
364
+ this . #myDB. productType = this . read8Row ( 30 , row ) ;
365
+ this . #myDB. fileSize = this . read32Row ( 31 , row ) ;
337
366
338
367
// check if is correct BIN (should be 1 for IP2Location BIN file), also checking for zipped file (PK being the first 2 chars)
339
368
if (
@@ -434,20 +463,28 @@ class IP2Location {
434
463
this . #categoryEnabled = CATEGORY_POSITION [ dbt ] != 0 ? 1 : 0 ;
435
464
436
465
if ( this . #myDB. indexed == 1 ) {
437
- let pointer = this . #myDB. indexBaseAddress ;
466
+ len = MAX_INDEX ;
467
+ if ( this . #myDB. indexedIPV6 == 1 ) {
468
+ len += MAX_INDEX ;
469
+ }
470
+ len *= 8 ; // 4 bytes for both From/To
471
+
472
+ row = this . readRow ( len , this . #myDB. indexBaseAddress ) ;
473
+
474
+ let pointer = 0 ;
438
475
439
476
for ( let x = 0 ; x < MAX_INDEX ; x ++ ) {
440
477
this . #indexArrayIPV4[ x ] = Array ( 2 ) ;
441
- this . #indexArrayIPV4[ x ] [ 0 ] = this . read32 ( pointer ) ;
442
- this . #indexArrayIPV4[ x ] [ 1 ] = this . read32 ( pointer + 4 ) ;
478
+ this . #indexArrayIPV4[ x ] [ 0 ] = this . read32Row ( pointer , row ) ;
479
+ this . #indexArrayIPV4[ x ] [ 1 ] = this . read32Row ( pointer + 4 , row ) ;
443
480
pointer += 8 ;
444
481
}
445
482
446
- if ( this . #myDB. indexBaseAddressIPV6 > 0 ) {
483
+ if ( this . #myDB. indexedIPV6 == 1 ) {
447
484
for ( let x = 0 ; x < MAX_INDEX ; x ++ ) {
448
485
this . #indexArrayIPV6[ x ] = Array ( 2 ) ;
449
- this . #indexArrayIPV6[ x ] [ 0 ] = this . read32 ( pointer ) ;
450
- this . #indexArrayIPV6[ x ] [ 1 ] = this . read32 ( pointer + 4 ) ;
486
+ this . #indexArrayIPV6[ x ] [ 0 ] = this . read32Row ( pointer , row ) ;
487
+ this . #indexArrayIPV6[ x ] [ 1 ] = this . read32Row ( pointer + 4 , row ) ;
451
488
pointer += 8 ;
452
489
}
453
490
}
@@ -509,8 +546,9 @@ class IP2Location {
509
546
let rowOffset2 ;
510
547
let ipFrom ;
511
548
let ipTo ;
512
- let firstCol ;
549
+ let firstCol = 4 ; // IP From is 4 bytes
513
550
let row ;
551
+ let fullRow ;
514
552
515
553
if ( ipType == 4 ) {
516
554
MAX_IP_RANGE = MAX_IPV4_RANGE ;
@@ -519,9 +557,11 @@ class IP2Location {
519
557
columnSize = this . #ipV4ColumnSize;
520
558
ipNumber = dot2Num ( myIP ) ;
521
559
522
- indexAddress = ipNumber >>> 16 ;
523
- low = this . #indexArrayIPV4[ indexAddress ] [ 0 ] ;
524
- high = this . #indexArrayIPV4[ indexAddress ] [ 1 ] ;
560
+ if ( this . #myDB. indexed == 1 ) {
561
+ indexAddress = ipNumber >>> 16 ;
562
+ low = this . #indexArrayIPV4[ indexAddress ] [ 0 ] ;
563
+ high = this . #indexArrayIPV4[ indexAddress ] [ 1 ] ;
564
+ }
525
565
} else if ( ipType == 6 ) {
526
566
MAX_IP_RANGE = MAX_IPV6_RANGE ;
527
567
high = this . #myDB. dbCountIPV6 ;
@@ -544,16 +584,20 @@ class IP2Location {
544
584
} else {
545
585
ipNumber = ipNumber . not ( ) . and ( LAST_32_BITS ) . toJSNumber ( ) ;
546
586
}
547
- indexAddress = ipNumber >>> 16 ;
548
- low = this . #indexArrayIPV4[ indexAddress ] [ 0 ] ;
549
- high = this . #indexArrayIPV4[ indexAddress ] [ 1 ] ;
587
+ if ( this . #myDB. indexed == 1 ) {
588
+ indexAddress = ipNumber >>> 16 ;
589
+ low = this . #indexArrayIPV4[ indexAddress ] [ 0 ] ;
590
+ high = this . #indexArrayIPV4[ indexAddress ] [ 1 ] ;
591
+ }
550
592
} else {
551
- indexAddress = ipNumber . shiftRight ( 112 ) . toJSNumber ( ) ;
552
- low = this . #indexArrayIPV6[ indexAddress ] [ 0 ] ;
553
- high = this . #indexArrayIPV6[ indexAddress ] [ 1 ] ;
593
+ firstCol = 16 ; // IPv6 is 16 bytes
594
+ if ( this . #myDB. indexedIPV6 == 1 ) {
595
+ indexAddress = ipNumber . shiftRight ( 112 ) . toJSNumber ( ) ;
596
+ low = this . #indexArrayIPV6[ indexAddress ] [ 0 ] ;
597
+ high = this . #indexArrayIPV6[ indexAddress ] [ 1 ] ;
598
+ }
554
599
}
555
600
}
556
-
557
601
data . ip = myIP ;
558
602
ipNumber = bigInt ( ipNumber ) ;
559
603
@@ -564,25 +608,23 @@ class IP2Location {
564
608
data . ipNo = ipNumber . toString ( ) ;
565
609
566
610
while ( low <= high ) {
567
- mid = parseInt ( ( low + high ) / 2 ) ;
611
+ mid = Math . trunc ( ( low + high ) / 2 ) ;
568
612
rowOffset = baseAddress + mid * columnSize ;
569
613
rowOffset2 = rowOffset + columnSize ;
570
614
571
- ipFrom = this . read32Or128 ( rowOffset , ipType ) ;
572
- ipTo = this . read32Or128 ( rowOffset2 , ipType ) ;
615
+ // reading IP From + whole row + next IP From
616
+ fullRow = this . readRow ( columnSize + firstCol , rowOffset ) ;
617
+ ipFrom = this . read32Or128Row ( 0 , fullRow , firstCol ) ;
618
+ ipTo = this . read32Or128Row ( columnSize , fullRow , firstCol ) ;
573
619
574
620
ipFrom = bigInt ( ipFrom ) ;
575
621
ipTo = bigInt ( ipTo ) ;
576
622
577
623
if ( ipFrom . leq ( ipNumber ) && ipTo . gt ( ipNumber ) ) {
578
624
loadMesg ( data , MSG_NOT_SUPPORTED ) ; // load default message
579
625
580
- firstCol = 4 ;
581
- if ( ipType == 6 ) {
582
- firstCol = 16 ;
583
- }
584
-
585
- row = this . readRow ( columnSize - firstCol , rowOffset + firstCol ) ;
626
+ let rowLen = columnSize - firstCol ;
627
+ row = fullRow . subarray ( firstCol , firstCol + rowLen ) ; // extract the actual row data
586
628
587
629
if ( this . #countryEnabled) {
588
630
if (
0 commit comments