changeset 692:2233b172e06d

Add checks for sql String parameter to prevent NullPointerException or executing an empty sql String.
author Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
date Thu, 17 Nov 2022 19:16:48 +0100 (2022-11-17)
parents fb55e62c50f3
children 3442d331cad0
files src/main/java/org/monetdb/jdbc/MonetConnection.java src/main/java/org/monetdb/jdbc/MonetStatement.java tests/JDBC_API_Tester.java
diffstat 3 files changed, 153 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/org/monetdb/jdbc/MonetConnection.java
+++ b/src/main/java/org/monetdb/jdbc/MonetConnection.java
@@ -770,6 +770,10 @@ public class MonetConnection
 		throws SQLException
 	{
 		checkNotClosed();
+
+		if (sql == null || sql.isEmpty())
+			throw new SQLException("Missing SQL statement", "M1M05");
+
 		try {
 			final CallableStatement ret = new MonetCallableStatement(
 				this,
@@ -875,6 +879,10 @@ public class MonetConnection
 		throws SQLException
 	{
 		checkNotClosed();
+
+		if (sql == null || sql.isEmpty())
+			throw new SQLException("Missing SQL statement", "M1M05");
+
 		try {
 			final PreparedStatement ret = new MonetPreparedStatement(
 				this,
--- a/src/main/java/org/monetdb/jdbc/MonetStatement.java
+++ b/src/main/java/org/monetdb/jdbc/MonetStatement.java
@@ -138,6 +138,9 @@ public class MonetStatement
 	 */
 	@Override
 	public void addBatch(final String sql) throws SQLException {
+		if (sql == null || sql.isEmpty())
+			throw new SQLException("Missing SQL statement", "M1M05");
+
 		if (batch == null) {
 			// create the ArrayList at first time use
 			batch = new ArrayList<String>();
@@ -438,6 +441,9 @@ public class MonetStatement
 			lastResponseList = null;
 		}
 
+		if (sql == null || sql.isEmpty())
+			throw new SQLException("Missing SQL statement", "M1M05");
+
 		if (queryTimeout != connection.lastSetQueryTimeout) {
 			// set requested/changed queryTimeout on the server side first
 			connection.setQueryTimeout(queryTimeout);
@@ -1285,6 +1291,8 @@ public class MonetStatement
 			final BatchUpdateException e)
 		throws BatchUpdateException
 	{
+		if (batch.length() == 0)
+			return false;
 		try {
 			long count = -1;
 			boolean hasResultSet = internalExecute(batch.toString());
--- a/tests/JDBC_API_Tester.java
+++ b/tests/JDBC_API_Tester.java
@@ -66,6 +66,7 @@ final public class JDBC_API_Tester {
 		jt.Test_Ctransaction();
 		jt.Test_Dobjects();
 		jt.Test_DBCmetadata();
+		jt.Test_EmptySql();
 		jt.Test_FetchSize();
 		jt.Test_Int128();
 		jt.Test_Interval_Types();
@@ -1385,6 +1386,142 @@ final public class JDBC_API_Tester {
 		compareExpectedOutput("Test_Dmetadata", "");
 	}
 
+	private void Test_EmptySql() {
+		sb.setLength(0);	// clear the output log buffer
+
+		Statement stmt = null;
+		try {
+			stmt = con.createStatement();
+		} catch (SQLException e) {
+			sb.append("FAILED: ").append(e.getMessage()).append("\n");
+		}
+
+		try {
+			stmt.execute(null);
+			sb.append("Failed to check null parameter!\n");
+		} catch (SQLException e) {
+			sb.append(e.getMessage()).append("\n");
+		}
+		try {
+			stmt.execute("");
+			sb.append("Failed to check empty sql string!\n");
+		} catch (SQLException e) {
+			sb.append(e.getMessage()).append("\n");
+		}
+
+		try {
+			int ret = stmt.executeUpdate(null);
+			sb.append("Failed to check null parameter!\n");
+		} catch (SQLException e) {
+			sb.append(e.getMessage()).append("\n");
+		}
+		try {
+			int ret = stmt.executeUpdate("");
+			sb.append("Failed to check empty sql string!\n");
+		} catch (SQLException e) {
+			sb.append(e.getMessage()).append("\n");
+		}
+		try {
+			long ret = stmt.executeLargeUpdate(null);
+			sb.append("Failed to check null parameter!\n");
+		} catch (SQLException e) {
+			sb.append(e.getMessage()).append("\n");
+		}
+		try {
+			long ret = stmt.executeLargeUpdate("");
+			sb.append("Failed to check empty sql string!\n");
+		} catch (SQLException e) {
+			sb.append(e.getMessage()).append("\n");
+		}
+		try {
+			stmt.addBatch(null);
+			sb.append("Failed to check null parameter!\n");
+		} catch (SQLException e) {
+			sb.append(e.getMessage()).append("\n");
+		}
+		try {
+			stmt.addBatch("");
+			sb.append("Failed to check empty sql string!\n");
+		} catch (SQLException e) {
+			sb.append(e.getMessage()).append("\n");
+		}
+
+		ResultSet rs = null;
+		try {
+			rs = stmt.executeQuery(null);
+			sb.append("Failed to check null parameter!\n");
+		} catch (SQLException e) {
+			sb.append(e.getMessage()).append("\n");
+		}
+		try {
+			rs = stmt.executeQuery("");
+			sb.append("Failed to check empty sql string!\n");
+		} catch (SQLException e) {
+			sb.append(e.getMessage()).append("\n");
+		}
+		closeStmtResSet(stmt, rs);
+
+		PreparedStatement pstmt = null;
+		try {
+			pstmt = con.prepareStatement(null);
+			sb.append("Failed to check null parameter!\n");
+		} catch (SQLException e) {
+			sb.append(e.getMessage()).append("\n");
+		}
+		try {
+			pstmt = con.prepareStatement("");
+			sb.append("Failed to check empty sql string!\n");
+		} catch (SQLException e) {
+			sb.append(e.getMessage()).append("\n");
+		}
+		try {
+			pstmt = con.prepareStatement(null, Statement.RETURN_GENERATED_KEYS);
+			sb.append("Failed to check null parameter!\n");
+		} catch (SQLException e) {
+			sb.append(e.getMessage()).append("\n");
+		}
+		try {
+			pstmt = con.prepareStatement("", Statement.RETURN_GENERATED_KEYS);
+			sb.append("Failed to check empty sql string!\n");
+		} catch (SQLException e) {
+			sb.append(e.getMessage()).append("\n");
+		}
+		closeStmtResSet(pstmt, null);
+
+		CallableStatement cstmt = null;
+		try {
+			pstmt = con.prepareCall(null);
+			sb.append("Failed to check null parameter!\n");
+		} catch (SQLException e) {
+			sb.append(e.getMessage()).append("\n");
+		}
+		try {
+			pstmt = con.prepareCall("");
+			sb.append("Failed to check empty sql string!\n");
+		} catch (SQLException e) {
+			sb.append(e.getMessage()).append("\n");
+		}
+		closeStmtResSet(cstmt, null);
+
+		compareExpectedOutput("Test_EmptySql",
+			"Missing SQL statement\n" +
+			"Missing SQL statement\n" +
+			"Missing SQL statement\n" +
+			"Missing SQL statement\n" +
+			"Missing SQL statement\n" +
+			"Missing SQL statement\n" +
+			"Missing SQL statement\n" +
+			"Missing SQL statement\n" +
+			"Missing SQL statement\n" +
+			"Missing SQL statement\n" +
+			"Missing SQL statement\n" +
+			"Missing SQL statement\n" +
+			"Missing SQL statement\n" +
+			"Missing SQL statement\n" +
+			"Missing SQL statement\n" +
+			"Missing SQL statement\n");
+	}
+
 	private void Test_FetchSize() {
 		sb.setLength(0);	// clear the output log buffer