從 .NET 11 開始,CborReader 和 CborWriter 預設都會強制限制巢狀深度上限。 讀取或寫入超過設定最大深度的 CBOR 資料會拋出例外。
所推出的版本
.NET 11 預覽 5
以前的行為
之前 CborReader ,且 CborWriter 沒有最大巢穴深度限制。 讀取或寫入任意巢狀的 CBOR 資料結構則無限制地成功。
// 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
}
var writer = new CborWriter();
for (int i = 0; i < 2000; i++)
{
writer.WriteStartArray(1); // Succeeded at any depth
}
新行為
從 .NET 11 開始,CborReader當讀取超過最大允許深度(預設:64)的容器(陣列、映射或不定長度字串)時,會拋CborContentException出。
CborWriter 會在寫入會超過 InvalidOperationException 最大允許深度(預設:1000)的容器時擲回 InvalidOperationException。
// 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
}
// 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
}
破壞性變更的類型
此變更為行為變更。
變更的原因
此變更限制巢狀深度,以防止過度的記憶體消耗與執行時間。 當你跳過深度巢狀的陣列或映射時,系統必須處理結構中的每個元素,這可能會消耗大量記憶體。 此變化也與 的Utf8JsonReaderUtf8JsonWriter行為一致。
建議的動作
如果您的應用程式處理的 CBOR 資料巢狀結構比預設允許的還要深(64 層用於讀取,1000 層用於寫入),請使用新的選項類型來指定更大的限制:
// For reading CBOR data nested more than 64 levels deep
var options = new CborReaderOptions { MaxDepth = 256 };
var reader = new CborReader(data, options);
// For writing CBOR data nested more than 1000 levels deep
var writerOptions = new CborWriterOptions { MaxDepth = 2000 };
var writer = new CborWriter(writerOptions);
Note
與 Utf8JsonReader/Utf8JsonWriter不同,CBOR 中的設定 MaxDepth = 0 是 不允許巢狀( 不是「使用執行時預設值」)。 要使用執行時預設值,請在構造 MaxDepth = -1CborReaderOptions/時設定CborWriterOptions或省略該屬性。
沒有可用於還原先前無限深度行為的 AppContext 開關。
受影響的 API
- System.Formats.Cbor.CborReader.ReadStartArray()
- System.Formats.Cbor.CborReader.ReadStartMap()
- System.Formats.Cbor.CborReader.ReadStartIndefiniteLengthByteString()
- System.Formats.Cbor.CborReader.ReadStartIndefiniteLengthTextString()
- CborWriter.WriteStartArray(Nullable<Int32>)
- System.Formats.Cbor.CborWriter.WriteStartIndefiniteLengthByteString()
- System.Formats.Cbor.CborWriter.WriteStartIndefiniteLengthTextString()
- System.Formats.Cbor.CborWriter.WriteStartMap(Nullable<Int32>)