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

Code before:
        public static async Task OpenWithFileAccess_CreateMode_WriteAccess_Succeeds(bool async)
        {
            using var ms = new MemoryStream();
            ZipArchive archive = await CreateZipArchive(async, ms, ZipArchiveMode.Create, leaveOpen: true);

            ZipArchiveEntry entry = archive.CreateEntry("test.txt");

            using Stream stream = entry.Open(FileAccess.Write);
            Assert.False(stream.CanRead);
            Assert.True(stream.CanWrite);

            await DisposeZipArchive(async, archive);
        }

        [Theory]
        [MemberData(nameof(Get_Booleans_Data))]
        public static async Task OpenWithFileAccess_CreateMode_ReadWriteAccess_Succeeds(bool async)
        {
            using var ms = new MemoryStream();
            ZipArchive archive = await CreateZipArchive(async, ms, ZipArchiveMode.Create, leaveOpen: true);

            ZipArchiveEntry entry = archive.CreateEntry("test.txt");

            // ReadWrite should be allowed in Create mode (it opens in write mode)
            using Stream stream = entry.Open(FileAccess.ReadWrite);
            Assert.True(stream.CanWrite);

            await DisposeZipArchive(async, archive);
        }

        [Theory]
        [MemberData(nameof(Get_Booleans_Data))]
        public static async Task OpenWithFileAccess_CreateMode_ReadAccess_Throws(bool async)
        {
            using var ms = new MemoryStream();
            ZipArchive archive = await CreateZipArchive(async, ms, ZipArchiveMode.Create, leaveOpen: true);

            ZipArchiveEntry entry = archive.CreateEntry("test.txt");

            Assert.Throws<ArgumentException>("access", () => entry.Open(FileAccess.Read));

            await DisposeZipArchive(async, archive);
        }

        [Theory]
        [MemberData(nameof(Get_Booleans_Data))]
        public static async Task OpenWithFileAccess_UpdateMode_ReadAccess_Succeeds(bool async)
        {
            using MemoryStream ms = await StreamHelpers.CreateTempCopyStream(zfile("normal.zip"));
            ZipArchive archive = await CreateZipArchive(async, ms, ZipArchiveMode.Update);


Review comment (suggestion):
In Create mode with `FileAccess.ReadWrite`, the test verifies `stream.CanWrite` but doesn't verify `stream.CanRead` like the corresponding Update mode test does (line 2324-2326). For consistency and completeness, consider adding an assertion for `stream.CanRead` to match the behavior documented in the comment on line 2256.

Code after:
                Assert.Equal(expectedLength.Value, stream.Length);

            await DisposeZipArchive(async, archive);
            ms.Dispose();
        }

        public static IEnumerable<object[]> OpenWithFileAccess_IncompatibleAccess_Throws_Data()
        {
            foreach (bool async in new[] { true, false })
            {
                // Read mode: Write and ReadWrite are not allowed
                yield return new object[] { async, ZipArchiveMode.Read, FileAccess.Write };
                yield return new object[] { async, ZipArchiveMode.Read, FileAccess.ReadWrite };
                // Create mode: Read is not allowed
                yield return new object[] { async, ZipArchiveMode.Create, FileAccess.Read };
            }
        }

        [Theory]
        [MemberData(nameof(OpenWithFileAccess_IncompatibleAccess_Throws_Data))]
        public static async Task OpenWithFileAccess_IncompatibleAccess_Throws(bool async, ZipArchiveMode mode, FileAccess access)
        {
            MemoryStream ms = mode == ZipArchiveMode.Create
                ? new MemoryStream()
                : await StreamHelpers.CreateTempCopyStream(zfile("normal.zip"));

            ZipArchive archive = await CreateZipArchive(async, ms, mode, leaveOpen: true);

            ZipArchiveEntry entry = mode == ZipArchiveMode.Create
                ? archive.CreateEntry("test.txt")
                : archive.GetEntry("first.txt");
            Assert.NotNull(entry);

            Assert.Throws<InvalidOperationException>(() => entry.Open(access));
            await Assert.ThrowsAsync<InvalidOperationException>(() => entry.OpenAsync(access));

            await DisposeZipArchive(async, archive);
            ms.Dispose();
        }

        [Theory]
        [MemberData(nameof(Get_Booleans_Data))]
        public static async Task OpenWithFileAccess_UpdateMode_WriteAccess_CanWriteAndReadBack(bool async)
        {
            const string entryName = "new_entry.txt";
            const string testContent = "Hello, World!";
            byte[] testData = System.Text.Encoding.UTF8.GetBytes(testContent);

            using MemoryStream ms = new MemoryStream();

            // Create archive with an entry using FileAccess.Write