Skip to content

Commit ed0fad8

Browse files
committed
Fix potential NullReferenceException. Fixes #1506
Signed-off-by: Bradley Grainger <[email protected]>
1 parent 1e009ea commit ed0fad8

File tree

1 file changed

+10
-9
lines changed

1 file changed

+10
-9
lines changed

src/MySqlConnector/MySqlConnection.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -879,13 +879,14 @@ internal ServerSession Session
879879

880880
internal void Cancel(ICancellableCommand command, int commandId, bool isCancel)
881881
{
882-
if (m_session?.Id is not string sessionId || State != ConnectionState.Open || m_session?.TryStartCancel(command) is not true)
882+
// NOTE: read and cache m_session in a local variable because it can be set to null by CloseAsync on another thread
883+
if (m_session is not { } session || State != ConnectionState.Open || !session.TryStartCancel(command))
883884
{
884885
Log.IgnoringCancellationForCommand(m_logger, commandId);
885886
return;
886887
}
887888

888-
Log.CommandHasBeenCanceled(m_logger, commandId, sessionId, isCancel ? "Cancel()" : "command timeout");
889+
Log.CommandHasBeenCanceled(m_logger, commandId, session.Id, isCancel ? "Cancel()" : "command timeout");
889890
try
890891
{
891892
// open a dedicated connection to the server to kill the active query
@@ -894,12 +895,12 @@ internal void Cancel(ICancellableCommand command, int commandId, bool isCancel)
894895
AutoEnlist = false,
895896
Pooling = false,
896897
};
897-
if (m_session.IPEndPoint is { Address: { } ipAddress, Port: { } port })
898+
if (session.IPEndPoint is { Address: { } ipAddress, Port: { } port })
898899
{
899900
csb.Server = ipAddress.ToString();
900901
csb.Port = (uint) port;
901902
}
902-
csb.UserID = m_session.UserID;
903+
csb.UserID = session.UserID;
903904
var cancellationTimeout = GetConnectionSettings().CancellationTimeout;
904905
csb.ConnectionTimeout = cancellationTimeout < 1 ? 3u : (uint) cancellationTimeout;
905906

@@ -912,20 +913,20 @@ internal void Cancel(ICancellableCommand command, int commandId, bool isCancel)
912913
#endif
913914
using var killCommand = new MySqlCommand(killQuerySql, connection);
914915
killCommand.CommandTimeout = cancellationTimeout < 1 ? 3 : cancellationTimeout;
915-
m_session?.DoCancel(command, killCommand);
916+
session.DoCancel(command, killCommand);
916917
}
917918
catch (InvalidOperationException ex)
918919
{
919920
// ignore a rare race condition where the connection is open at the beginning of the method, but closed by the time
920921
// KILL QUERY is executed: https://github.com/mysql-net/MySqlConnector/issues/1002
921-
Log.IgnoringCancellationForClosedConnection(m_logger, ex, sessionId);
922-
m_session?.AbortCancel(command);
922+
Log.IgnoringCancellationForClosedConnection(m_logger, ex, session.Id);
923+
session.AbortCancel(command);
923924
}
924925
catch (MySqlException ex)
925926
{
926927
// cancelling the query failed; setting the state back to 'Querying' will allow another call to 'Cancel' to try again
927-
Log.CancelingCommandFailed(m_logger, ex, sessionId, command.CommandId);
928-
m_session?.AbortCancel(command);
928+
Log.CancelingCommandFailed(m_logger, ex, session.Id, command.CommandId);
929+
session.AbortCancel(command);
929930
}
930931
}
931932

0 commit comments

Comments
 (0)