Skip to content
Open
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
16 changes: 11 additions & 5 deletions gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java
Original file line number Diff line number Diff line change
Expand Up @@ -761,11 +761,17 @@ public void write(JsonWriter out, URI value) throws IOException {
public static final TypeAdapter<InetAddress> INET_ADDRESS =
new TypeAdapter<InetAddress>() {

// A pattern that matches every IP address and no DNS address. It matches plenty of things
// that aren't either of those, which is fine. An IPv4 address is n.n.n.n where each n is a
// non-negative integer. An IPv6 address contains at least one colon. (There are further
// constraints in both cases, but they don't matter here.)
private final Pattern ipAddressPattern = Pattern.compile(".*:.*|[0-9]+(\\.[0-9]+){3}");
// A pattern that matches every IP address and no DNS address. It matches some things that
// aren't either of those, but only ones that InetAddress.getByName will reject without
// attempting a lookup. An IPv4 address is n.n.n.n where each n is between 0 and 255,
// written with at most three digits (getByName accepts leading zeros such as "001").
// An IPv6 address contains at least one colon, and getByName only tries to parse a string
// as an IP literal (rather than looking it up) if it starts with a hex digit, a colon, or
// an opening bracket; a string that it tries to parse and that contains a colon is either
// parsed or rejected.
private static final String IPV4_PART = "(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])";
private final Pattern ipAddressPattern =
Pattern.compile("[0-9A-Fa-f:\\[].*:.*|" + IPV4_PART + "(\\." + IPV4_PART + "){3}");

@Override
public InetAddress read(JsonReader in) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,40 @@ public void testInetAddressDeserializeNonIpAddress() {
.startsWith("Failed parsing 'localhost' as InetAddress; at path $");
}

@Test
public void testInetAddressDeserializeIpLikeNonIpAddress() {
// These look like IP addresses but are not IP literals that InetAddress.getByName parses.
for (String address :
new String[] {"256.1.1.1", "300.1.1.1", "1.2.3.999", "0001.2.3.4", "zz:1", "g::1"}) {
String jsonAddress = "\"" + address + "\"";
JsonSyntaxException e =
assertThrows(
JsonSyntaxException.class, () -> gson.fromJson(jsonAddress, InetAddress.class));
assertThat(e)
.hasMessageThat()
.startsWith("Failed parsing '" + address + "' as InetAddress; at path $");
}
}

@Test
public void testInetAddressDeserializeIpAddressForms() throws Exception {
for (String address :
new String[] {
"0.0.0.0",
"255.255.255.255",
"01.2.3.4",
"001.002.003.004",
"::1",
"[::1]",
"::ffff:1.2.3.4",
"fe80::1%1"
}) {
String jsonAddress = "\"" + address + "\"";
assertThat(gson.fromJson(jsonAddress, InetAddress.class))
.isEqualTo(InetAddress.getByName(address));
}
}

@Test
public void testInetAddressDeserializeNonIpAddressAllowed() throws Exception {
String jsonAddress = "\"localhost\"";
Expand Down
Loading