Skip to content

Commit cadff97

Browse files
authored
Merge pull request #607 from AKakkar28/refactor-code
[REFACTOR] JsonInjector and NetworkDeserializer classes
2 parents a57188e + 23d6c80 commit cadff97

File tree

2 files changed

+125
-13
lines changed

2 files changed

+125
-13
lines changed

src/main/java/com/maxmind/geoip2/NetworkDeserializer.java

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
/**
1212
* This class provides a deserializer for the Network class.
1313
*/
14-
public class NetworkDeserializer extends StdDeserializer<Network> {
14+
public final class NetworkDeserializer extends StdDeserializer<Network> {
1515

1616
/**
17-
* Constructs a @{code NetworkDeserializer} object.
17+
* Constructs a {@code NetworkDeserializer} with no type specified.
1818
*/
1919
public NetworkDeserializer() {
2020
this(null);
@@ -30,23 +30,46 @@ public NetworkDeserializer(Class<?> vc) {
3030
}
3131

3232
@Override
33-
public Network deserialize(
34-
JsonParser jsonparser, DeserializationContext context)
35-
throws IOException {
33+
public Network deserialize(JsonParser jsonparser, DeserializationContext context)
34+
throws IOException {
3635

37-
String cidr = jsonparser.getText();
38-
if (cidr == null) {
36+
final String cidr = jsonparser.getValueAsString();
37+
if (cidr == null || cidr.isBlank()) {
3938
return null;
4039
}
41-
String[] parts = cidr.split("/", 2);
40+
return parseCidr(cidr);
41+
}
42+
43+
private static Network parseCidr(String cidr) throws IOException {
44+
final String[] parts = cidr.split("/", 2);
4245
if (parts.length != 2) {
43-
throw new RuntimeException("Invalid cidr format: " + cidr);
46+
throw new IllegalArgumentException("Invalid CIDR format: " + cidr);
4447
}
45-
int prefixLength = Integer.parseInt(parts[1]);
48+
49+
final String addrPart = parts[0];
50+
final String prefixPart = parts[1];
51+
52+
final InetAddress address;
4653
try {
47-
return new Network(InetAddress.getByName(parts[0]), prefixLength);
54+
address = InetAddress.getByName(addrPart);
4855
} catch (UnknownHostException e) {
49-
throw new RuntimeException(e);
56+
throw new IOException("Unknown host in CIDR: " + cidr, e);
5057
}
58+
59+
final int prefixLength;
60+
try {
61+
prefixLength = Integer.parseInt(prefixPart);
62+
} catch (NumberFormatException e) {
63+
throw new IllegalArgumentException(
64+
"Invalid prefix length in CIDR: " + cidr, e);
65+
}
66+
67+
final int maxPrefix = (address.getAddress().length == 4) ? 32 : 128;
68+
if (prefixLength < 0 || prefixLength > maxPrefix) {
69+
throw new IllegalArgumentException(
70+
"Prefix length out of range (0-" + maxPrefix + ") for CIDR: " + cidr);
71+
}
72+
73+
return new Network(address, prefixLength);
5174
}
52-
}
75+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package com.maxmind.geoip2;
2+
3+
import com.fasterxml.jackson.core.JsonFactory;
4+
import com.fasterxml.jackson.core.JsonParser;
5+
import com.maxmind.db.Network;
6+
import org.junit.jupiter.api.Test;
7+
8+
import java.io.IOException;
9+
import java.net.InetAddress;
10+
11+
import static org.junit.jupiter.api.Assertions.*;
12+
13+
final class NetworkDeserializerTest {
14+
15+
16+
private static Network parse(String jsonString) throws IOException {
17+
var deserializer = new NetworkDeserializer();
18+
JsonFactory jf = new JsonFactory();
19+
try (JsonParser p = jf.createParser(jsonString)) {
20+
p.nextToken();
21+
return deserializer.deserialize(p, null);
22+
}
23+
}
24+
private static void assertNetwork(Network n, String addr, int prefix) throws Exception {
25+
assertNotNull(n);
26+
assertEquals(InetAddress.getByName(addr), n.getNetworkAddress());
27+
assertEquals(prefix, n.getPrefixLength());
28+
}
29+
30+
@Test
31+
void parsesValidIPv4Cidr() throws Exception {
32+
Network actual = parse("\"1.2.3.0/24\"");
33+
assertNetwork(actual, "1.2.3.0", 24);
34+
}
35+
36+
@Test
37+
void parsesValidIPv6Cidr() throws Exception {
38+
Network actual = parse("\"2001:db8::/32\"");
39+
assertNetwork(actual, "2001:db8::", 32);
40+
}
41+
42+
@Test
43+
void rejectsWhitespaceInCidr() {
44+
assertThrows(IOException.class, () -> parse("\" 10.0.0.0/8 \""));
45+
}
46+
47+
48+
49+
50+
@Test
51+
void returnsNullOnJsonNull() throws Exception {
52+
Network actual = parse("null");
53+
assertNull(actual);
54+
}
55+
56+
@Test
57+
void returnsNullOnBlankString() throws Exception {
58+
Network actual = parse("\" \"");
59+
assertNull(actual);
60+
}
61+
62+
@Test
63+
void throwsOnMissingSlash() {
64+
assertThrows(IllegalArgumentException.class, () -> parse("\"1.2.3.0\""));
65+
}
66+
67+
@Test
68+
void throwsOnNonNumericPrefix() {
69+
assertThrows(IllegalArgumentException.class, () -> parse("\"1.2.3.0/xx\""));
70+
}
71+
72+
@Test
73+
void throwsOnOutOfRangePrefixIpv4() {
74+
assertThrows(IllegalArgumentException.class, () -> parse("\"1.2.3.0/64\""));
75+
assertThrows(IllegalArgumentException.class, () -> parse("\"1.2.3.0/-1\""));
76+
}
77+
78+
@Test
79+
void throwsOnOutOfRangePrefixIpv6() {
80+
assertThrows(IllegalArgumentException.class, () -> parse("\"::/129\""));
81+
assertThrows(IllegalArgumentException.class, () -> parse("\"::/-1\""));
82+
}
83+
84+
@Test
85+
void wrapsUnknownHostInIOException() {
86+
IOException ex = assertThrows(IOException.class, () -> parse("\"999.999.999.999/24\""));
87+
assertNotNull(ex.getCause());
88+
}
89+
}

0 commit comments

Comments
 (0)