Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
CHANGELOG
=========

5.0.2 (unreleased)
------------------

* Fixed an issue where decoding `IpRiskResponse` from the IP Risk database would
fail when the `ip_risk` field was not present in the database record. The
`ipRisk` field now defaults to 0.0 when not present. A value of 0.0 indicates
that the risk score was not set in the database. In a future major release,
this field may be changed to a nullable `Double` to better distinguish between
"no data" and "zero risk". Reported by Fabrice Bacchella. GitHub #644.

5.0.1 (2025-12-02)
------------------

Expand Down
10 changes: 8 additions & 2 deletions src/main/java/com/maxmind/geoip2/model/IpRiskResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,14 @@
* @param isTorExitNode Whether the IP address is a Tor exit node.
* @param network The network associated with the record. In particular, this is the largest
* network where all the fields besides IP address have the same value.
* @param ipRisk The IP risk of a model.
* @param ipRisk The IP risk score for the IP address. A value of 0.0 indicates that the
* risk score was not set in the database. This is a limitation of primitive
* types in Java - the value cannot be null. In a future major version, this
* field may be changed to a nullable {@code Double} to distinguish between
* "no data" and "zero risk".
*/
// TODO: In the next major version (6.0.0), consider changing ipRisk to Double
// to allow null values, distinguishing "no data" from "zero risk".
public record IpRiskResponse(
@JsonProperty("ip_address")
@MaxMindDbIpAddress
Expand Down Expand Up @@ -65,7 +71,7 @@ public record IpRiskResponse(
Network network,

@JsonProperty("ip_risk")
@MaxMindDbParameter(name = "ip_risk")
@MaxMindDbParameter(name = "ip_risk", useDefault = true)
double ipRisk
) implements JsonSerializable {

Expand Down
43 changes: 43 additions & 0 deletions src/test/java/com/maxmind/geoip2/DatabaseReaderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.maxmind.geoip2.model.CountryResponse;
import com.maxmind.geoip2.model.DomainResponse;
import com.maxmind.geoip2.model.EnterpriseResponse;
import com.maxmind.geoip2.model.IpRiskResponse;
import com.maxmind.geoip2.model.IspResponse;
import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -427,6 +428,48 @@ public void testIsp() throws Exception {
}
}

@Test
public void testIpRisk() throws Exception {
try (DatabaseReader reader = new DatabaseReader.Builder(
this.getFile("GeoIP2-IP-Risk-Test.mmdb")).build()
) {
InetAddress ipAddress = InetAddress.getByName("214.2.3.0");
IpRiskResponse response = reader.ipRisk(ipAddress);
assertEquals(25.0, response.ipRisk());
assertTrue(response.isAnonymous());
assertTrue(response.isAnonymousVpn());
assertFalse(response.isHostingProvider());
assertFalse(response.isPublicProxy());
assertFalse(response.isResidentialProxy());
assertFalse(response.isTorExitNode());
assertEquals(ipAddress.getHostAddress(), response.ipAddress().getHostAddress());
assertEquals("214.2.3.0/30", response.network().toString());

IpRiskResponse tryResponse = reader.tryIpRisk(ipAddress).get();
assertEquals(response.toJson(), tryResponse.toJson());
}
}

@Test
public void testIpRiskWithoutIpRiskField() throws Exception {
// Test that records without ip_risk field default to 0.0.
// A value of 0.0 indicates that the risk score was not set in the database.
try (DatabaseReader reader = new DatabaseReader.Builder(
this.getFile("GeoIP2-IP-Risk-Test.mmdb")).build()
) {
InetAddress ipAddress = InetAddress.getByName("11.1.2.3");
IpRiskResponse response = reader.ipRisk(ipAddress);
assertEquals(0.0, response.ipRisk());
assertTrue(response.isAnonymous());
assertFalse(response.isAnonymousVpn());
assertFalse(response.isHostingProvider());
assertTrue(response.isPublicProxy());
assertFalse(response.isResidentialProxy());
assertFalse(response.isTorExitNode());
assertEquals(ipAddress.getHostAddress(), response.ipAddress().getHostAddress());
}
}

private File getFile(String filename) throws URISyntaxException {
URL resource = DatabaseReaderTest.class
.getResource("/maxmind-db/test-data/" + filename);
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/maxmind-db
Submodule maxmind-db updated 47 files
+15 −9 .github/dependabot.yml
+4 −4 .github/workflows/codeql-analysis.yml
+3 −3 .github/workflows/go.yml
+2 −5 .github/workflows/golangci-lint.yml
+4 −13 .github/workflows/zizmor.yml
+48 −35 .golangci.yml
+5 −5 go.mod
+10 −10 go.sum
+27 −23 pkg/writer/geoip2.go
+13,482 −13,271 source-data/GeoIP2-City-Test.json
+60 −0 source-data/GeoIP2-IP-Risk-Test.json
+160 −0 source-data/GeoIP2-Precision-Enterprise-Test.json
+ test-data/GeoIP-Anonymous-Plus-Test.mmdb
+ test-data/GeoIP-Anonymous-Plus.mmdb
+ test-data/GeoIP2-Anonymous-IP-Test.mmdb
+ test-data/GeoIP2-City-Shield-Test.mmdb
+ test-data/GeoIP2-City-Test.mmdb
+ test-data/GeoIP2-Connection-Type-Test.mmdb
+ test-data/GeoIP2-Country-Shield-Test.mmdb
+ test-data/GeoIP2-Country-Test.mmdb
+ test-data/GeoIP2-DensityIncome-Test.mmdb
+ test-data/GeoIP2-Domain-Test.mmdb
+ test-data/GeoIP2-Enterprise-Shield-Test.mmdb
+ test-data/GeoIP2-Enterprise-Test.mmdb
+ test-data/GeoIP2-IP-Risk-Test.mmdb
+ test-data/GeoIP2-ISP-Test.mmdb
+ test-data/GeoIP2-Precision-Enterprise-Shield-Test.mmdb
+ test-data/GeoIP2-Precision-Enterprise-Test.mmdb
+ test-data/GeoIP2-Static-IP-Score-Test.mmdb
+ test-data/GeoIP2-User-Count-Test.mmdb
+ test-data/GeoLite2-ASN-Test.mmdb
+ test-data/GeoLite2-City-Test.mmdb
+ test-data/GeoLite2-Country-Test.mmdb
+ test-data/MaxMind-DB-no-ipv4-search-tree.mmdb
+ test-data/MaxMind-DB-string-value-entries.mmdb
+ test-data/MaxMind-DB-test-decoder.mmdb
+ test-data/MaxMind-DB-test-ipv4-24.mmdb
+ test-data/MaxMind-DB-test-ipv4-28.mmdb
+ test-data/MaxMind-DB-test-ipv4-32.mmdb
+ test-data/MaxMind-DB-test-ipv6-24.mmdb
+ test-data/MaxMind-DB-test-ipv6-28.mmdb
+ test-data/MaxMind-DB-test-ipv6-32.mmdb
+ test-data/MaxMind-DB-test-metadata-pointers.mmdb
+ test-data/MaxMind-DB-test-mixed-24.mmdb
+ test-data/MaxMind-DB-test-mixed-28.mmdb
+ test-data/MaxMind-DB-test-mixed-32.mmdb
+ test-data/MaxMind-DB-test-nested.mmdb
Loading