Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/core/compatibility/11.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ See [Breaking changes in ASP.NET Core 10](/aspnet/core/breaking-changes/10/overv

| Title | Type of change |
|-------------------------------------------------------------------|-------------------|
| [CRC32 validation added when reading ZIP archive entries](core-libraries/11/ziparchive-entry-crc32-validation.md) | Behavioral change |
| [DateOnly and TimeOnly TryParse methods throw for invalid input](core-libraries/11/dateonly-timeonly-tryparse-argumentexception.md) | Behavioral change |
| [DeflateStream and GZipStream write headers and footers for empty payload](core-libraries/11/deflatestream-gzipstream-empty-payload.md) | Behavioral change |
| [Environment.TickCount made consistent with Windows timeout behavior](core-libraries/11/environment-tickcount-windows-behavior.md) | Behavioral change |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
title: "Breaking change: CRC32 validation added when reading ZIP archive entries"
description: "Learn about the breaking change in .NET 11 where reading ZIP archive entries now validates CRC32 checksums and throws InvalidDataException for corrupted data."
ms.date: 04/03/2026
ai-usage: ai-assisted
---

# CRC32 validation added when reading ZIP archive entries

Starting in .NET 11, the <xref:System.IO.Compression> library validates CRC32 checksums when reading ZIP archive entries. If the computed CRC32 checksum doesn't match the expected value stored in the ZIP file's metadata, an <xref:System.IO.InvalidDataException> is thrown.

## Version introduced

.NET 11 Preview 3

## Previous behavior

Previously, `System.IO.Compression` didn't validate CRC32 checksums when reading ZIP archive entries. Corrupted or tampered ZIP entries could be read without errors, potentially causing silent data corruption.

```csharp
using System.IO.Compression;

using var archive = ZipFile.OpenRead("corrupted.zip");
var entry = archive.GetEntry("file.txt");
using var stream = entry.Open();

// Data could be read without any validation of its integrity.
byte[] buffer = new byte[entry.Length];
stream.Read(buffer, 0, buffer.Length);
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ZipArchiveEntry.Length is a long, so new byte[entry.Length] doesn't compile. Use an int buffer size (for example a fixed-size buffer) or convert safely, and avoid allocating based on the full entry size.

Copilot uses AI. Check for mistakes.
```

## New behavior

Starting in .NET 11, the library verifies the integrity of ZIP entries during read operations. If the computed CRC32 checksum doesn't match the expected value from the ZIP file's metadata, an <xref:System.IO.InvalidDataException> is thrown.

## Type of breaking change

This change is a [behavioral change](../../categories.md#behavioral-change).

## Reason for change

This change improves the reliability and security of `System.IO.Compression`. By validating CRC32 checksums, the library detects and prevents use of corrupted or tampered ZIP entries, ensuring applications don't inadvertently process invalid data. For more information, see [dotnet/runtime#124766](https://github.com/dotnet/runtime/pull/124766).

## Recommended action

If your application processes ZIP files that might be corrupted or tampered with, handle <xref:System.IO.InvalidDataException> appropriately:

```csharp
try
{
using var archive = ZipFile.OpenRead("example.zip");
var entry = archive.GetEntry("file.txt");
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the recommended action sample, archive.GetEntry("file.txt") can return null, and the next line calls entry.Open() unconditionally. Add a null check so the sample fails with a clear message rather than NullReferenceException.

Suggested change
var entry = archive.GetEntry("file.txt");
var entry = archive.GetEntry("file.txt")
?? throw new InvalidOperationException("The ZIP archive doesn't contain 'file.txt'.");

Copilot uses AI. Check for mistakes.
using var stream = entry.Open();

byte[] buffer = new byte[entry.Length];
stream.Read(buffer, 0, buffer.Length);
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the recommended action sample, new byte[entry.Length] doesn't compile because ZipArchiveEntry.Length is long. Use a fixed-size buffer (or a safe conversion) instead of sizing the array from entry.Length.

Copilot uses AI. Check for mistakes.
}
catch (InvalidDataException ex)
{
Console.WriteLine($"Error reading ZIP entry: {ex.Message}");
}
```

## Affected APIs

- <xref:System.IO.Compression.ZipArchiveEntry.Open?displayProperty=fullName>
2 changes: 2 additions & 0 deletions docs/core/compatibility/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ items:
href: 11.md
- name: Core .NET libraries
items:
- name: CRC32 validation added when reading ZIP archive entries
href: core-libraries/11/ziparchive-entry-crc32-validation.md
- name: DateOnly and TimeOnly TryParse methods throw for invalid input
href: core-libraries/11/dateonly-timeonly-tryparse-argumentexception.md
- name: DeflateStream and GZipStream write headers and footers for empty payload
Expand Down
Loading