@@ -31,7 +31,7 @@ class Database
3131 *
3232 * @var string
3333 */
34- public const VERSION = '2.0.1 ' ;
34+ public const VERSION = '2.1.0 ' ;
3535
3636 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3737 // Error field constants ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -481,6 +481,9 @@ class Database
481481 private $ year ;
482482 private $ month ;
483483 private $ day ;
484+
485+ // This variable will be used to hold the raw row of columns's positions
486+ private $ raw_positions_row ;
484487
485488 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
486489 // Default fields //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -855,6 +858,14 @@ protected function lookup($ip, $fields = null, $asNamed = true)
855858 if ($ fields === null ) {
856859 $ fields = $ this ->defaultFields ;
857860 }
861+
862+ // Get the entire row based on the pointer value.
863+ // The length of the row differs based on the IP version.
864+ if (4 === $ ipVersion ) {
865+ $ this ->raw_positions_row = $ this ->read ($ pointer - 1 , $ this ->columnWidth [4 ] + 4 );
866+ } elseif (6 === $ ipVersion ) {
867+ $ this ->raw_positions_row = $ this ->read ($ pointer - 1 , $ this ->columnWidth [6 ]);
868+ }
858869
859870 // turn fields into an array in case it wasn't already
860871 $ ifields = (array ) $ fields ;
@@ -1251,7 +1262,7 @@ private static function ipVersionAndNumber($ip)
12511262 } elseif (filter_var ($ ip , FILTER_VALIDATE_IP , FILTER_FLAG_IPV6 )) {
12521263 // 6to4 Address - 2002::/16
12531264 if (substr ($ ip , 0 , 4 ) == '2002 ' ) {
1254- return [4 , sprintf ('%u ' , long2ip (gmp_import (inet_pton ('::FFFF: ' . substr ($ ip , 5 , 9 )))))];
1265+ return [4 , sprintf ('%u ' , long2ip (gmp_intval ( gmp_import (inet_pton ('::FFFF: ' . substr ($ ip , 5 , 9 ) )))))];
12551266 }
12561267
12571268 // Teredo Address - 2001:0::/32
@@ -1342,9 +1353,9 @@ private function read($pos, $len)
13421353 * @return string
13431354 */
13441355 private function readString ($ pos , $ additional = 0 )
1345- {
1346- // Get the actual pointer to the string's head
1347- $ spos = $ this ->readWord ( $ pos) + $ additional ;
1356+ {
1357+ // Get the actual pointer to the string's head by extract from raw row data.
1358+ $ spos = unpack ( ' V ' , substr ( $ this ->raw_positions_row , $ pos, 4 ))[ 1 ] + $ additional ;
13481359
13491360 // Read as much as the length (first "string" byte) indicates
13501361 return $ this ->read ($ spos + 1 , $ this ->readByte ($ spos + 1 ));
@@ -1427,8 +1438,8 @@ private function readCountryNameAndCode($pointer)
14271438 // Read the country code and name (the name shares the country's pointer,
14281439 // but it must be artificially displaced 3 bytes ahead: 2 for the country code, one
14291440 // for the country name's length)
1430- $ countryCode = $ this ->readString ($ pointer + self ::$ columns [self ::COUNTRY_CODE ][$ this ->type ]);
1431- $ countryName = $ this ->readString ($ pointer + self ::$ columns [self ::COUNTRY_NAME ][$ this ->type ], 3 );
1441+ $ countryCode = $ this ->readString (self ::$ columns [self ::COUNTRY_CODE ][$ this ->type ]);
1442+ $ countryName = $ this ->readString (self ::$ columns [self ::COUNTRY_NAME ][$ this ->type ], 3 );
14321443 }
14331444
14341445 return [$ countryName , $ countryCode ];
@@ -1451,7 +1462,7 @@ private function readRegionName($pointer)
14511462 $ regionName = self ::FIELD_NOT_SUPPORTED ;
14521463 } else {
14531464 // Read the region name
1454- $ regionName = $ this ->readString ($ pointer + self ::$ columns [self ::REGION_NAME ][$ this ->type ]);
1465+ $ regionName = $ this ->readString (self ::$ columns [self ::REGION_NAME ][$ this ->type ]);
14551466 }
14561467
14571468 return $ regionName ;
@@ -1474,7 +1485,7 @@ private function readCityName($pointer)
14741485 $ cityName = self ::FIELD_NOT_SUPPORTED ;
14751486 } else {
14761487 // Read the city name
1477- $ cityName = $ this ->readString ($ pointer + self ::$ columns [self ::CITY_NAME ][$ this ->type ]);
1488+ $ cityName = $ this ->readString (self ::$ columns [self ::CITY_NAME ][$ this ->type ]);
14781489 }
14791490
14801491 return $ cityName ;
@@ -1497,7 +1508,7 @@ private function readIsp($pointer)
14971508 $ isp = self ::FIELD_NOT_SUPPORTED ;
14981509 } else {
14991510 // Read isp name
1500- $ isp = $ this ->readString ($ pointer + self ::$ columns [self ::ISP ][$ this ->type ]);
1511+ $ isp = $ this ->readString (self ::$ columns [self ::ISP ][$ this ->type ]);
15011512 }
15021513
15031514 return $ isp ;
@@ -1520,7 +1531,7 @@ private function readProxyType($pointer)
15201531 $ proxyType = self ::FIELD_NOT_SUPPORTED ;
15211532 } else {
15221533 // Read proxy type
1523- $ proxyType = $ this ->readString ($ pointer + self ::$ columns [self ::PROXY_TYPE ][$ this ->type ]);
1534+ $ proxyType = $ this ->readString (self ::$ columns [self ::PROXY_TYPE ][$ this ->type ]);
15241535 }
15251536
15261537 return $ proxyType ;
@@ -1543,7 +1554,7 @@ private function readDomain($pointer)
15431554 $ domain = self ::FIELD_NOT_SUPPORTED ;
15441555 } else {
15451556 // Read the domain
1546- $ domain = $ this ->readString ($ pointer + self ::$ columns [self ::DOMAIN ][$ this ->type ]);
1557+ $ domain = $ this ->readString (self ::$ columns [self ::DOMAIN ][$ this ->type ]);
15471558 }
15481559
15491560 return $ domain ;
@@ -1566,7 +1577,7 @@ private function readUsageType($pointer)
15661577 $ usageType = self ::FIELD_NOT_SUPPORTED ;
15671578 } else {
15681579 // Read the domain
1569- $ usageType = $ this ->readString ($ pointer + self ::$ columns [self ::USAGE_TYPE ][$ this ->type ]);
1580+ $ usageType = $ this ->readString (self ::$ columns [self ::USAGE_TYPE ][$ this ->type ]);
15701581 }
15711582
15721583 return $ usageType ;
@@ -1589,7 +1600,7 @@ private function readAsn($pointer)
15891600 $ asn = self ::FIELD_NOT_SUPPORTED ;
15901601 } else {
15911602 // Read the domain
1592- $ asn = $ this ->readString ($ pointer + self ::$ columns [self ::ASN ][$ this ->type ]);
1603+ $ asn = $ this ->readString (self ::$ columns [self ::ASN ][$ this ->type ]);
15931604 }
15941605
15951606 return $ asn ;
@@ -1612,7 +1623,7 @@ private function readAs($pointer)
16121623 $ as = self ::FIELD_NOT_SUPPORTED ;
16131624 } else {
16141625 // Read the domain
1615- $ as = $ this ->readString ($ pointer + self ::$ columns [self ::_AS ][$ this ->type ]);
1626+ $ as = $ this ->readString (self ::$ columns [self ::_AS ][$ this ->type ]);
16161627 }
16171628
16181629 return $ as ;
@@ -1635,7 +1646,7 @@ private function readLastSeen($pointer)
16351646 $ lastSeen = self ::FIELD_NOT_SUPPORTED ;
16361647 } else {
16371648 // Read the domain
1638- $ lastSeen = $ this ->readString ($ pointer + self ::$ columns [self ::LAST_SEEN ][$ this ->type ]);
1649+ $ lastSeen = $ this ->readString (self ::$ columns [self ::LAST_SEEN ][$ this ->type ]);
16391650 }
16401651
16411652 return $ lastSeen ;
0 commit comments