Browse Source

Fix rare multi-packet string corruption (#3505)

* add test and simplify code to fix problems

* review feedback

* review feedback

* review feedback
pull/2894/merge
Wraith 3 days ago
committed by GitHub
parent
commit
63443f45e2
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 13
      src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs
  2. 15
      src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs
  3. 22
      src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs
  4. 191
      src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderTest.cs

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

@ -13116,11 +13116,10 @@ namespace Microsoft.Data.SqlClient
if (canContinue)
{
if (isContinuing || isStarting)
{
temp = stateObj.TryTakeSnapshotStorage() as char[];
Debug.Assert(temp == null || length == int.MaxValue || temp.Length == length, "stored buffer length must be null or must have been created with the correct length");
}
temp = stateObj.TryTakeSnapshotStorage() as char[];
Debug.Assert(temp != null || !isContinuing, "if continuing stored buffer must be present to contain previous data to continue from");
Debug.Assert(temp == null || length == int.MaxValue || temp.Length == length, "stored buffer length must be null or must have been created with the correct length");
if (temp != null)
{
startOffset = stateObj.GetSnapshotTotalSize();
@ -13136,7 +13135,7 @@ namespace Microsoft.Data.SqlClient
supportRentedBuff: !canContinue, // do not use the arraypool if we are going to keep the buffer in the snapshot
rentedBuff: ref buffIsRented,
startOffset,
isStarting || isContinuing
canContinue
);
if (result == TdsOperationStatus.Done)
@ -13163,7 +13162,7 @@ namespace Microsoft.Data.SqlClient
}
else if (result == TdsOperationStatus.NeedMoreData)
{
if (isStarting || isContinuing)
if (canContinue)
{
stateObj.SetSnapshotStorage(temp);
}

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

@ -13306,11 +13306,10 @@ namespace Microsoft.Data.SqlClient
if (canContinue)
{
if (isContinuing || isStarting)
{
temp = stateObj.TryTakeSnapshotStorage() as char[];
Debug.Assert(temp == null || length == int.MaxValue || temp.Length == length, "stored buffer length must be null or must have been created with the correct length");
}
temp = stateObj.TryTakeSnapshotStorage() as char[];
Debug.Assert(temp != null || !isContinuing, "if continuing stored buffer must be present to contain previous data to continue from");
Debug.Assert(temp == null || length == int.MaxValue || temp.Length == length, "stored buffer length must be null or must have been created with the correct length");
if (temp != null)
{
startOffset = stateObj.GetSnapshotTotalSize();
@ -13325,8 +13324,8 @@ namespace Microsoft.Data.SqlClient
out length,
supportRentedBuff: !canContinue, // do not use the arraypool if we are going to keep the buffer in the snapshot
rentedBuff: ref buffIsRented,
startOffset,
isStarting || isContinuing
startOffset,
canContinue
);
if (result == TdsOperationStatus.Done)
@ -13353,7 +13352,7 @@ namespace Microsoft.Data.SqlClient
}
else if (result == TdsOperationStatus.NeedMoreData)
{
if (isStarting || isContinuing)
if (canContinue)
{
stateObj.SetSnapshotStorage(temp);
}

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

@ -1529,11 +1529,10 @@ namespace Microsoft.Data.SqlClient
(bool canContinue, bool isStarting, bool isContinuing) = GetSnapshotStatuses();
if (canContinue)
{
if (isContinuing || isStarting)
{
temp = TryTakeSnapshotStorage() as byte[];
Debug.Assert(bytes == null || bytes.Length == length, "stored buffer length must be null or must have been created with the correct length");
}
temp = TryTakeSnapshotStorage() as byte[];
Debug.Assert(temp != null || !isContinuing, "if continuing stored buffer must be present to contain previous data to continue from");
Debug.Assert(bytes == null || bytes.Length == length, "stored buffer length must be null or must have been created with the correct length");
if (temp != null)
{
offset = GetSnapshotTotalSize();
@ -1554,7 +1553,7 @@ namespace Microsoft.Data.SqlClient
}
else if (result == TdsOperationStatus.NeedMoreData)
{
if (isStarting || isContinuing)
if (canContinue)
{
SetSnapshotStorage(temp);
}
@ -1983,11 +1982,10 @@ namespace Microsoft.Data.SqlClient
int startOffset = 0;
if (canContinue)
{
if (isContinuing || isStarting)
{
buf = TryTakeSnapshotStorage() as byte[];
Debug.Assert(buf == null || buf.Length == length, "stored buffer length must be null or must have been created with the correct length");
}
buf = TryTakeSnapshotStorage() as byte[];
Debug.Assert(buf != null || !isContinuing, "if continuing stored buffer must be present to contain previous data to continue from");
Debug.Assert(buf == null || buf.Length == length, "stored buffer length must be null or must have been created with the correct length");
if (buf != null)
{
startOffset = GetSnapshotTotalSize();
@ -2005,7 +2003,7 @@ namespace Microsoft.Data.SqlClient
{
if (result == TdsOperationStatus.NeedMoreData)
{
if (isStarting || isContinuing)
if (canContinue)
{
SetSnapshotStorage(buf);
}

191
src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderTest.cs
File diff suppressed because it is too large
View File

Loading…
Cancel
Save