SqlDataRecord.SetBytes fails to set length, incorrectly preserving data from a previous call
- Dominant language
- C#
- Stars
- 989
- Forks
- 340
- Avg merge
- 4d 19h
- Merged PRs (30d)
- 72
Description
### Describe the bug
Suppose you are using `IEnumerable` as the value of a table-valued `SqlParameter` and re-using the same `SqlDataRecord` instance for each item. One of the fields is type `VARBINARY(MAX)`, and you use the `SetBytes` method to copy data into the field. After the first call to `SetBytes`, a subsequent call that copies _fewer_ bytes will write to the existing buffer without setting the field's length, causing the remaining stale buffered bytes from the first call to get copied to the server, too.
### To reproduce
```c#
#!/usr/bin/env dotnet run
#:package Microsoft.Data.SqlClient@6.*
using Microsoft.Data.SqlClient.Server;
using System.Data;
using System.Data.SqlTypes;
using System.Text;
var columns = new SqlMetaData[]
{
new("Data", SqlDbType.VarBinary, SqlMetaData.Max),
};
var rec = new SqlDataRecord(columns);
var buffer = new byte[4096];
// write first record value
SetBytes(rec, 0, buffer, "Two Words");
ReadBytesToConsole(rec, 0, buffer); // writes "Two Words"
// write second record value
SetBytes(rec, 0, buffer, "One");
ReadBytesToConsole(rec, 0, buffer); // writes "One Words"
// write third record value using SqlBytes, which avoids the bug
var sqlBytes = new SqlBytes(Encoding.UTF8.GetBytes("Three"));
rec.SetSqlBytes(0, sqlBytes);
ReadBytesToConsole(rec, 0, buffer); // writes "Three"
static void SetBytes(SqlDataRecord rec, int ordinal, byte[] buffer, string value)
{
int length = Encoding.UTF8.GetBytes(value, buffer);
rec.SetBytes(ordinal, 0, buffer, 0, length);
}
static void ReadBytesToConsole(SqlDataRecord rec, int ordinal, byte[] buffer)
{
var length = rec.GetBytes(ordinal, 0, buffer, 0, buffer.Length);
var s = Encoding.UTF8.GetString(buffer, 0, int.CreateChecked(length));
Console.WriteLine(s);
}
```
### Expected behavior
The program should output:
```txt
Two Words
One
Three
```
### Further technical details
Microsoft.Data.SqlClient version: 6.1.4
.NET target: .NET 10.0
SQL Server version: N/A
Operating system: Windows 11 Pro 26200.7840
Contributor guide
Assessment
This issue has not been assessed yet.