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

Code before:
                    switch (access)
                    {
                        case FileAccess.Read:
                            return OpenInReadMode(checkOpenable: true);
                        case FileAccess.Write:
                            return OpenInWriteMode();
                        case FileAccess.ReadWrite:
                            return OpenInUpdateMode();
                        default:
                            throw new ArgumentException(SR.InvalidFileAccess, nameof(access));
                    }

                default:
                    Debug.Assert(_archive.Mode == ZipArchiveMode.Update);
                    return OpenInUpdateMode();
            }
        }

        /// <summary>
        /// Returns the FullName of the entry.
        /// </summary>
        /// <returns>FullName of the entry</returns>
        public override string ToString()
        {
            return FullName;
        }

        private string DecodeEntryString(byte[] entryStringBytes)
        {
            Debug.Assert(entryStringBytes != null);

            Encoding readEntryStringEncoding =
                (_generalPurposeBitFlag & BitFlagValues.UnicodeFileNameAndComment) == BitFlagValues.UnicodeFileNameAndComment
                ? Encoding.UTF8
                : _archive?.EntryNameAndCommentEncoding ?? Encoding.UTF8;

            return readEntryStringEncoding.GetString(entryStringBytes);
        }

        // Only allow opening ZipArchives with large ZipArchiveEntries in update mode when running in a 64-bit process.
        // This is for compatibility with old behavior that threw an exception for all process bitnesses, because this
        // will not work in a 32-bit process.
        private static readonly bool s_allowLargeZipArchiveEntriesInUpdateMode = IntPtr.Size > 4;

        internal bool EverOpenedForWrite => _everOpenedForWrite;

        internal long GetOffsetOfCompressedData()
        {
            if (_storedOffsetOfCompressedData == null)
            {
                _archive.ArchiveStream.Seek(_offsetOfLocalHeader, SeekOrigin.Begin);

Review comment (bug):
Invalid `FileAccess` values are not properly validated in Read and Create modes. 

In Read mode (lines 381-384): An invalid value like `(FileAccess)0` or `(FileAccess)4` will throw `CannotBeWrittenInReadMode`, which is misleading since the real issue is an invalid parameter value.

In Create mode (lines 386-389): An invalid value like `(FileAccess)0` or `(FileAccess)4` will incorrectly succeed and call `OpenInWriteMode()`.

Add explicit validation for valid FileAccess enum values before the mode-specific logic. For example:
```csharp
if (access != FileAccess.Read && access != FileAccess.Write && access != FileAccess.ReadWrite)
    throw new ArgumentException(SR.InvalidFileAccess, nameof(access));
```

Code after:
        /// </list>
        /// </remarks>
        /// <exception cref="ArgumentOutOfRangeException"><paramref name="access"/> is not a valid <see cref="FileAccess"/> value.</exception>
        /// <exception cref="InvalidOperationException">The requested access is not compatible with the archive's open mode.</exception>
        /// <exception cref="IOException">The entry is already currently open for writing. -or- The entry has been deleted from the archive. -or- The archive that this entry belongs to was opened in ZipArchiveMode.Create, and this entry has already been written to once.</exception>
        /// <exception cref="InvalidDataException">The entry is missing from the archive or is corrupt and cannot be read. -or- The entry has been compressed using a compression method that is not supported.</exception>
        /// <exception cref="ObjectDisposedException">The ZipArchive that this entry belongs to has been disposed.</exception>
        public Stream Open(FileAccess access)
        {
            ThrowIfInvalidArchive();

            if (access is not (FileAccess.Read or FileAccess.Write or FileAccess.ReadWrite))
                throw new ArgumentOutOfRangeException(nameof(access), SR.InvalidFileAccess);

            // Validate that the requested access is compatible with the archive's mode
            switch (_archive.Mode)
            {
                case ZipArchiveMode.Read:
                    if (access != FileAccess.Read)
                        throw new InvalidOperationException(SR.CannotBeWrittenInReadMode);
                    return OpenInReadMode(checkOpenable: true);

                case ZipArchiveMode.Create:
                    if (access == FileAccess.Read)
                        throw new InvalidOperationException(SR.CannotBeReadInCreateMode);
                    return OpenInWriteMode();

                case ZipArchiveMode.Update:
                default:
                    Debug.Assert(_archive.Mode == ZipArchiveMode.Update);
                    switch (access)
                    {
                        case FileAccess.Read:
                            return OpenInReadMode(checkOpenable: true);
                        case FileAccess.Write:
                            return OpenInUpdateMode(loadExistingContent: false);
                        case FileAccess.ReadWrite:
                        default:
                            return OpenInUpdateMode(loadExistingContent: true);
                    }
            }
        }

        /// <summary>
        /// Returns the FullName of the entry.
        /// </summary>
        /// <returns>FullName of the entry</returns>
        public override string ToString()
        {
            return FullName;
        }