Skip to content

Inconsistent handling of empty BLOB slices as parameters #2465

@mgravell

Description

@mgravell

using the Offset and Size to control slicing of byte[] parameters gives inconsistent results and throws exceptions in some cases:

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Repro Available ✔️Issues that are reproducible with repro provided.

    Type

    No fields configured for Bug.

    Projects

    Status

    To triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions