Skip to content

Commit 814894c

Browse files
authored
Fix CborWriter.Reset.
The first issue is that Reset did not correctly set _definiteLength back after a reset. If allowMultipleRootLevelValues from the constructor is false, the default, it should be initialized to 1. However Reset set it as null, which behaves as if allowMultipleRootLevelValues is true. This sets _definiteLength back to the same way the constructor does. The second is that _currentIndefiniteLengthStringRanges is not cleared during Reset. This means if a Reset occurred while in the middle of writing an indefinite length value and convertIndefiniteLengthEncodings is true, the next time an encode tried to re-encode segments as definite encoding where the list indicated would be pointing to incorrect locations.
1 parent de62bfc commit 814894c

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

src/libraries/System.Formats.Cbor/src/System/Formats/Cbor/Writer/CborWriter.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public void Reset()
110110
_offset = 0;
111111
_nestedDataItems?.Clear();
112112
_currentMajorType = null;
113-
_definiteLength = null;
113+
_definiteLength = AllowMultipleRootLevelValues ? null : (int?)1;
114114
_itemsWritten = 0;
115115
_frameOffset = 0;
116116
_isTagContext = false;
@@ -120,6 +120,7 @@ public void Reset()
120120
_keysRequireSorting = false;
121121
_keyValuePairEncodingRanges?.Clear();
122122
_keyEncodingRanges?.Clear();
123+
_currentIndefiniteLengthStringRanges?.Clear();
123124
}
124125
}
125126

src/libraries/System.Formats.Cbor/tests/Writer/CborWriterTests.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,33 @@ public static void Reset_NonTrivialWriter_HappyPath()
123123
Assert.Equal(new byte[] { 0x18, 0x2a }, writer.Encode());
124124
}
125125

126+
[Fact]
127+
public static void Reset_PreservesMultipleRootLevels()
128+
{
129+
var writer = new CborWriter(allowMultipleRootLevelValues: false);
130+
writer.WriteBoolean(true);
131+
writer.Reset();
132+
writer.WriteInt32(6);
133+
Assert.Throws<InvalidOperationException>(() => writer.WriteInt32(7));
134+
}
135+
136+
[Fact]
137+
public static void Reset_ClearsIndefiniteLengthRanges()
138+
{
139+
var writer = new CborWriter(convertIndefiniteLengthEncodings: true);
140+
141+
writer.WriteStartIndefiniteLengthByteString();
142+
writer.WriteByteString([1, 2, 3]);
143+
writer.Reset();
144+
145+
writer.WriteStartIndefiniteLengthByteString();
146+
writer.WriteByteString([1, 2, 3]);
147+
writer.WriteEndIndefiniteLengthByteString();
148+
ReadOnlySpan<byte> encoded = writer.Encode();
149+
ReadOnlySpan<byte> expected = [0x43, 0x01, 0x02, 0x03];
150+
AssertExtensions.SequenceEqual(expected, encoded);
151+
}
152+
126153
[Fact]
127154
public static void ConformanceMode_DefaultValue_ShouldEqualStrict()
128155
{

0 commit comments

Comments
 (0)