From fb0efface46862e3cd283eeab56095b5d789d3d7 Mon Sep 17 00:00:00 2001 From: lionsoul2014 Date: Tue, 3 Mar 2026 13:40:54 +0800 Subject: [PATCH] optimize the ptr checking and return empty string for missing data --- binding/c/xdb_searcher.c | 7 +++++++ binding/csharp/IP2Region.Net/IP2Region.Net.csproj | 2 +- binding/csharp/IP2Region.Net/XDB/Searcher.cs | 8 ++++++++ binding/golang/xdb/searcher.go | 5 +++++ binding/java/README.md | 2 +- binding/java/README_zh.md | 2 +- binding/java/pom.xml | 2 +- .../main/java/org/lionsoul/ip2region/xdb/Searcher.java | 5 +++++ binding/javascript/package.json | 2 +- binding/javascript/searcher.js | 6 ++++++ binding/lua/xdb_searcher.lua | 9 ++++++++- binding/php/xdb/Searcher.class.php | 8 +++++++- binding/python/ip2region/searcher.py | 7 ++++++- binding/python/setup.py | 2 +- binding/rust/ip2region/Cargo.toml | 2 +- binding/rust/ip2region/src/searcher.rs | 6 ++++++ 16 files changed, 65 insertions(+), 10 deletions(-) diff --git a/binding/c/xdb_searcher.c b/binding/c/xdb_searcher.c index 8a6338c..d5fa8e9 100644 --- a/binding/c/xdb_searcher.c +++ b/binding/c/xdb_searcher.c @@ -196,6 +196,13 @@ XDB_PUBLIC(int) xdb_search(xdb_searcher_t *xdb, const bytes_ip_t *ip_bytes, int } // printf("s_ptr=%u, e_ptr=%u\n", s_ptr, e_ptr); + // @Note: ptr validate, zero ptr means source data missing + // so we could just stop here and return an empty string. + if (s_ptr == 0 || e_ptr == 0) { + xdb_region_buffer_empty(region); + return err; + } + // binary search to get the final region info // segment_buffer = xdb_malloc(seg_index_size); seg_index_size = xdb->version->segment_index_size; diff --git a/binding/csharp/IP2Region.Net/IP2Region.Net.csproj b/binding/csharp/IP2Region.Net/IP2Region.Net.csproj index 9851def..a3e1cbf 100644 --- a/binding/csharp/IP2Region.Net/IP2Region.Net.csproj +++ b/binding/csharp/IP2Region.Net/IP2Region.Net.csproj @@ -2,7 +2,7 @@ IP2Region.Net - 3.0.1 + 3.0.2 IP2Region.Net Alan Lee;Argo Zhang(argo@live.ca) Apache-2.0 diff --git a/binding/csharp/IP2Region.Net/XDB/Searcher.cs b/binding/csharp/IP2Region.Net/XDB/Searcher.cs index abccb75..4fdb739 100644 --- a/binding/csharp/IP2Region.Net/XDB/Searcher.cs +++ b/binding/csharp/IP2Region.Net/XDB/Searcher.cs @@ -75,6 +75,14 @@ public class Searcher(CachePolicy cachePolicy, string xdbPath) : ISearcher var sPtr = BinaryPrimitives.ReadUInt32LittleEndian(vector.Span); var ePtr = BinaryPrimitives.ReadUInt32LittleEndian(vector.Span.Slice(4)); + // @Note: ptr validate, zero ptr means source data missing + // so we could just stop here and return an empty string. + if (sPtr == 0 || ePtr == 0) + { + return ""; + } + + var length = ipBytes.Length; var indexSize = length * 2 + 6; var l = 0; diff --git a/binding/golang/xdb/searcher.go b/binding/golang/xdb/searcher.go index 7ab111e..eb46b3d 100644 --- a/binding/golang/xdb/searcher.go +++ b/binding/golang/xdb/searcher.go @@ -132,6 +132,11 @@ func (s *Searcher) Search(ip []byte) (string, error) { } // fmt.Printf("sPtr=%d, ePtr=%d\n", sPtr, ePtr) + // @Note: ptr validate, zero ptr means source data missing + // so we could just stop here and return an empty string. + if sPtr == 0 || ePtr == 0 { + return "", nil + } // binary search the segment index to get the region var bytes, dBytes = len(ip), len(ip) << 1 diff --git a/binding/java/README.md b/binding/java/README.md index 6eed991..95b0a82 100644 --- a/binding/java/README.md +++ b/binding/java/README.md @@ -10,7 +10,7 @@ org.lionsoul ip2region - 3.3.5 + 3.3.6 ``` diff --git a/binding/java/README_zh.md b/binding/java/README_zh.md index b889cd0..cf570c5 100644 --- a/binding/java/README_zh.md +++ b/binding/java/README_zh.md @@ -9,7 +9,7 @@ org.lionsoul ip2region - 3.3.5 + 3.3.6 ``` diff --git a/binding/java/pom.xml b/binding/java/pom.xml index a139f38..31e2dc3 100644 --- a/binding/java/pom.xml +++ b/binding/java/pom.xml @@ -4,7 +4,7 @@ org.lionsoul ip2region - 3.3.5 + 3.3.6 jar ip2region diff --git a/binding/java/src/main/java/org/lionsoul/ip2region/xdb/Searcher.java b/binding/java/src/main/java/org/lionsoul/ip2region/xdb/Searcher.java index 1786bfb..1dc9b79 100644 --- a/binding/java/src/main/java/org/lionsoul/ip2region/xdb/Searcher.java +++ b/binding/java/src/main/java/org/lionsoul/ip2region/xdb/Searcher.java @@ -138,6 +138,11 @@ public class Searcher { } // System.out.printf("sPtr: %d, ePtr: %d\n", sPtr, ePtr); + // @Note: ptr validate, zero ptr means source data missing + // so we could just stop here and return an empty string. + if (sPtr == 0 || ePtr == 0) { + return ""; + } // binary search the segment index block to get the region info final int bytes = ip.length, dBytes = ip.length << 1; diff --git a/binding/javascript/package.json b/binding/javascript/package.json index 5f3879b..1033288 100644 --- a/binding/javascript/package.json +++ b/binding/javascript/package.json @@ -1,6 +1,6 @@ { "name": "ip2region.js", - "version": "3.1.7", + "version": "3.1.8", "description": "official javascript binding for ip2region with both IPv4 and IPv6 supported ", "type": "module", "main": "index.js", diff --git a/binding/javascript/searcher.js b/binding/javascript/searcher.js index 698748d..4d132e6 100644 --- a/binding/javascript/searcher.js +++ b/binding/javascript/searcher.js @@ -66,6 +66,12 @@ export class Searcher { } // console.log(`sPtr: ${sPtr}, ePtr: ${ePtr}`); + // @Note: ptr validate, zero ptr means source data missing + // so we could just stop here and return an empty string. + if (sPtr == 0 || ePtr == 0) { + return ""; + } + // binary search the segment index block to get the region info const bytes = ipBytes.length, dBytes = ipBytes.length << 1; const indexSize = this.version.indexSize; diff --git a/binding/lua/xdb_searcher.lua b/binding/lua/xdb_searcher.lua index 844e012..4148c17 100644 --- a/binding/lua/xdb_searcher.lua +++ b/binding/lua/xdb_searcher.lua @@ -129,6 +129,13 @@ function xdb:search(ip_bytes) end -- print(string.format("s_ptr: %d, e_ptr: %d", s_ptr, e_ptr)) + -- @Note: ptr validate, zero ptr means source data missing + -- so we could just stop here and return an empty string. + if s_ptr == 0 or e_ptr == 0 then + return "", nil + end + + -- binary search to get the data local index_size, ip_sub_compare = version.index_size, version.ip_sub_compare local bytes, d_bytes = version.bytes, version.bytes << 1 @@ -701,4 +708,4 @@ xdb.structure_30 = xdb_structure_30 xdb.IPv4 = IPv4 xdb.IPv6 = IPv6 -return xdb \ No newline at end of file +return xdb diff --git a/binding/php/xdb/Searcher.class.php b/binding/php/xdb/Searcher.class.php index c55dee2..09f826c 100644 --- a/binding/php/xdb/Searcher.class.php +++ b/binding/php/xdb/Searcher.class.php @@ -504,6 +504,12 @@ class Searcher { } // printf("sPtr: %d, ePtr: %d\n", $sPtr, $ePtr); + // @Note: ptr validate, zero ptr means source data missing + // so we could just stop here and return an empty string. + if ($sPtr == 0 || $ePtr == 0) { + return ""; + } + [$bytes, $dBytes] = [strlen($ipBytes), strlen($ipBytes) << 1]; // binary search the segment index to get the region info @@ -564,4 +570,4 @@ class Searcher { return $buff; } -} \ No newline at end of file +} diff --git a/binding/python/ip2region/searcher.py b/binding/python/ip2region/searcher.py index 7e6b445..f102704 100644 --- a/binding/python/ip2region/searcher.py +++ b/binding/python/ip2region/searcher.py @@ -68,6 +68,11 @@ class Searcher(object): e_ptr = util.le_get_uint32(buff, 4) # print("s_ptr: {}, e_ptr: {}".format(s_ptr, e_ptr)) + # @Note: ptr validate, zero ptr means source data missing + # so we could just stop here and return an empty string. + if s_ptr == 0 or e_ptr == 0: + return "" + # binary search the segment index block to get the region info _bytes, _d_bytes = len(ip_bytes), len(ip_bytes) << 1 index_size = self.version.index_size @@ -129,4 +134,4 @@ def new_with_vector_index(version: util.Version, db_path: str, vector_index: byt return Searcher(version, db_path, vector_index, None) def new_with_buffer(version: util.Version, c_buffer: bytes): - return Searcher(version, None, None, c_buffer) \ No newline at end of file + return Searcher(version, None, None, c_buffer) diff --git a/binding/python/setup.py b/binding/python/setup.py index 7c62011..aec93c4 100644 --- a/binding/python/setup.py +++ b/binding/python/setup.py @@ -2,7 +2,7 @@ setuptools.setup( name="py-ip2region", - version="3.0.3", + version="3.0.4", description="ip2region official python binding with both IPv4 and IPv6 supported", long_description=open("README.md", encoding='utf-8').read(), long_description_content_type='text/markdown', diff --git a/binding/rust/ip2region/Cargo.toml b/binding/rust/ip2region/Cargo.toml index cc60b34..66813bc 100644 --- a/binding/rust/ip2region/Cargo.toml +++ b/binding/rust/ip2region/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ip2region" -version = "0.2.0" +version = "0.2.1" edition = "2024" rust-version = "1.89.0" description = "The rust binding for ip2region" diff --git a/binding/rust/ip2region/src/searcher.rs b/binding/rust/ip2region/src/searcher.rs index 2ad73f6..9882ef7 100644 --- a/binding/rust/ip2region/src/searcher.rs +++ b/binding/rust/ip2region/src/searcher.rs @@ -68,6 +68,12 @@ impl Searcher { let end_ptr = u32::from_le_bytes(vector_index[start_point + 4..start_point + 8].try_into()?) as usize; + // @Note: ptr validate, zero ptr means source data missing + // so we could just stop here and return an empty string. + if start_ptr == 0 || end_ptr == 0 { + return Ok(String::new()) + } + // Binary search the segment index to get the region let segment_index_size = self.header.segment_index_size(); let ip_bytes_len = self.header.ip_bytes_len();