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

Code before:
            // write header
            await _archive.ArchiveStream.WriteAsync(lfStaticHeader, cancellationToken).ConfigureAwait(false);
            await _archive.ArchiveStream.WriteAsync(_storedEntryNameBytes, cancellationToken).ConfigureAwait(false);

            // Only when handling zip64
            if (zip64ExtraField != null)
            {
                await zip64ExtraField.WriteBlockAsync(_archive.ArchiveStream, cancellationToken).ConfigureAwait(false);
            }

            await ZipGenericExtraField.WriteAllBlocksAsync(_lhUnknownExtraFields, _lhTrailingExtraFieldData ?? Array.Empty<byte>(), _archive.ArchiveStream, cancellationToken).ConfigureAwait(false);
        }

        return zip64ExtraField != null;
    }

    private async Task WriteLocalFileHeaderAndDataIfNeededAsync(bool forceWrite, CancellationToken cancellationToken)
    {
        cancellationToken.ThrowIfCancellationRequested();

        // Check if the entry's stored data was actually modified (StoredData flag is set).
        // If _storedUncompressedData is loaded but StoredData is not set, it means the entry
        // was opened for update but no writes occurred - we should use the original compressed bytes.
        bool storedDataModified = (Changes & ZipArchive.ChangeState.StoredData) != 0;

        // If _storedUncompressedData is loaded but not modified, clear it so we use _compressedBytes
        if (_storedUncompressedData != null && !storedDataModified)
        {
            await _storedUncompressedData.DisposeAsync().ConfigureAwait(false);
            _storedUncompressedData = null;
        }

        // _storedUncompressedData gets frozen here, and is what gets written to the file
        if (_storedUncompressedData != null || _compressedBytes != null)
        {
            if (_storedUncompressedData != null)
            {
                _uncompressedSize = _storedUncompressedData.Length;

                //The compressor fills in CRC and sizes
                //The DirectToArchiveWriterStream writes headers and such
                DirectToArchiveWriterStream entryWriter = new(GetDataCompressor(_archive.ArchiveStream, true, null), this);
                await using (entryWriter)
                {
                    _storedUncompressedData.Seek(0, SeekOrigin.Begin);
                    await _storedUncompressedData.CopyToAsync(entryWriter, cancellationToken).ConfigureAwait(false);
                    await _storedUncompressedData.DisposeAsync().ConfigureAwait(false);
                    _storedUncompressedData = null;
                }
            }
            else

Review comment (suggestion):
Same concern as the sync path: discarding `_storedUncompressedData` when `StoredData` isn't set can create header/data mismatches because `GetUncompressedDataAsync()` may have already changed metadata (e.g., `CompressionMethod` is normalized to Deflate). If the archive is later rewritten for other reasons, the entry may be written with updated metadata but original `_compressedBytes`. Ensure metadata normalization happens only when the entry is actually modified, or restore original metadata when reverting to `_compressedBytes`.
```suggestion

```

Code after:
            {
                await zip64ExtraField.WriteBlockAsync(_archive.ArchiveStream, cancellationToken).ConfigureAwait(false);
            }

            await ZipGenericExtraField.WriteAllBlocksAsync(_lhUnknownExtraFields, _lhTrailingExtraFieldData ?? Array.Empty<byte>(), _archive.ArchiveStream, cancellationToken).ConfigureAwait(false);
        }

        return zip64ExtraField != null;
    }

    private async Task WriteLocalFileHeaderAndDataIfNeededAsync(bool forceWrite, CancellationToken cancellationToken)
    {
        cancellationToken.ThrowIfCancellationRequested();

        // Check if the entry's stored data was actually modified (StoredData flag is set).
        // If _storedUncompressedData is loaded but StoredData is not set, it means the entry
        // was opened for update but no writes occurred - we should use the original compressed bytes.
        bool storedDataModified = (Changes & ZipArchive.ChangeState.StoredData) != 0;

        // If _storedUncompressedData is loaded but not modified, clear it so we use _compressedBytes
        if (_storedUncompressedData != null && !storedDataModified)
        {
            await _storedUncompressedData.DisposeAsync().ConfigureAwait(false);
            _storedUncompressedData = null;
        }

        // _storedUncompressedData gets frozen here, and is what gets written to the file
        if (_storedUncompressedData != null || _compressedBytes != null)
        {
            if (_storedUncompressedData != null)
            {
                _uncompressedSize = _storedUncompressedData.Length;

                //The compressor fills in CRC and sizes
                //The DirectToArchiveWriterStream writes headers and such
                DirectToArchiveWriterStream entryWriter = new(GetDataCompressor(_archive.ArchiveStream, true, null), this);
                await using (entryWriter)
                {
                    _storedUncompressedData.Seek(0, SeekOrigin.Begin);
                    await _storedUncompressedData.CopyToAsync(entryWriter, cancellationToken).ConfigureAwait(false);
                    await _storedUncompressedData.DisposeAsync().ConfigureAwait(false);
                    _storedUncompressedData = null;
                }
            }
            else
            {
                if (_uncompressedSize == 0)
                {
                    // reset size to ensure proper central directory size header
                    _compressedSize = 0;
                }