Repository: dotnet/runtime
File: src/libraries/System.IO.Compression/tests/ZipArchive/zip_InvalidParametersAndStrangeFiles.cs (C#)

Code before:
                // compression method should not have changed
                Assert.Equal(firstEntryCompressionMethod, fileContent[8]);

                testStream.Seek(0, SeekOrigin.Begin);
                // second attempt: open archive with zero-length file that is compressed (Deflate = 0x8)
                zip = await CreateZipArchive(async, testStream, ZipArchiveMode.Update, leaveOpen: true);

                var zipEntryStream = await OpenEntryStream(async, zip.Entries[0]);
                // Opening and disposing an entry stream without writing does not mark the archive as modified,
                // so no rewrite will occur
                await DisposeStream(async, zipEntryStream);

                await DisposeZipArchive(async, zip);

                fileContent = testStream.ToArray();

                // compression method should remain unchanged since we didn't write anything
                Assert.Equal(firstEntryCompressionMethod, fileContent[8]);

                // extract and check the file
                zip = await CreateZipArchive(async, testStream, ZipArchiveMode.Update);

                ZipArchiveEntry entry = zip.GetEntry(ExpectedFileName);
                // The entry retains its original properties since it was never modified
                Assert.Equal(0, entry.Length);

                await DisposeZipArchive(async, zip);
            }
        }
        /// <summary>
        /// Opens an empty file that has a 64KB EOCD comment.
        /// Adds two 64KB text entries. Verifies they can be read correctly.
        /// Appends 64KB of garbage at the end of the file. Verifies we throw.
        /// Prepends 64KB of garbage at the beginning of the file. Verifies we throw.
        /// </summary>
        [Theory]
        [MemberData(nameof(Get_Booleans_Data))]
        public static async Task ReadArchive_WithEOCDComment_TrailingPrecedingGarbage(bool async)
        {
            async Task InsertEntry(ZipArchive archive, string name, string contents, bool async)
            {
                ZipArchiveEntry entry = archive.CreateEntry(name);
                Stream s = await OpenEntryStream(async, entry);
                using (StreamWriter writer = new StreamWriter(s))
                {
                    writer.WriteLine(contents);
                }
                await DisposeStream(async, s);
            }

            async Task<int> GetEntryContentsLength(ZipArchiveEntry entry, bool async)

Review comment (bug):
Before re-opening `testStream` for the final verification, the stream should be rewound to the beginning. `CreateZipArchive` does not reset the stream position, and after disposing the previous archive the stream is likely positioned near EOF, which can make the subsequent open/read behave incorrectly or fail.

Code after:
                // compression method should not have changed
                Assert.Equal(firstEntryCompressionMethod, fileContent[8]);

                testStream.Seek(0, SeekOrigin.Begin);
                // second attempt: open archive with zero-length file that is compressed (Deflate = 0x8)
                zip = await CreateZipArchive(async, testStream, ZipArchiveMode.Update, leaveOpen: true);

                var zipEntryStream = await OpenEntryStream(async, zip.Entries[0]);
                // Opening and disposing an entry stream without writing does not mark the archive as modified,
                // so no rewrite will occur
                await DisposeStream(async, zipEntryStream);

                await DisposeZipArchive(async, zip);

                fileContent = testStream.ToArray();

                // compression method should remain unchanged since we didn't write anything
                Assert.Equal(firstEntryCompressionMethod, fileContent[8]);

                testStream.Seek(0, SeekOrigin.Begin);
                // extract and check the file
                zip = await CreateZipArchive(async, testStream, ZipArchiveMode.Update);

                ZipArchiveEntry entry = zip.GetEntry(ExpectedFileName);
                // The entry retains its original properties since it was never modified
                Assert.Equal(0, entry.Length);

                var extractedEntryStream = await OpenEntryStream(async, entry);
                byte[] buffer = new byte[1];
                int bytesRead;
                if (async)
                {
                    bytesRead = await extractedEntryStream.ReadAsync(buffer, 0, buffer.Length);
                }
                else
                {
                    bytesRead = extractedEntryStream.Read(buffer, 0, buffer.Length);
                }

                Assert.Equal(0, bytesRead);

                await DisposeStream(async, extractedEntryStream);
                await DisposeZipArchive(async, zip);
            }
        }
        /// <summary>
        /// Opens an empty file that has a 64KB EOCD comment.
        /// Adds two 64KB text entries. Verifies they can be read correctly.
        /// Appends 64KB of garbage at the end of the file. Verifies we throw.
        /// Prepends 64KB of garbage at the beginning of the file. Verifies we throw.
        /// </summary>