Skip to content

Commit 4b891d8

Browse files
committed
fix read error with reused uncleared packet
fix 0 length read at the start of a packe in plp stream returning 0 when continuing handle char array sizing better change existing test to use multiple packet sizes
1 parent 31b5f28 commit 4b891d8

File tree

4 files changed

+28
-18
lines changed

4 files changed

+28
-18
lines changed

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13149,7 +13149,7 @@ bool writeDataSizeToSnapshot
1314913149
if (stateObj._longlen == 0)
1315013150
{
1315113151
Debug.Assert(stateObj._longlenleft == 0);
13152-
totalCharsRead = 0;
13152+
totalCharsRead = startOffsetByteCount >> 1;
1315313153
return TdsOperationStatus.Done; // No data
1315413154
}
1315513155

@@ -13169,14 +13169,14 @@ bool writeDataSizeToSnapshot
1316913169
// later needing to repeatedly allocate new target buffers and copy data as we discover new data
1317013170
if (buff == null && stateObj._longlen != TdsEnums.SQL_PLP_UNKNOWNLEN && stateObj._longlen < (int.MaxValue >> 1))
1317113171
{
13172-
if (supportRentedBuff && stateObj._longlen < 1073741824) // 1 Gib
13172+
if (supportRentedBuff && stateObj._longlen >> 1 < 1073741824) // 1 Gib
1317313173
{
13174-
buff = ArrayPool<char>.Shared.Rent((int)Math.Min((int)stateObj._longlen, len));
13174+
buff = ArrayPool<char>.Shared.Rent((int)Math.Min((int)stateObj._longlen >> 1, len));
1317513175
rentedBuff = true;
1317613176
}
1317713177
else
1317813178
{
13179-
buff = new char[(int)Math.Min((int)stateObj._longlen, len)];
13179+
buff = new char[(int)Math.Min((int)stateObj._longlen >> 1, len)];
1318013180
rentedBuff = false;
1318113181
}
1318213182
}

src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13312,7 +13312,7 @@ bool writeDataSizeToSnapshot
1331213312
if (stateObj._longlen == 0)
1331313313
{
1331413314
Debug.Assert(stateObj._longlenleft == 0);
13315-
totalCharsRead = 0;
13315+
totalCharsRead = startOffsetByteCount >> 1;
1331613316
return TdsOperationStatus.Done; // No data
1331713317
}
1331813318

@@ -13332,14 +13332,14 @@ bool writeDataSizeToSnapshot
1333213332
// allocate the whole buffer in one shot instead of realloc'ing and copying over each time
1333313333
if (buff == null && stateObj._longlen != TdsEnums.SQL_PLP_UNKNOWNLEN && stateObj._longlen < (int.MaxValue >> 1))
1333413334
{
13335-
if (supportRentedBuff && stateObj._longlen < 1073741824) // 1 Gib
13335+
if (supportRentedBuff && stateObj._longlen >> 1 < 1073741824) // 1 Gib
1333613336
{
13337-
buff = ArrayPool<char>.Shared.Rent((int)Math.Min((int)stateObj._longlen, len));
13337+
buff = ArrayPool<char>.Shared.Rent((int)Math.Min((int)stateObj._longlen >> 1, len));
1333813338
rentedBuff = true;
1333913339
}
1334013340
else
1334113341
{
13342-
buff = new char[(int)Math.Min((int)stateObj._longlen, len)];
13342+
buff = new char[(int)Math.Min((int)stateObj._longlen >> 1, len)];
1334313343
rentedBuff = false;
1334413344
}
1334513345
}

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3764,8 +3764,9 @@ internal sealed partial class StateSnapshot
37643764
{
37653765
private sealed partial class PacketData
37663766
{
3767-
public byte[] Buffer;
3768-
public int Read;
3767+
public readonly byte[] Buffer;
3768+
public readonly int Read;
3769+
37693770
public PacketData NextPacket;
37703771
public PacketData PrevPacket;
37713772

@@ -3775,6 +3776,12 @@ private sealed partial class PacketData
37753776
/// </summary>
37763777
public int RunningDataSize;
37773778

3779+
public PacketData(byte[] buffer, int read)
3780+
{
3781+
Buffer = buffer;
3782+
Read = read;
3783+
}
3784+
37783785
public int PacketID => Packet.GetIDFromHeader(Buffer.AsSpan(0, TdsEnums.HEADER_LEN));
37793786

37803787
internal int GetPacketDataOffset()
@@ -4172,10 +4179,7 @@ internal void AppendPacketData(byte[] buffer, int read)
41724179
}
41734180
}
41744181
#endif
4175-
PacketData packetData = new PacketData();
4176-
4177-
packetData.Buffer = buffer;
4178-
packetData.Read = read;
4182+
PacketData packetData = new PacketData(buffer, read);
41794183
#if DEBUG
41804184
packetData.SetDebugStack(_stateObj._lastStack);
41814185
packetData.SetDebugPacketId(Interlocked.Increment(ref _packetCounter));

src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderTest.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,11 +1035,18 @@ [Value] [nvarchar](max) NULL
10351035
}
10361036
}
10371037

1038-
int counter = 0;
1039-
while (counter < 10)
1038+
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(DataTestUtility.TCPConnectionString);
1039+
builder.PersistSecurityInfo = true;
1040+
builder.Pooling = false;
1041+
1042+
for (int packetSize = 512; packetSize<2048; packetSize++)
10401043
{
1041-
using (var cmd = cn.CreateCommand())
1044+
builder.PacketSize = packetSize;
1045+
using (SqlConnection sizedConnection = new SqlConnection(builder.ToString()))
1046+
using (SqlCommand cmd = sizedConnection.CreateCommand())
10421047
{
1048+
sizedConnection.Open();
1049+
10431050
cmd.CommandText = $"SELECT [d].[Id], [d].[DocumentIdentificationId], [d].[Name], [d].[Value] FROM [{tableName}] AS [d]";
10441051
using (var reader = await cmd.ExecuteReaderAsync())
10451052
{
@@ -1063,7 +1070,6 @@ [Value] [nvarchar](max) NULL
10631070
}
10641071
}
10651072
}
1066-
counter++;
10671073
}
10681074
}
10691075
finally

0 commit comments

Comments
 (0)