Merge pull request #621 from v-kaywon/AEStreamError

add error handling for fetching stream with always encrypted
This commit is contained in:
Yuki Wong 2017-12-08 17:35:29 -08:00 committed by GitHub
commit 54ca7ffed6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 378 additions and 286 deletions

View file

@ -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, {} }
};

View file

@ -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,

View file

@ -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;

View file

@ -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, {} }

View file

@ -0,0 +1,80 @@
--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";
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 {
$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;
}
}
}
if ($success) {
echo "Done.\n";
} else {
fatalError("Failed to fetch stream ");
}
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.