Skip to content

Commit 13e5897

Browse files
SteveSandersonMSpranavkm
authored andcommitted
Fix MessagePackReader for multi-segment strings (#1)
* Add failing unit test to show the bug
1 parent d5d6b6e commit 13e5897

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

src/MessagePack/MessagePackReader.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,7 @@ private string ReadStringSlow(int byteLength)
808808
}
809809
}
810810
#endif
811+
this.reader.Advance(bytesRead);
811812
}
812813

813814
string value = new string(charArray, 0, initializedChars);
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using System;
2+
using System.Buffers;
3+
using Xunit;
4+
5+
namespace MessagePack.Tests
6+
{
7+
partial class MessagePackReaderTests
8+
{
9+
[Fact]
10+
public void ReadString_HandlesSingleSegment()
11+
{
12+
var seq = BuildSequence(new[] {
13+
(byte)(MessagePackCode.MinFixStr + 2),
14+
(byte)'A', (byte)'B' });
15+
16+
var reader = new MessagePackReader(seq);
17+
var result = reader.ReadString();
18+
Assert.Equal("AB", result);
19+
}
20+
21+
[Fact]
22+
public void ReadString_HandlesMultipleSegments()
23+
{
24+
var seq = BuildSequence(
25+
new[] { (byte)(MessagePackCode.MinFixStr + 2), (byte)'A' },
26+
new[] { (byte)'B' });
27+
28+
var reader = new MessagePackReader(seq);
29+
var result = reader.ReadString();
30+
Assert.Equal("AB", result);
31+
}
32+
33+
ReadOnlySequence<T> BuildSequence<T>(params T[][] segmentContents)
34+
{
35+
var segments = new TestSequenceSegment<T>[segmentContents.Length];
36+
TestSequenceSegment<T> last = null;
37+
for (var i = 0; i < segmentContents.Length; i++)
38+
{
39+
last = segments[i] = new TestSequenceSegment<T>(segmentContents[i], last);
40+
}
41+
42+
return new ReadOnlySequence<T>(segments[0], 0, last, last.Memory.Length);
43+
}
44+
45+
class TestSequenceSegment<T> : ReadOnlySequenceSegment<T>
46+
{
47+
public TestSequenceSegment(T[] data, TestSequenceSegment<T> prev = null)
48+
{
49+
Memory = new Memory<T>(data);
50+
51+
if (prev != null)
52+
{
53+
prev.Next = this;
54+
RunningIndex = prev.RunningIndex + prev.Memory.Length;
55+
}
56+
}
57+
}
58+
}
59+
}

0 commit comments

Comments
 (0)