adamhathcock/sharpcompress

GZipArchive doesn't support entry re-reading

alexmgerasimov opened this issue · 0 comments

Hello!

GZipArchive class doesn't support re-reading of the entry. The code below crashes:

			var inputStream = new MemoryStream();
			using (var fileStream = File.Open("archive.tgz", FileMode.Open))
			{
				fileStream.CopyTo(inputStream);
				inputStream.Position = 0;
			}
			var archive = ArchiveFactory.Open(inputStream);
			var archiveEntry = archive.Entries.First();
			MemoryStream tarStream;
			using (var entryStream = archiveEntry.OpenEntryStream())
			{
				var result = SharpCompress.Archives.Tar.TarArchive.IsTarFile(entryStream);
			}			
			using (var entryStream = archiveEntry.OpenEntryStream())
			{
				tarStream = new MemoryStream();
				entryStream.CopyTo(tarStream);
			}

The exception is the follwoing:

SharpCompress.Compressors.Deflate.ZlibException was unhandled
HResult=-2146233088
Message=Bad state (invalid distance code)
Source=SharpCompress
StackTrace:
в SharpCompress.Compressors.Deflate.InflateManager.Inflate(FlushType flush)
в SharpCompress.Compressors.Deflate.ZlibBaseStream.Read(Byte[] buffer, Int32 offset, Int32 count)
в System.IO.Stream.InternalCopyTo(Stream destination, Int32 bufferSize)
в SevenZipTest.Program.Main(String[] args)
в System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
в System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
в Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
в System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
в System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
в System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
в System.Threading.ThreadHelper.ThreadStart()

It seems to me this happens because GZipFilePart doesn't rewind internal stream in the GetCompressedStream() after first reading. GZipFilePart constructor should remember stream position after GZip header reading and validation and set this initial position to the stream on each GetCompressedStream() call.