add error handling for fetching stream with always encrypted

This commit is contained in:
v-kaywon 2017-12-07 17:29:06 -08:00
Родитель 05f9a54442
Коммит b9579a2426
5 изменённых файлов: 98 добавлений и 0 удалений

Просмотреть файл

@ -421,6 +421,10 @@ pdo_error PDO_ERRORS[] = {
SQLSRV_ERROR_OUTPUT_PARAM_TYPES_NOT_SUPPORTED,
{ IMSSP, (SQLCHAR*) "Stored Procedures do not support text, ntext or image as OUTPUT parameters.", -83, false }
},
{
SQLSRV_ERROR_ENCRYPTED_STREAM_FETCH,
{ IMSSP, (SQLCHAR*) "Connection with Column Encryption enabled does not support fetching stream. Please fetch the data as a string.", -84, false }
},
{ UINT_MAX, {} }
};

Просмотреть файл

@ -1716,6 +1716,7 @@ enum SQLSRV_ERROR_CODES {
SQLSRV_ERROR_KEYSTORE_KEY_MISSING,
SQLSRV_ERROR_KEYSTORE_INVALID_VALUE,
SQLSRV_ERROR_OUTPUT_PARAM_TYPES_NOT_SUPPORTED,
SQLSRV_ERROR_ENCRYPTED_STREAM_FETCH,
// Driver specific error codes starts from here.
SQLSRV_ERROR_DRIVER_SPECIFIC = 1000,

Просмотреть файл

@ -1711,6 +1711,9 @@ void core_get_field_common( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_i
// for how these fields are used.
case SQLSRV_PHPTYPE_STREAM:
{
CHECK_CUSTOM_ERROR(stmt->conn->ce_option.enabled, stmt, SQLSRV_ERROR_ENCRYPTED_STREAM_FETCH) {
throw core::CoreException();
}
php_stream* stream = NULL;
sqlsrv_stream* ss = NULL;

Просмотреть файл

@ -412,6 +412,10 @@ ss_error SS_ERRORS[] = {
SQLSRV_ERROR_OUTPUT_PARAM_TYPES_NOT_SUPPORTED,
{ IMSSP, (SQLCHAR*) "Stored Procedures do not support text, ntext or image as OUTPUT parameters.", -108, false }
},
{
SQLSRV_ERROR_ENCRYPTED_STREAM_FETCH,
{ IMSSP, (SQLCHAR*) "Connection with Column Encryption enabled does not support fetching stream. Please fetch the data as a string.", -109, false }
},
// terminate the list of errors/warnings
{ UINT_MAX, {} }

Просмотреть файл

@ -0,0 +1,86 @@
--TEST--
Streaming Field Test
--DESCRIPTION--
Verifies the streaming behavior and proper error handling with Always Encrypted
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
--FILE--
<?php
require_once('MsCommon.inc');
$conn = AE\connect();
$tableName = "test_max_fields";
dropTable($conn, $tableName);
AE\createTable($conn, $tableName, array(new AE\ColumnMeta("varchar(max)", "varchar_max_col")));
$inValue = str_repeat("ÃÜðßZZýA©", 600);
$insertSql = "INSERT INTO $tableName (varchar_max_col) VALUES (?)";
$params = array($inValue);
$stmt = sqlsrv_prepare($conn, $insertSql, $params);
if ($stmt) {
sqlsrv_execute($stmt);
}
$query = "SELECT * FROM $tableName";
$stmt = sqlsrv_prepare($conn, $query);
if ($stmt) {
sqlsrv_execute($stmt);
}
if (!sqlsrv_fetch($stmt)) {
fatalError("Failed to fetch row ");
}
$stream = sqlsrv_get_field($stmt, 0, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_CHAR));
$success = false;
if ($stream === false) {
$error = sqlsrv_errors()[0];
if (AE\isColEncrypted() && $error['SQLSTATE'] === "IMSSP" && $error['code'] === -109 &&
$error['message'] === "Connection with Column Encryption enabled does not support fetching stream. Please fetch the data as a string.") {
$success = true;
} else {
var_dump($error);
fatalError("Failed to read field");
}
} else {
$value = '';
if (!AE\isColEncrypted()) {
$num = 0;
while (!feof($stream)) {
$value .= fread($stream, 8192);
}
fclose($stream);
if (checkData($value, $inValue)) { // compare the data to see if they match!
$success = true;
} else {
fatalError("Data corruption!\n");
}
} else {
fatalError("Error in getting stream!");
}
}
if ($success) {
echo "Done.\n";
}
function checkData($actual, $expected)
{
$success = true;
$pos = strpos($actual, $expected);
if (($pos === false) || ($pos > 1)) {
$success = false;
}
if (!$success) {
trace("\nData error\nExpected:\n$expected\nActual:\n$actual\n");
}
return ($success);
}
?>
--EXPECT--
Done.