-
Couldn't load subscription status.
- Fork 5.2k
Description
Consider the following code:
using System.IO;
using System.IO.Compression;
namespace ConsoleApp
{
class Program
{
static void Main()
{
DirectoryInfo directory = new DirectoryInfo(@"C:\path\to\directory\with\huge\files\to\compress");
using (FileStream stream = new FileStream(@"C:\path\to\new\Compressed.zip", FileMode.CreateNew))
{
using (ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Update /* this is the problem */, leaveOpen: false))
{
foreach (FileInfo file in directory.EnumerateFiles("*", SearchOption.AllDirectories))
{
archive.CreateEntryFromFile(
sourceFileName: file.FullName,
entryName: file.Name,
CompressionLevel.Optimal); // throws
}
}
}
}
}
}The exception would be:
Backup failed with exception System.IO.IOException: Stream was too long.
at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.Stream.InternalCopyTo(Stream destination, Int32 bufferSize)
at System.IO.Compression.ZipFileExtensions.DoCreateEntryFromFile(ZipArchive destination, String sourceFileName, String entryName, Nullable`1 compressionLevel)
CreateEntryFromFile has this exception documented here.
The exception is thrown because we restrict the size of a file to Int32.MaxValue. The restriction is reached because the code is opening the ZipArchive with ZipArchiveMode.Update. That mode requires a stream that allows seeking, so we internally create a MemoryStream so that we can update the archive, but the size limit for the file is Int32.MaxValue.
The ZipArchiveMode remarks state that ZipArchiveMode.Update allows both reading and writing, but in this code, writing is not needed.
The Roslyn analyzer would only create a diagnostic if we can detect that the code:
- Is creating a new
ZipArchivewithFileMode.CreateorFileMode.CreateNew, and- Is either calling
CreateEntryFromFile, which takes the file name and creates theZipArchiveEntryinternally (and it does not get updated), or - Is creating
ZipArchiveEntryinstances but does not manipulate them before adding them to theZipArchive.
- Is either calling
The Roslyn fixer would suggest changing ZipArchiveMode.Update to ZipArchiveMode.Create.
Is this a good candidate for a Roslyn analyzer/fixer?