@@ -74,7 +74,10 @@ final class MySQLConnectionHandler: ChannelDuplexHandler {
74
74
case . commandPhase:
75
75
if let current = self . queue. first {
76
76
do {
77
- let commandState = try current. handler. handle ( packet: & packet, capabilities: self . serverCapabilities!)
77
+ guard let capabilities = self . serverCapabilities else {
78
+ throw MySQLError . protocolError
79
+ }
80
+ let commandState = try current. handler. handle ( packet: & packet, capabilities: capabilities)
78
81
self . handleCommandState ( context: context, commandState)
79
82
} catch {
80
83
self . queue. removeFirst ( )
@@ -226,7 +229,10 @@ final class MySQLConnectionHandler: ChannelDuplexHandler {
226
229
database: state. database,
227
230
authPluginName: authPluginName
228
231
)
229
- try context. write ( self . wrapOutboundOut ( . encode( res, capabilities: self . serverCapabilities!) ) , promise: nil )
232
+ guard let capabilities = self . serverCapabilities else {
233
+ throw MySQLError . protocolError
234
+ }
235
+ try context. write ( self . wrapOutboundOut ( . encode( res, capabilities: capabilities) ) , promise: nil )
230
236
context. flush ( )
231
237
}
232
238
@@ -264,7 +270,10 @@ final class MySQLConnectionHandler: ChannelDuplexHandler {
264
270
}
265
271
guard !packet. isError else {
266
272
self . logger. trace ( " caching_sha2_password replied ERR, decoding " )
267
- let err = try packet. decode ( MySQLProtocol . ERR_Packet. self, capabilities: self . serverCapabilities!)
273
+ guard let capabilities = self . serverCapabilities else {
274
+ throw MySQLError . protocolError
275
+ }
276
+ let err = try packet. decode ( MySQLProtocol . ERR_Packet. self, capabilities: capabilities)
268
277
throw MySQLError . server ( err)
269
278
}
270
279
guard let status = packet. payload. readInteger ( endianness: . little, as: UInt8 . self) else {
@@ -327,7 +336,10 @@ final class MySQLConnectionHandler: ChannelDuplexHandler {
327
336
case " mysql_native_password " :
328
337
guard !packet. isError else {
329
338
self . logger. trace ( " mysql_native_password sent ERR, decoding " )
330
- let error = try packet. decode ( MySQLProtocol . ERR_Packet. self, capabilities: self . serverCapabilities!)
339
+ guard let capabilities = self . serverCapabilities else {
340
+ throw MySQLError . protocolError
341
+ }
342
+ let error = try packet. decode ( MySQLProtocol . ERR_Packet. self, capabilities: capabilities)
331
343
throw MySQLError . server ( error)
332
344
}
333
345
guard !packet. isOK else {
@@ -365,12 +377,16 @@ final class MySQLConnectionHandler: ChannelDuplexHandler {
365
377
guard let command = self . queue. first else {
366
378
return
367
379
}
380
+ guard let capabilities = self . serverCapabilities else {
381
+ command. promise. fail ( MySQLError . protocolError)
382
+ return
383
+ }
368
384
self . commandState = . busy
369
385
370
386
// send initial
371
387
do {
372
388
self . sequence. current = nil
373
- let commandState = try command. handler. activate ( capabilities: self . serverCapabilities! )
389
+ let commandState = try command. handler. activate ( capabilities: capabilities )
374
390
self . handleCommandState ( context: context, commandState)
375
391
} catch {
376
392
self . queue. removeFirst ( )
@@ -413,7 +429,10 @@ final class MySQLConnectionHandler: ChannelDuplexHandler {
413
429
private func _close( context: ChannelHandlerContext , mode: CloseMode , promise: EventLoopPromise < Void > ? ) throws {
414
430
self . sequence. reset ( )
415
431
let quit = MySQLProtocol . COM_QUIT ( )
416
- try context. write ( self . wrapOutboundOut ( . encode( quit, capabilities: self . serverCapabilities!) ) , promise: nil )
432
+ // N.B.: It is possible to get here without having processed a handshake packet yet, in which case there will
433
+ // not be any serverCapabilities. Since COM_QUIT doesn't care about any of those anyway, don't crash if they're
434
+ // not there!
435
+ try context. write ( self . wrapOutboundOut ( . encode( quit, capabilities: self . serverCapabilities ?? . init( ) ) ) , promise: nil )
417
436
context. flush ( )
418
437
419
438
if let promise = promise {
0 commit comments