Intended change
The Socket class will now throw a SocketException if the socket has been explicitly destroyed or upgraded to a secure socket upon setting or getting socket options. Previously setting a socket option would be ignored and getting a socket option would return null.
Rationale
The non-nullable-by-default migration required making subtle changes to some dart:io semantics in order to provide a better API. The Socket.getRawOption() method never returns null except if the socket had been destroyed or upgraded to a secure socket, after which the socket object should not be used. It will never return null for all legitimate uses, so to provide a better API when Dart is null-safe, we would like to change the API to never return null and instead throw a SocketException in this case. This behavior is consistent with the Socket.port, Socket.address, Socket.remotePort, and Socket.remoteAddress getters that also throw a SocketException when the socket has been destroyed or upgraded to a secure socket.
While here, the Socket.setOption() and Socket.setRawOption() methods are changed to also throw for consistency in this case instead of silently not setting the option.
Expected impact
Socket objects are not supposed to be used after destroy() has been called on them or after they've been upgraded to a secure socket. Therefore code shouldn't been trying to set or get socket options at that time and it's not expected any code will break.
Steps for mitigation
Affected code should be changed to not set or get socket options after sockets has been explicitly destroyed or upgraded to a secure socket. Alternatively such code can catch the SocketException.
Implementation
This change was implemented in https://dart-review.googlesource.com/c/sdk/+/134328.
cc @franklinyow @mit-mit @lrhn @athomas
Intended change
The
Socketclass will now throw aSocketExceptionif the socket has been explicitly destroyed or upgraded to a secure socket upon setting or getting socket options. Previously setting a socket option would be ignored and getting a socket option would returnnull.Rationale
The non-nullable-by-default migration required making subtle changes to some dart:io semantics in order to provide a better API. The
Socket.getRawOption()method never returnsnullexcept if the socket had been destroyed or upgraded to a secure socket, after which the socket object should not be used. It will never return null for all legitimate uses, so to provide a better API when Dart is null-safe, we would like to change the API to never returnnulland instead throw aSocketExceptionin this case. This behavior is consistent with theSocket.port,Socket.address,Socket.remotePort, andSocket.remoteAddressgetters that also throw aSocketExceptionwhen the socket has been destroyed or upgraded to a secure socket.While here, the
Socket.setOption()andSocket.setRawOption()methods are changed to also throw for consistency in this case instead of silently not setting the option.Expected impact
Socketobjects are not supposed to be used afterdestroy()has been called on them or after they've been upgraded to a secure socket. Therefore code shouldn't been trying to set or get socket options at that time and it's not expected any code will break.Steps for mitigation
Affected code should be changed to not set or get socket options after sockets has been explicitly destroyed or upgraded to a secure socket. Alternatively such code can catch the
SocketException.Implementation
This change was implemented in https://dart-review.googlesource.com/c/sdk/+/134328.
cc @franklinyow @mit-mit @lrhn @athomas