Skip to content

Commit f3d84ca

Browse files
authored
Fix: NetworkStream throwing inconsistent exceptions (#40772)
Fix a bug: Span<byte> overloads of NetworkStream throwing ObjectDisposedException instead of NetworkException, when not using derived NetworkStream.
1 parent bd6c905 commit f3d84ca

File tree

2 files changed

+38
-15
lines changed

2 files changed

+38
-15
lines changed

src/libraries/System.Net.Sockets/src/System/Net/Sockets/NetworkStream.cs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,17 @@ public override int Read(Span<byte> buffer)
250250
ThrowIfDisposed();
251251
if (!CanRead) throw new InvalidOperationException(SR.net_writeonlystream);
252252

253-
int bytesRead = _streamSocket.Receive(buffer, SocketFlags.None, out SocketError errorCode);
253+
int bytesRead;
254+
SocketError errorCode;
255+
try
256+
{
257+
bytesRead = _streamSocket.Receive(buffer, SocketFlags.None, out errorCode);
258+
}
259+
catch (Exception exception) when (!(exception is OutOfMemoryException))
260+
{
261+
throw GetCustomException(SR.Format(SR.net_io_readfailure, exception.Message), exception);
262+
}
263+
254264
if (errorCode != SocketError.Success)
255265
{
256266
var socketException = new SocketException((int)errorCode);
@@ -320,7 +330,16 @@ public override void Write(ReadOnlySpan<byte> buffer)
320330
ThrowIfDisposed();
321331
if (!CanWrite) throw new InvalidOperationException(SR.net_readonlystream);
322332

323-
_streamSocket.Send(buffer, SocketFlags.None, out SocketError errorCode);
333+
SocketError errorCode;
334+
try
335+
{
336+
_streamSocket.Send(buffer, SocketFlags.None, out errorCode);
337+
}
338+
catch (Exception exception) when (!(exception is OutOfMemoryException))
339+
{
340+
throw GetCustomException(SR.Format(SR.net_io_writefailure, exception.Message), exception);
341+
}
342+
324343
if (errorCode != SocketError.Success)
325344
{
326345
var socketException = new SocketException((int)errorCode);

src/libraries/System.Net.Sockets/tests/FunctionalTests/NetworkStreamTest.cs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,10 @@ await RunWithConnectedNetworkStreamsAsync((server, _) =>
307307
});
308308
}
309309

310-
[Fact]
311-
public async Task DisposeSocketDirectly_ReadWriteThrowNetworkException()
310+
[Theory]
311+
[InlineData(true)]
312+
[InlineData(false)]
313+
public async Task DisposeSocketDirectly_ReadWriteThrowNetworkException(bool derivedNetworkStream)
312314
{
313315
using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
314316
using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
@@ -318,20 +320,22 @@ public async Task DisposeSocketDirectly_ReadWriteThrowNetworkException()
318320

319321
Task<Socket> acceptTask = listener.AcceptAsync();
320322
await Task.WhenAll(acceptTask, client.ConnectAsync(new IPEndPoint(IPAddress.Loopback, ((IPEndPoint)listener.LocalEndPoint).Port)));
321-
using (Socket serverSocket = await acceptTask)
322-
using (DerivedNetworkStream server = new DerivedNetworkStream(serverSocket))
323-
{
324-
serverSocket.Dispose();
323+
using Socket serverSocket = await acceptTask;
324+
using NetworkStream server = derivedNetworkStream ? (NetworkStream)new DerivedNetworkStream(serverSocket) : new NetworkStream(serverSocket);
325+
326+
serverSocket.Dispose();
325327

326-
Assert.Throws<IOException>(() => server.Read(new byte[1], 0, 1));
327-
Assert.Throws<IOException>(() => server.Write(new byte[1], 0, 1));
328+
Assert.Throws<IOException>(() => server.Read(new byte[1], 0, 1));
329+
Assert.Throws<IOException>(() => server.Write(new byte[1], 0, 1));
328330

329-
Assert.Throws<IOException>(() => server.BeginRead(new byte[1], 0, 1, null, null));
330-
Assert.Throws<IOException>(() => server.BeginWrite(new byte[1], 0, 1, null, null));
331+
Assert.Throws<IOException>(() => server.Read((Span<byte>)new byte[1]));
332+
Assert.Throws<IOException>(() => server.Write((ReadOnlySpan<byte>)new byte[1]));
331333

332-
Assert.Throws<IOException>(() => { server.ReadAsync(new byte[1], 0, 1); });
333-
Assert.Throws<IOException>(() => { server.WriteAsync(new byte[1], 0, 1); });
334-
}
334+
Assert.Throws<IOException>(() => server.BeginRead(new byte[1], 0, 1, null, null));
335+
Assert.Throws<IOException>(() => server.BeginWrite(new byte[1], 0, 1, null, null));
336+
337+
Assert.Throws<IOException>(() => { server.ReadAsync(new byte[1], 0, 1); });
338+
Assert.Throws<IOException>(() => { server.WriteAsync(new byte[1], 0, 1); });
335339
}
336340
}
337341

0 commit comments

Comments
 (0)