File mysql-connector-java-CVE-2023-21971.patch of Package mysql-connector-java.28298
From 9f1bbb8ebf5c11a290552c861f1df61206bd4834 Mon Sep 17 00:00:00 2001
From: Filipe Silva <filipe.silva@oracle.com>
Date: Sat, 4 Feb 2023 00:42:22 +0000
Subject: [PATCH] Fix for Bug#109864 (Bug#35034666), Connector/J 8.0.32 hangs
on MySQL 5.5 with prepared statements.
Change-Id: I1830f3b459f16052868bc669e2bac29ebf6d239e
---
CHANGES | 2 +
.../com/mysql/cj/ServerPreparedQuery.java | 9 +--
.../regression/StatementRegressionTest.java | 73 +++++++++++++++----
3 files changed, 66 insertions(+), 18 deletions(-)
Index: mysql-connector-j-8.0.32/src/main/core-impl/java/com/mysql/cj/ServerPreparedQuery.java
===================================================================
--- mysql-connector-j-8.0.32.orig/src/main/core-impl/java/com/mysql/cj/ServerPreparedQuery.java
+++ mysql-connector-j-8.0.32/src/main/core-impl/java/com/mysql/cj/ServerPreparedQuery.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2022, Oracle and/or its affiliates.
+ * Copyright (c) 2017, 2023, Oracle and/or its affiliates.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 2.0, as published by the
@@ -113,7 +113,6 @@ public class ServerPreparedQuery extends
}
/**
- *
* @param sql
* query string
* @throws IOException
@@ -160,9 +159,9 @@ public class ServerPreparedQuery extends
// Read in the result set column information
if (fieldCount > 0) {
this.resultFields = this.session.getProtocol().read(ColumnDefinition.class, new ColumnDefinitionFactory(fieldCount, null));
- }
- if (checkEOF && this.session.getProtocol().probeMessage(null).isEOFPacket()) { // Skip the following EOF packet.
- this.session.getProtocol().skipPacket();
+ if (checkEOF && this.session.getProtocol().probeMessage(null).isEOFPacket()) { // Skip the following EOF packet.
+ this.session.getProtocol().skipPacket();
+ }
}
}
}
Index: mysql-connector-j-8.0.32/src/test/java/testsuite/regression/StatementRegressionTest.java
===================================================================
--- mysql-connector-j-8.0.32.orig/src/test/java/testsuite/regression/StatementRegressionTest.java
+++ mysql-connector-j-8.0.32/src/test/java/testsuite/regression/StatementRegressionTest.java
@@ -8360,14 +8360,14 @@ public class StatementRegressionTest ext
// A. Test Statement.execute() results
createTable("testBug71672", tableDDL);
for (int i = 0; i < queries.length; i++) {
- testBug71672Statement(testStep, testConn, queries[i], -1, expectedGenKeys[i]);
+ checkStatementForTestBug71672(testStep, testConn, queries[i], -1, expectedGenKeys[i]);
}
dropTable("testBug71672");
// B. Test Statement.executeUpdate() results
createTable("testBug71672", tableDDL);
for (int i = 0; i < queries.length; i++) {
- testBug71672Statement(testStep, testConn, queries[i], expectedUpdCount[i], expectedGenKeys[i]);
+ checkStatementForTestBug71672(testStep, testConn, queries[i], expectedUpdCount[i], expectedGenKeys[i]);
}
dropTable("testBug71672");
@@ -8397,14 +8397,14 @@ public class StatementRegressionTest ext
// D. Test PreparedStatement.execute() results
createTable("testBug71672", tableDDL);
for (int i = 0; i < queries.length; i++) {
- testBug71672PreparedStatement(testStep, testConn, queries[i], -1, expectedGenKeys[i]);
+ checkPreparedStatementForTestBug71672(testStep, testConn, queries[i], -1, expectedGenKeys[i]);
}
dropTable("testBug71672");
// E. Test PreparedStatement.executeUpdate() results
createTable("testBug71672", tableDDL);
for (int i = 0; i < queries.length; i++) {
- testBug71672PreparedStatement(testStep, testConn, queries[i], expectedUpdCount[i], expectedGenKeys[i]);
+ checkPreparedStatementForTestBug71672(testStep, testConn, queries[i], expectedUpdCount[i], expectedGenKeys[i]);
}
dropTable("testBug71672");
@@ -8462,22 +8462,22 @@ public class StatementRegressionTest ext
// A. Test Statement.execute() results
createTable("testBug71672", tableDDL);
- testBug71672Statement(testStep, testConn, allQueries, -1, expectedGenKeysMultiQueries);
+ checkStatementForTestBug71672(testStep, testConn, allQueries, -1, expectedGenKeysMultiQueries);
dropTable("testBug71672");
// B. Test Statement.executeUpdate() results
createTable("testBug71672", tableDDL);
- testBug71672Statement(testStep, testConn, allQueries, 3, expectedGenKeysMultiQueries);
+ checkStatementForTestBug71672(testStep, testConn, allQueries, 3, expectedGenKeysMultiQueries);
dropTable("testBug71672");
// C. Test PreparedStatement.execute() results
createTable("testBug71672", tableDDL);
- testBug71672PreparedStatement(testStep, testConn, allQueries, -1, expectedGenKeysMultiQueries);
+ checkPreparedStatementForTestBug71672(testStep, testConn, allQueries, -1, expectedGenKeysMultiQueries);
dropTable("testBug71672");
// D. Test PreparedStatement.executeUpdate() results
createTable("testBug71672", tableDDL);
- testBug71672PreparedStatement(testStep, testConn, allQueries, 3, expectedGenKeysMultiQueries);
+ checkPreparedStatementForTestBug71672(testStep, testConn, allQueries, 3, expectedGenKeysMultiQueries);
dropTable("testBug71672");
testConn.close();
@@ -8495,7 +8495,8 @@ public class StatementRegressionTest ext
* @param expectedKeys
* @throws SQLException
*/
- public void testBug71672Statement(int testStep, Connection testConn, String query, int expectedUpdateCount, int[] expectedKeys) throws SQLException {
+ private void checkStatementForTestBug71672(int testStep, Connection testConn, String query, int expectedUpdateCount, int[] expectedKeys)
+ throws SQLException {
Statement testStmt = testConn.createStatement();
if (expectedUpdateCount < 0) {
@@ -8525,7 +8526,7 @@ public class StatementRegressionTest ext
* @param expectedKeys
* @throws SQLException
*/
- public void testBug71672PreparedStatement(int testStep, Connection testConn, String query, int expectedUpdateCount, int[] expectedKeys)
+ private void checkPreparedStatementForTestBug71672(int testStep, Connection testConn, String query, int expectedUpdateCount, int[] expectedKeys)
throws SQLException {
PreparedStatement testPStmt = testConn.prepareStatement(query);
@@ -12847,7 +12848,7 @@ public class StatementRegressionTest ext
}
/**
- * Tests for Bug#99604 (Bug#31612628), Add support to row alias on INSERT... ON DUPLICATE KEY UPDATE on batch mode.
+ * Tests fix for Bug#99604 (Bug#31612628), Add support to row alias on INSERT... ON DUPLICATE KEY UPDATE on batch mode.
* Resolved by fix for Bug#106240 (33781440), StringIndexOutOfBoundsException when VALUE is at the end of the query.
*
* @throws Exception
@@ -12945,4 +12946,50 @@ public class StatementRegressionTest ext
testConn.close();
} while ((useSPS = !useSPS) || (cachePS = !cachePS));
}
+
+ /**
+ * Tests fix for Bug#109864 (Bug#35034666), Connector/J 8.0.32 hangs on MySQL 5.5 with prepared statements.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testBug109864() throws Exception {
+ createTable("testBug109864", "(id INT)");
+
+ boolean useSPS = false;
+
+ do {
+ Properties props = new Properties();
+ props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
+ props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
+ props.setProperty(PropertyKey.useServerPrepStmts.getKeyName(), Boolean.toString(useSPS));
+ props.setProperty(PropertyKey.socketTimeout.getKeyName(), "5000");
+
+ Connection testConn = getConnectionWithProps(props);
+
+ this.pstmt = testConn.prepareStatement("SELECT ?"); // Both column and parameter definition blocks in Prepare response.
+ this.pstmt.setInt(1, 1);
+ this.rs = this.pstmt.executeQuery();
+ assertTrue(this.rs.next());
+ assertFalse(this.rs.next());
+ this.pstmt.close();
+
+ this.pstmt = testConn.prepareStatement("SELECT 1"); // No parameter definition block in Stmt Prepare response.
+ this.rs = this.pstmt.executeQuery();
+ assertTrue(this.rs.next());
+ assertFalse(this.rs.next());
+
+ // Prior to this fix preparing this statement would hang indefinitely with server-prepared statements.
+ this.pstmt = testConn.prepareStatement("INSERT INTO testBug109864 VALUES (?)"); // No column definition block in Prepare response.
+ this.pstmt.setInt(1, 1);
+ assertEquals(1, this.pstmt.executeUpdate());
+ this.pstmt.close();
+
+ this.pstmt = testConn.prepareStatement("INSERT INTO testBug109864 VALUES (2)"); // No column or parameter definition blocks in Prepare response.
+ assertEquals(1, this.pstmt.executeUpdate());
+ this.pstmt.close();
+
+ testConn.close();
+ } while (useSPS = !useSPS);
+ }
}