-
Notifications
You must be signed in to change notification settings - Fork 323
Open
Description
Describe the bug
Suppose you are using IEnumerable<SqlDataRecord> 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
#!/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:
Two Words
One
ThreeFurther 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
Reactions are currently unavailable