Inconsistent handling of empty BLOB slices as parameters
- Dominant language
- C#
- Stars
- 989
- Forks
- 340
- Avg merge
- 4d 19h
- Merged PRs (30d)
- 72
Description
using the `Offset` and `Size` to control slicing of `byte[]` parameters gives inconsistent results and throws exceptions in some cases:
``` c#
using Microsoft.Data.SqlClient;
using System;
using System.Data;
var cs = new SqlConnectionStringBuilder
{
TrustServerCertificate = true,
IntegratedSecurity = true,
InitialCatalog = "master",
DataSource = "."
};
using var conn = new SqlConnection(cs.ConnectionString);
conn.Open();
// entire array
Console.WriteLine(Test(conn, 10, 0, 10)); // 10 - fine
// slice of array
Console.WriteLine(Test(conn, 10, 1, 8)); // 8 - fine
// small slice of array
Console.WriteLine(Test(conn, 10, 1, 1)); // 1 - fine
// empty array
Console.WriteLine(Test(conn, 0, 0, 0)); // 8000 - wat?
// empty slice of non-empty array
Console.WriteLine(Test(conn, 10, 0, 0)); // 10 - um, nope
// empty slice of non-empty array, non-zero offset
Console.WriteLine(Test(conn, 10, 1, 0)); // fault from TdsParserStateObject.WriteByteArray
static int Test(SqlConnection connection, int arraySize, int offset, int count)
{
var arr = new byte[arraySize];
using var cmd = connection.CreateCommand();
cmd.CommandText = "select datalength(@x)";
var p = new SqlParameter("@x", SqlDbType.Binary, size: count);
p.Offset = offset;
p.Value = arr;
// have tried setting size after value; no change
// p.Size = count;
cmd.Parameters.Add(p);
return (int)cmd.ExecuteScalar();
}
```
I'm guessing this is "implicit vs explicit zero", with it treating zero as "just send everything"; *at a minimum*, IMO, this should mean `value.Length - Offset` (i.e. "the rest of the buffer"), not `value.Length`. At the moment I'm working around this by detecting zero-length buffers and swapping out for `byte[0]` so that it can't get confused, but that leaves me a little worried about that `8000`
Contributor guide
Assessment
This issue has not been assessed yet.