From 3df32f9bf9da38cc5f0fbb212a3034e4634dd3c7 Mon Sep 17 00:00:00 2001 From: Sehrope Sarkuni Date: Fri, 13 Sep 2019 08:18:27 -0400 Subject: [PATCH] fix: Revert inet default Java type to PGObject and handle values with net masks (#1568) Reverts inet type columns to return their value as a PGObject rather than parsing them as InetAddress values. This ensures that the mask value is not lost. Also corrects the getObject(..., InetAddress.class) handling to split out the net mask and return only the address portion. --- .../org/postgresql/jdbc/PgConnection.java | 11 ---- .../java/org/postgresql/jdbc/PgResultSet.java | 26 +++------ .../test/jdbc4/jdbc41/GetObjectTest.java | 55 +++++++++++-------- 3 files changed, 40 insertions(+), 52 deletions(-) diff --git a/pgjdbc/src/main/java/org/postgresql/jdbc/PgConnection.java b/pgjdbc/src/main/java/org/postgresql/jdbc/PgConnection.java index aeba61020f..d9f4debc60 100644 --- a/pgjdbc/src/main/java/org/postgresql/jdbc/PgConnection.java +++ b/pgjdbc/src/main/java/org/postgresql/jdbc/PgConnection.java @@ -39,8 +39,6 @@ import org.postgresql.util.PSQLState; import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; import java.sql.Array; import java.sql.Blob; import java.sql.CallableStatement; @@ -551,15 +549,6 @@ public Object getObject(String type, String value, byte[] byteValue) throws SQLE } } - if (type.equals("inet")) { - try { - return InetAddress.getByName(value); - } catch (UnknownHostException e) { - throw new PSQLException(GT.tr("IP address {0} of a host could not be determined", value), - PSQLState.CONNECTION_FAILURE, e); - } - } - PGobject obj = null; if (LOGGER.isLoggable(Level.FINEST)) { diff --git a/pgjdbc/src/main/java/org/postgresql/jdbc/PgResultSet.java b/pgjdbc/src/main/java/org/postgresql/jdbc/PgResultSet.java index ec0a8294b1..107e9e642a 100644 --- a/pgjdbc/src/main/java/org/postgresql/jdbc/PgResultSet.java +++ b/pgjdbc/src/main/java/org/postgresql/jdbc/PgResultSet.java @@ -36,6 +36,7 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.net.InetAddress; +import java.net.UnknownHostException; import java.sql.Array; import java.sql.Blob; import java.sql.Clob; @@ -217,10 +218,6 @@ protected Object internalGetObject(int columnIndex, Field field) throws SQLExcep return getString(columnIndex); } - if (type.equals("inet")) { - return getInetAddress(getPGType(columnIndex), getString(columnIndex)); - } - if (type.equals("uuid")) { if (isBinary(columnIndex)) { return getUUID(thisRow[columnIndex - 1]); @@ -3095,16 +3092,6 @@ protected Object getUUID(byte[] data) throws SQLException { return new UUID(ByteConverter.int8(data, 0), ByteConverter.int8(data, 8)); } - protected Object getInetAddress(String type, String data) throws SQLException { - InetAddress inet; - try { - inet = (InetAddress) connection.getObject(type, data, null); - } catch (IllegalArgumentException iae) { - throw new PSQLException(GT.tr("Invalid Inet data."), PSQLState.INVALID_PARAMETER_VALUE, iae); - } - return inet; - } - private class PrimaryKey { int index; // where in the result set is this primaryKey String name; // what is the columnName of this primary Key @@ -3355,11 +3342,16 @@ public T getObject(int columnIndex, Class type) throws SQLException { } else if (type == UUID.class) { return type.cast(getObject(columnIndex)); } else if (type == InetAddress.class) { - Object addressString = getObject(columnIndex); - if (addressString == null) { + String inetText = getString(columnIndex); + if (inetText == null) { return null; } - return type.cast(getObject(columnIndex)); + int slash = inetText.indexOf("/"); + try { + return type.cast(InetAddress.getByName(slash < 0 ? inetText : inetText.substring(0, slash))); + } catch (UnknownHostException ex) { + throw new PSQLException(GT.tr("Invalid Inet data."), PSQLState.INVALID_PARAMETER_VALUE, ex); + } // JSR-310 support //#if mvn.project.property.postgresql.jdbc.spec >= "JDBC4.2" } else if (type == LocalDate.class) { diff --git a/pgjdbc/src/test/java/org/postgresql/test/jdbc4/jdbc41/GetObjectTest.java b/pgjdbc/src/test/java/org/postgresql/test/jdbc4/jdbc41/GetObjectTest.java index a452bece63..bcdc541e4a 100644 --- a/pgjdbc/src/test/java/org/postgresql/test/jdbc4/jdbc41/GetObjectTest.java +++ b/pgjdbc/src/test/java/org/postgresql/test/jdbc4/jdbc41/GetObjectTest.java @@ -22,6 +22,7 @@ import org.postgresql.test.TestUtil; import org.postgresql.util.PGInterval; import org.postgresql.util.PGmoney; +import org.postgresql.util.PGobject; import org.junit.After; import org.junit.Before; @@ -938,42 +939,48 @@ public void testGetInetAddressNull() throws SQLException, UnknownHostException { } } - /** - * Test the behavior getObject for inet columns. - */ - @Test - public void testGetInet4Address() throws SQLException, UnknownHostException { + private void testInet(String inet, InetAddress expectedAddr, String expectedText) throws SQLException, UnknownHostException { + PGobject expectedObj = new PGobject(); + expectedObj.setType("inet"); + expectedObj.setValue(expectedText); Statement stmt = conn.createStatement(); - String expected = "192.168.100.128"; - stmt.executeUpdate(TestUtil.insertSQL("table1","inet_column","'" + expected + "'")); - - ResultSet rs = stmt.executeQuery(TestUtil.selectSQL("table1", "inet_column")); + ResultSet rs = stmt.executeQuery("SELECT '" + inet + "'::inet AS inet_column"); try { assertTrue(rs.next()); - assertEquals(InetAddress.getByName(expected), rs.getObject("inet_column", InetAddress.class)); - assertEquals(InetAddress.getByName(expected), rs.getObject(1, InetAddress.class)); + assertEquals("The string value of the inet should match when fetched via getString(...)", expectedText, rs.getString(1)); + assertEquals("The string value of the inet should match when fetched via getString(...)", expectedText, rs.getString("inet_column")); + assertEquals("The object value of the inet should match when fetched via getObject(...)", expectedObj, rs.getObject(1)); + assertEquals("The object value of the inet should match when fetched via getObject(...)", expectedObj, rs.getObject("inet_column")); + assertEquals("The InetAddress value should match when fetched via getObject(..., InetAddress.class)", expectedAddr, rs.getObject("inet_column", InetAddress.class)); + assertEquals("The InetAddress value should match when fetched via getObject(..., InetAddress.class)", expectedAddr, rs.getObject(1, InetAddress.class)); } finally { rs.close(); + stmt.close(); } } /** - * Test the behavior getObject for inet columns. + * Test the behavior getObject for ipv4 inet columns. */ @Test - public void testGetInet6Address() throws SQLException, UnknownHostException { - Statement stmt = conn.createStatement(); - String expected = "2001:4f8:3:ba:2e0:81ff:fe22:d1f1"; - stmt.executeUpdate(TestUtil.insertSQL("table1","inet_column","'" + expected + "'")); + public void testGetInet4Address() throws SQLException, UnknownHostException { + String inet = "192.168.100.128"; + InetAddress addr = InetAddress.getByName(inet); + testInet(inet, addr, inet); + testInet(inet + "/16", addr, inet + "/16"); + testInet(inet + "/32", addr, inet); + } - ResultSet rs = stmt.executeQuery(TestUtil.selectSQL("table1", "inet_column")); - try { - assertTrue(rs.next()); - assertEquals(InetAddress.getByName(expected), rs.getObject("inet_column", InetAddress.class)); - assertEquals(InetAddress.getByName(expected), rs.getObject(1, InetAddress.class)); - } finally { - rs.close(); - } + /** + * Test the behavior getObject for ipv6 inet columns. + */ + @Test + public void testGetInet6Address() throws SQLException, UnknownHostException { + String inet = "2001:4f8:3:ba:2e0:81ff:fe22:d1f1"; + InetAddress addr = InetAddress.getByName(inet); + testInet(inet, addr, inet); + testInet(inet + "/16", addr, inet + "/16"); + testInet(inet + "/128", addr, inet); } }