diff --git a/docs/core/compatibility/11.md b/docs/core/compatibility/11.md index 7fa15ba32a648..786ec105b5281 100644 --- a/docs/core/compatibility/11.md +++ b/docs/core/compatibility/11.md @@ -50,6 +50,7 @@ See [Breaking changes in EF Core 11](/ef/core/what-is-new/ef-core-11.0/breaking- | Title | Type of change | |-------|-------------------| +| [CborReader and CborWriter enforce a default maximum nesting depth](extensions/11/cbor-max-depth.md) | Behavioral change | | [IHost.RunAsync and IHost.StopAsync throw when a BackgroundService fails](extensions/11/ihost-runasync-stopasync-throw-backgroundservice-failure.md) | Behavioral change | | [Some Microsoft.Extensions packages included in shared framework](extensions/11/extensions-in-shared-framework.md) | Behavioral change | diff --git a/docs/core/compatibility/extensions/11/cbor-max-depth.md b/docs/core/compatibility/extensions/11/cbor-max-depth.md new file mode 100644 index 0000000000000..219404548468d --- /dev/null +++ b/docs/core/compatibility/extensions/11/cbor-max-depth.md @@ -0,0 +1,101 @@ +--- +title: "Breaking change: CborReader and CborWriter enforce a default maximum nesting depth" +description: "Learn about the breaking change in .NET 11 where CborReader and CborWriter enforce a maximum nesting depth by default, throwing exceptions when the limit is exceeded." +ms.date: 06/12/2026 +ai-usage: ai-assisted +--- + +# CborReader and CborWriter enforce a default maximum nesting depth + +Starting in .NET 11, `CborReader` and `CborWriter` enforce a maximum nesting depth by default. Reading or writing CBOR data that exceeds the configured maximum depth throws an exception. + +## Version introduced + +.NET 11 Preview 5 + +## Previous behavior + +Previously, `CborReader` and `CborWriter` had no maximum nesting depth limit. Reading or writing arbitrarily nested CBOR data structures succeeded without restriction. + +```csharp +// Deeply nested CBOR data (100 levels of nested arrays) +var reader = new CborReader(deeplyNestedBuffer); + +for (int i = 0; i < 100; i++) +{ + reader.ReadStartArray(); // Succeeded at any depth +} +``` + +```csharp +var writer = new CborWriter(); + +for (int i = 0; i < 2000; i++) +{ + writer.WriteStartArray(1); // Succeeded at any depth +} +``` + +## New behavior + +Starting in .NET 11, `CborReader` throws when reading a container (array, map, or indefinite-length string) that would exceed the maximum allowed depth (default: 64). `CborWriter` throws when writing a container that would exceed the maximum allowed depth (default: 1000). + +```csharp +// Throws CborContentException when nesting depth exceeds 64 +var reader = new CborReader(deeplyNestedBuffer); + +for (int i = 0; i < 65; i++) +{ + reader.ReadStartArray(); // Throws CborContentException on the 65th call +} +``` + +```csharp +// Throws InvalidOperationException when nesting depth exceeds 1000 +var writer = new CborWriter(); + +for (int i = 0; i < 1001; i++) +{ + writer.WriteStartArray(1); // Throws InvalidOperationException on the 1001st call +} +``` + +## Type of breaking change + +This change is a [behavioral change](../../categories.md#behavioral-change). + +## Reason for change + +To prevent excessive memory consumption and execution time, this change limits the nesting depth. Skipping over a deeply nested array or map requires processing every element in the structure, which can use a surprising amount of memory. This change is also consistent with the behavior of and . + +## Recommended action + +If your application processes CBOR data nested more deeply than the defaults allow (64 levels for reading, 1000 levels for writing), use the new options types to specify a larger limit: + +```csharp +// For reading CBOR data nested more than 64 levels deep +var options = new CborReaderOptions { MaxDepth = 256 }; +var reader = new CborReader(data, options); +``` + +```csharp +// For writing CBOR data nested more than 1000 levels deep +var writerOptions = new CborWriterOptions { MaxDepth = 2000 }; +var writer = new CborWriter(writerOptions); +``` + +> [!NOTE] +> Unlike `Utf8JsonReader`/`Utf8JsonWriter`, setting `MaxDepth = 0` in CBOR means *no nesting is allowed* (not "use the runtime default"). To use the runtime default, set `MaxDepth = -1` or omit the property when constructing `CborReaderOptions`/`CborWriterOptions`. + +There is no AppContext switch to restore the previous unlimited-depth behavior. + +## Affected APIs + +- +- +- +- +- +- +- +- diff --git a/docs/core/compatibility/toc.yml b/docs/core/compatibility/toc.yml index e90706727d39f..6d3f16df24ef6 100644 --- a/docs/core/compatibility/toc.yml +++ b/docs/core/compatibility/toc.yml @@ -38,6 +38,8 @@ items: href: cryptography/11/dsa-removed-macos.md - name: Extensions items: + - name: CborReader and CborWriter enforce a default maximum nesting depth + href: extensions/11/cbor-max-depth.md - name: IHost.RunAsync and IHost.StopAsync throw when a BackgroundService fails href: extensions/11/ihost-runasync-stopasync-throw-backgroundservice-failure.md - name: Some Microsoft.Extensions packages included in shared framework