Skip to content

sqlsrv_next_result() returns incorrect result with varchar(max) field when Always Encrypted is enabled #574

@yitam

Description

@yitam

To reproduce this, connect with Always Encrypted enabled, create a table with only one varchar(max) column and then fetch the result by running two selects in a row. This is an example (the problem is gone when the column type is varchar(1024)):

$tableName = 'TextTable';
$sql = "create table $tableName (col1 varchar(max) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = deterministic, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = AEColumnKey) )";

$stmt = sqlsrv_query($conn, $sql);

$sql = "insert into $tableName (col1) VALUES (?)";
$params = array("This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test This is a test ");

$stmt = sqlsrv_prepare($conn, $sql, $params);
if ($stmt) {
    $r = sqlsrv_execute($stmt);
    if (!$r) {
        print_r(sqlsrv_errors());
    }
}

$stmt = sqlsrv_prepare($conn, "SELECT * FROM [$tableName]; SELECT * FROM [$tableName]");
if ($stmt) {
    $r = sqlsrv_execute($stmt);
    if (!$r) {
        print_r(sqlsrv_errors());
    }
}

echo "1. next result? ";
$next = sqlsrv_next_result($stmt);
var_dump($next);

$row = sqlsrv_fetch($stmt);
if ($row) {
    $fld = sqlsrv_get_field($stmt, 0, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR));
    echo(substr($fld, 0, 15)) . PHP_EOL;
}

echo "2. next result? ";
$next = sqlsrv_next_result($stmt);
var_dump($next);

echo "3. next result? ";
$next = sqlsrv_next_result($stmt);
var_dump($next);

The expected output is

1. next result? bool(true)
This is a test
2. next result? NULL
3. next result? bool(false)

The actual output is

1. next result? bool(true)
This is a test
2. next result? bool(true)
3. next result? NULL

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions