From: Alexander Köplinger Date: Fri, 23 Dec 2022 13:30:06 +0000 (+0100) Subject: Dispose underlying stream in TarReader.DisposeAsync() as well (#79920) X-Git-Tag: accepted/tizen/unified/riscv/20231226.055536~4913 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=372adbf8a4fcfe788e8f0fca3ed0fb9423099a76;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Dispose underlying stream in TarReader.DisposeAsync() as well (#79920) * Dispose underlying stream in TarReader.DisposeAsync() as well Same as https://github.com/dotnet/runtime/pull/79899 * Consolidate duplicated WrappedStream test helpers to Common sources * Dispose stream passed to WrappedStream --- diff --git a/src/libraries/Common/tests/System/IO/WrappedStream.cs b/src/libraries/Common/tests/System/IO/WrappedStream.cs new file mode 100644 index 00000000000..71be0b98c9a --- /dev/null +++ b/src/libraries/Common/tests/System/IO/WrappedStream.cs @@ -0,0 +1,130 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.IO +{ + public class WrappedStream : Stream + { + private readonly Stream _baseStream; + private readonly EventHandler _onClosed; + private bool _canRead, _canWrite, _canSeek; + + public WrappedStream(Stream baseStream, bool canRead, bool canWrite, bool canSeek, EventHandler onClosed = null) + { + _baseStream = baseStream; + _onClosed = onClosed; + _canRead = canRead; + _canSeek = canSeek; + _canWrite = canWrite; + } + + public override void Flush() => _baseStream.Flush(); + + public override int Read(byte[] buffer, int offset, int count) + { + if (CanRead) + { + try + { + return _baseStream.Read(buffer, offset, count); + } + catch (ObjectDisposedException ex) + { + throw new InvalidOperationException("This stream does not support reading", ex); + } + } + else throw new InvalidOperationException("This stream does not support reading"); + } + + public override long Seek(long offset, SeekOrigin origin) + { + if (CanSeek) + { + try + { + return _baseStream.Seek(offset, origin); + } + catch (ObjectDisposedException ex) + { + throw new InvalidOperationException("This stream does not support seeking", ex); + } + } + else throw new InvalidOperationException("This stream does not support seeking"); + } + + public override void SetLength(long value) { _baseStream.SetLength(value); } + + public override void Write(byte[] buffer, int offset, int count) + { + if (CanWrite) + { + try + { + _baseStream.Write(buffer, offset, count); + } + catch (ObjectDisposedException ex) + { + throw new InvalidOperationException("This stream does not support writing", ex); + } + } + else throw new InvalidOperationException("This stream does not support writing"); + } + + public override bool CanRead => _canRead && _baseStream.CanRead; + + public override bool CanSeek => _canSeek && _baseStream.CanSeek; + + public override bool CanWrite => _canWrite && _baseStream.CanWrite; + + public override long Length + { + get + { + if (!CanSeek) + { + throw new InvalidOperationException("This stream does not support seeking."); + } + return _baseStream.Length; + } + } + + public override long Position + { + get + { + if (!CanSeek) + { + throw new InvalidOperationException("This stream does not support seeking"); + } + return _baseStream.Position; + } + set + { + if (CanSeek) + { + try + { + _baseStream.Position = value; + } + catch (ObjectDisposedException ex) + { + throw new InvalidOperationException("This stream does not support seeking", ex); + } + } + else throw new InvalidOperationException("This stream does not support seeking"); + } + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + _onClosed?.Invoke(this, null); + _canRead = false; + _canWrite = false; + _canSeek = false; + } + base.Dispose(disposing); + } + } +} \ No newline at end of file diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarReader.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarReader.cs index 22c7970644b..1754f2f3bcf 100644 --- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarReader.cs +++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarReader.cs @@ -82,11 +82,16 @@ namespace System.Formats.Tar { _isDisposed = true; - if (!_leaveOpen && _dataStreamsToDispose?.Count > 0) + if (!_leaveOpen) { - foreach (Stream s in _dataStreamsToDispose) + await _archiveStream.DisposeAsync().ConfigureAwait(false); + + if (_dataStreamsToDispose?.Count > 0) { - await s.DisposeAsync().ConfigureAwait(false); + foreach (Stream s in _dataStreamsToDispose) + { + await s.DisposeAsync().ConfigureAwait(false); + } } } } diff --git a/src/libraries/System.Formats.Tar/tests/System.Formats.Tar.Tests.csproj b/src/libraries/System.Formats.Tar/tests/System.Formats.Tar.Tests.csproj index 1d30aa09d0f..7ec67c69fc9 100644 --- a/src/libraries/System.Formats.Tar/tests/System.Formats.Tar.Tests.csproj +++ b/src/libraries/System.Formats.Tar/tests/System.Formats.Tar.Tests.csproj @@ -68,9 +68,9 @@ - + diff --git a/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntry.LongFile.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntry.LongFile.Tests.cs index 6fd2166e81c..613e30c541d 100644 --- a/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntry.LongFile.Tests.cs +++ b/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntry.LongFile.Tests.cs @@ -30,7 +30,7 @@ namespace System.Formats.Tar.Tests public void WriteEntry_LongFileSize(TarEntryFormat entryFormat, long size, bool unseekableStream) { // Write archive with a 8 Gb long entry. - FileStream tarFile = File.Open(GetTestFilePath(), new FileStreamOptions { Access = FileAccess.ReadWrite, Mode = FileMode.Create, Options = FileOptions.DeleteOnClose }); + using FileStream tarFile = File.Open(GetTestFilePath(), new FileStreamOptions { Access = FileAccess.ReadWrite, Mode = FileMode.Create, Options = FileOptions.DeleteOnClose }); Stream s = unseekableStream ? new WrappedStream(tarFile, tarFile.CanRead, tarFile.CanWrite, canSeek: false) : tarFile; using (TarWriter writer = new(s, leaveOpen: true)) diff --git a/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntryAsync.LongFile.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntryAsync.LongFile.Tests.cs index 0f6202662d6..6d260cc9ab7 100644 --- a/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntryAsync.LongFile.Tests.cs +++ b/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntryAsync.LongFile.Tests.cs @@ -20,7 +20,7 @@ namespace System.Formats.Tar.Tests public async Task WriteEntry_LongFileSizeAsync(TarEntryFormat entryFormat, long size, bool unseekableStream) { // Write archive with a 8 Gb long entry. - FileStream tarFile = File.Open(GetTestFilePath(), new FileStreamOptions { Access = FileAccess.ReadWrite, Mode = FileMode.Create, Options = FileOptions.DeleteOnClose }); + await using FileStream tarFile = File.Open(GetTestFilePath(), new FileStreamOptions { Access = FileAccess.ReadWrite, Mode = FileMode.Create, Options = FileOptions.DeleteOnClose }); Stream s = unseekableStream ? new WrappedStream(tarFile, tarFile.CanRead, tarFile.CanWrite, canSeek: false) : tarFile; await using (TarWriter writer = new(s, leaveOpen: true)) diff --git a/src/libraries/System.Formats.Tar/tests/WrappedStream.cs b/src/libraries/System.Formats.Tar/tests/WrappedStream.cs deleted file mode 100644 index 5697f7c09ba..00000000000 --- a/src/libraries/System.Formats.Tar/tests/WrappedStream.cs +++ /dev/null @@ -1,132 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.IO; - -namespace System.Formats.Tar -{ - public class WrappedStream : Stream - { - private readonly Stream _baseStream; - private readonly EventHandler _onClosed; - private bool _canRead, _canWrite, _canSeek; - - public WrappedStream(Stream baseStream, bool canRead, bool canWrite, bool canSeek, EventHandler onClosed = null) - { - _baseStream = baseStream; - _onClosed = onClosed; - _canRead = canRead; - _canSeek = canSeek; - _canWrite = canWrite; - } - - public override void Flush() => _baseStream.Flush(); - - public override int Read(byte[] buffer, int offset, int count) - { - if (CanRead) - { - try - { - return _baseStream.Read(buffer, offset, count); - } - catch (ObjectDisposedException ex) - { - throw new InvalidOperationException("This stream does not support reading", ex); - } - } - else throw new InvalidOperationException("This stream does not support reading"); - } - - public override long Seek(long offset, SeekOrigin origin) - { - if (CanSeek) - { - try - { - return _baseStream.Seek(offset, origin); - } - catch (ObjectDisposedException ex) - { - throw new InvalidOperationException("This stream does not support seeking", ex); - } - } - else throw new InvalidOperationException("This stream does not support seeking"); - } - - public override void SetLength(long value) { _baseStream.SetLength(value); } - - public override void Write(byte[] buffer, int offset, int count) - { - if (CanWrite) - { - try - { - _baseStream.Write(buffer, offset, count); - } - catch (ObjectDisposedException ex) - { - throw new InvalidOperationException("This stream does not support writing", ex); - } - } - else throw new InvalidOperationException("This stream does not support writing"); - } - - public override bool CanRead => _canRead && _baseStream.CanRead; - - public override bool CanSeek => _canSeek && _baseStream.CanSeek; - - public override bool CanWrite => _canWrite && _baseStream.CanWrite; - - public override long Length - { - get - { - if (!CanSeek) - { - throw new InvalidOperationException("This stream does not support seeking."); - } - return _baseStream.Length; - } - } - - public override long Position - { - get - { - if (!CanSeek) - { - throw new InvalidOperationException("This stream does not support seeking"); - } - return _baseStream.Position; - } - set - { - if (CanSeek) - { - try - { - _baseStream.Position = value; - } - catch (ObjectDisposedException ex) - { - throw new InvalidOperationException("This stream does not support seeking", ex); - } - } - else throw new InvalidOperationException("This stream does not support seeking"); - } - } - - protected override void Dispose(bool disposing) - { - if (disposing) - { - _onClosed?.Invoke(this, null); - _canRead = false; - _canWrite = false; - _canSeek = false; - } - base.Dispose(disposing); - } - } -} \ No newline at end of file diff --git a/src/libraries/System.IO.Compression/tests/System.IO.Compression.Tests.csproj b/src/libraries/System.IO.Compression/tests/System.IO.Compression.Tests.csproj index 60a2473e74e..15afc84fa1c 100644 --- a/src/libraries/System.IO.Compression/tests/System.IO.Compression.Tests.csproj +++ b/src/libraries/System.IO.Compression/tests/System.IO.Compression.Tests.csproj @@ -18,7 +18,6 @@ - @@ -37,6 +36,7 @@ + diff --git a/src/libraries/System.IO.Compression/tests/Utilities/WrappedStream.cs b/src/libraries/System.IO.Compression/tests/Utilities/WrappedStream.cs deleted file mode 100644 index c93e6662be3..00000000000 --- a/src/libraries/System.IO.Compression/tests/Utilities/WrappedStream.cs +++ /dev/null @@ -1,123 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.IO; - -internal class WrappedStream : Stream -{ - private readonly Stream _baseStream; - private readonly EventHandler _onClosed; - private bool _canRead, _canWrite, _canSeek; - - internal WrappedStream(Stream baseStream, bool canRead, bool canWrite, bool canSeek, EventHandler onClosed) - { - _baseStream = baseStream; - _onClosed = onClosed; - _canRead = canRead; - _canSeek = canSeek; - _canWrite = canWrite; - } - - internal WrappedStream(Stream baseStream, EventHandler onClosed) - : this(baseStream, true, true, true, onClosed) { } - - internal WrappedStream(Stream baseStream) : this(baseStream, null) { } - - public override void Flush() => _baseStream.Flush(); - - public override int Read(byte[] buffer, int offset, int count) - { - if (CanRead) - { - try - { - return _baseStream.Read(buffer, offset, count); - } - catch (ObjectDisposedException ex) - { - throw new NotSupportedException("This stream does not support reading", ex); - } - } - else throw new NotSupportedException("This stream does not support reading"); - } - - public override long Seek(long offset, SeekOrigin origin) - { - if (CanSeek) - { - try - { - return _baseStream.Seek(offset, origin); - } - catch (ObjectDisposedException ex) - { - throw new NotSupportedException("This stream does not support seeking", ex); - } - } - else throw new NotSupportedException("This stream does not support seeking"); - } - - public override void SetLength(long value) { _baseStream.SetLength(value); } - - public override void Write(byte[] buffer, int offset, int count) - { - if (CanWrite) - { - try - { - _baseStream.Write(buffer, offset, count); - } - catch (ObjectDisposedException ex) - { - throw new NotSupportedException("This stream does not support writing", ex); - } - } - else throw new NotSupportedException("This stream does not support writing"); - } - - public override bool CanRead => _canRead && _baseStream.CanRead; - - public override bool CanSeek => _canSeek && _baseStream.CanSeek; - - public override bool CanWrite => _canWrite && _baseStream.CanWrite; - - public override long Length => _baseStream.Length; - - public override long Position - { - get - { - if (CanSeek) - return _baseStream.Position; - throw new NotSupportedException("This stream does not support seeking"); - } - set - { - if (CanSeek) - { - try - { - _baseStream.Position = value; - } - catch (ObjectDisposedException ex) - { - throw new NotSupportedException("This stream does not support seeking", ex); - } - } - else throw new NotSupportedException("This stream does not support seeking"); - } - } - - protected override void Dispose(bool disposing) - { - if (disposing) - { - _onClosed?.Invoke(this, null); - _canRead = false; - _canWrite = false; - _canSeek = false; - } - base.Dispose(disposing); - } -}