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

Code before:
        /// Opens the entry. If the archive that the entry belongs to was opened in Read mode, the returned stream will be readable, and it may or may not be seekable. If Create mode, the returned stream will be writable and not seekable. If Update mode, the returned stream will be readable, writable, seekable, and support SetLength.
        /// </summary>
        /// <returns>A Stream that represents the contents of the entry.</returns>
        /// <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()
        {
            ThrowIfInvalidArchive();

            switch (_archive.Mode)
            {
                case ZipArchiveMode.Read:
                    return OpenInReadMode(checkOpenable: true);
                case ZipArchiveMode.Create:
                    return OpenInWriteMode();
                case ZipArchiveMode.Update:
                default:
                    Debug.Assert(_archive.Mode == ZipArchiveMode.Update);
                    return OpenInUpdateMode();
            }
        }

        /// <summary>
        /// Opens the entry with the specified access mode. This allows for more granular control over the returned stream's capabilities.
        /// </summary>
        /// <param name="access">The file access mode for the returned stream.</param>
        /// <returns>A <see cref="Stream"/> that represents the contents of the entry with the specified access capabilities.</returns>
        /// <exception cref="ArgumentException">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 and not FileAccess.Write and not FileAccess.ReadWrite)
                throw new ArgumentException(SR.InvalidFileAccess, nameof(access));

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

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

Review comment (suggestion):
The XML documentation summary doesn't adequately describe what each FileAccess mode does in different ZipArchiveModes, particularly the important behavioral differences in Update mode. Consider adding a remarks section that explains:
- In Read mode: only FileAccess.Read is allowed
- In Create mode: FileAccess.Write and FileAccess.ReadWrite are allowed (both behave as write-only)
- In Update mode: 
  - FileAccess.Read opens a read-only stream without loading into memory
  - FileAccess.Write provides an empty writable stream, discarding existing data
  - FileAccess.ReadWrite loads existing data into memory for modification (same as parameterless Open())

This is especially important because the behavior in Update mode with FileAccess.Write (discarding existing data) is semantically different from intuitive expectations.

Code after:
        /// Opens the entry. If the archive that the entry belongs to was opened in Read mode, the returned stream will be readable, and it may or may not be seekable. If Create mode, the returned stream will be writable and not seekable. If Update mode, the returned stream will be readable, writable, seekable, and support SetLength.
        /// </summary>
        /// <returns>A Stream that represents the contents of the entry.</returns>
        /// <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()
        {
            ThrowIfInvalidArchive();

            switch (_archive.Mode)
            {
                case ZipArchiveMode.Read:
                    return OpenInReadMode(checkOpenable: true);
                case ZipArchiveMode.Create:
                    return OpenInWriteMode();
                case ZipArchiveMode.Update:
                default:
                    Debug.Assert(_archive.Mode == ZipArchiveMode.Update);
                    return OpenInUpdateMode();
            }
        }

        /// <summary>
        /// Opens the entry with the specified access mode. This allows for more granular control over the returned stream's capabilities.
        /// </summary>
        /// <param name="access">The file access mode for the returned stream.</param>
        /// <returns>A <see cref="Stream"/> that represents the contents of the entry with the specified access capabilities.</returns>
        /// <remarks>
        /// <para>The allowed <paramref name="access"/> values depend on the <see cref="ZipArchiveMode"/>:</para>
        /// <list type="bullet">
        /// <item><description><see cref="ZipArchiveMode.Read"/>: Only <see cref="FileAccess.Read"/> is allowed.</description></item>
        /// <item><description><see cref="ZipArchiveMode.Create"/>: <see cref="FileAccess.Write"/> and <see cref="FileAccess.ReadWrite"/> are allowed (both write-only).</description></item>
        /// <item><description><see cref="ZipArchiveMode.Update"/>: All values are allowed. <see cref="FileAccess.Read"/> reads directly from the archive. <see cref="FileAccess.Write"/> discards existing content and provides an empty writable stream. <see cref="FileAccess.ReadWrite"/> loads existing content into memory (equivalent to <see cref="Open()"/>).</description></item>
        /// </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)
            {