From 631f80a9af9293ac4f3dad44d00f090707518976 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Thu, 26 Oct 2017 13:58:38 -0700 Subject: [PATCH] added error handling for using direct_query and emulate_prepare in a Column Encryption enabled connection --- source/pdo_sqlsrv/pdo_stmt.cpp | 16 ++++- source/pdo_sqlsrv/pdo_util.cpp | 8 +++ source/pdo_sqlsrv/php_pdo_sqlsrv.h | 4 +- .../pdo_ae_unsupported_stmt_attr.phpt | 66 +++++++++++++++++++ 4 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 test/functional/pdo_sqlsrv/pdo_ae_unsupported_stmt_attr.phpt diff --git a/source/pdo_sqlsrv/pdo_stmt.cpp b/source/pdo_sqlsrv/pdo_stmt.cpp index d77a9623..6db17d29 100644 --- a/source/pdo_sqlsrv/pdo_stmt.cpp +++ b/source/pdo_sqlsrv/pdo_stmt.cpp @@ -1146,9 +1146,19 @@ int pdo_sqlsrv_stmt_param_hook( _Inout_ pdo_stmt_t *stmt, // since the param isn't reliable, we don't do anything here case PDO_PARAM_EVT_ALLOC: - if ( stmt->supports_placeholders == PDO_PLACEHOLDER_NONE && (param->param_type & PDO_PARAM_INPUT_OUTPUT )) { - sqlsrv_stmt* driver_stmt = reinterpret_cast( stmt->driver_data ); - THROW_PDO_ERROR( driver_stmt, PDO_SQLSRV_ERROR_EMULATE_INOUT_UNSUPPORTED ); + { + pdo_sqlsrv_stmt* driver_stmt = reinterpret_cast(stmt->driver_data); + if (driver_stmt->conn->ce_option.enabled) { + if (driver_stmt->direct_query) { + THROW_PDO_ERROR(driver_stmt, PDO_SQLSRV_ERROR_CE_DIRECT_QUERY_UNSUPPORTED); + } + if (stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) { + THROW_PDO_ERROR(driver_stmt, PDO_SQLSRV_ERROR_CE_EMULATE_PREPARE_UNSUPPORTED); + } + } + if (stmt->supports_placeholders == PDO_PLACEHOLDER_NONE && (param->param_type & PDO_PARAM_INPUT_OUTPUT)) { + THROW_PDO_ERROR(driver_stmt, PDO_SQLSRV_ERROR_EMULATE_INOUT_UNSUPPORTED); + } } break; case PDO_PARAM_EVT_FREE: diff --git a/source/pdo_sqlsrv/pdo_util.cpp b/source/pdo_sqlsrv/pdo_util.cpp index 310b66a4..faf89552 100644 --- a/source/pdo_sqlsrv/pdo_util.cpp +++ b/source/pdo_sqlsrv/pdo_util.cpp @@ -409,6 +409,14 @@ pdo_error PDO_ERRORS[] = { SQLSRV_ERROR_SPECIFIED_DRIVER_NOT_FOUND, { IMSSP, (SQLCHAR*) "The specified ODBC Driver is not found.", -80, false } }, + { + PDO_SQLSRV_ERROR_CE_DIRECT_QUERY_UNSUPPORTED, + { IMSSP, (SQLCHAR*) "Connection with Column Encryption enabled do no support PDO::SQLSRV_ATTR_DIRECT_QUERY with binding parameters.", -81, false } + }, + { + PDO_SQLSRV_ERROR_CE_EMULATE_PREPARE_UNSUPPORTED, + { IMSSP, (SQLCHAR*) "Connection with Column Encryption enabled do no support PDO::ATTR_EMULATE_PREPARES with binding parameters.", -82, false } + }, { UINT_MAX, {} } }; diff --git a/source/pdo_sqlsrv/php_pdo_sqlsrv.h b/source/pdo_sqlsrv/php_pdo_sqlsrv.h index da9024e9..e61134d7 100644 --- a/source/pdo_sqlsrv/php_pdo_sqlsrv.h +++ b/source/pdo_sqlsrv/php_pdo_sqlsrv.h @@ -393,7 +393,9 @@ enum PDO_ERROR_CODES { PDO_SQLSRV_ERROR_INVALID_OUTPUT_PARAM_TYPE, PDO_SQLSRV_ERROR_INVALID_CURSOR_WITH_SCROLL_TYPE, PDO_SQLSRV_ERROR_EMULATE_INOUT_UNSUPPORTED, - PDO_SQLSRV_ERROR_INVALID_AUTHENTICATION_OPTION + PDO_SQLSRV_ERROR_INVALID_AUTHENTICATION_OPTION, + PDO_SQLSRV_ERROR_CE_DIRECT_QUERY_UNSUPPORTED, + PDO_SQLSRV_ERROR_CE_EMULATE_PREPARE_UNSUPPORTED }; extern pdo_error PDO_ERRORS[]; diff --git a/test/functional/pdo_sqlsrv/pdo_ae_unsupported_stmt_attr.phpt b/test/functional/pdo_sqlsrv/pdo_ae_unsupported_stmt_attr.phpt new file mode 100644 index 00000000..9a2cbfcb --- /dev/null +++ b/test/functional/pdo_sqlsrv/pdo_ae_unsupported_stmt_attr.phpt @@ -0,0 +1,66 @@ +--TEST-- +Test emulate prepare utf8 encoding set at the statement level +--SKIPIF-- + +--FILE-- + "nvarchar(max)")); +} catch (PDOException $e) { + var_dump($e->errorInfo); +} + +try { + $name = "Edward"; + $st = $connection->prepare("INSERT INTO $tbname (name) VALUES (:p0)", array(PDO::SQLSRV_ATTR_DIRECT_QUERY => true)); + $st->execute(array("p0" => $name)); +} catch (PDOException $e) { + $error = $e->errorInfo; + // expects an exception if Column Encryption is enabled + if (isColEncrypted()) { + if ($error[0] != "IMSSP" || + $error[1] != -81 || + $error[2] != "Connection with Column Encryption enabled do no support PDO::SQLSRV_ATTR_DIRECT_QUERY with binding parameters.") { + echo "An unexpected exception was caught.\n"; + var_dump($error); + } + } else { + var_dump($error); + } +} + +try { + $name = "Alphonse"; + $st = $connection->prepare("INSERT INTO $tbname (name) VALUES (:p0)", array(PDO::ATTR_EMULATE_PREPARES => true)); + $st->execute(array("p0" => $name)); +} catch (PDOException $e) { + $error = $e->errorInfo; + // expects an exception if Column Encryption is enabled + if (isColEncrypted()) { + if ($error[0] != "IMSSP" || + $error[1] != -82 || + $error[2] != "Connection with Column Encryption enabled do no support PDO::ATTR_EMULATE_PREPARES with binding parameters.") { + echo "An unexpected exception was caught.\n"; + var_dump($error); + } + } else { + var_dump($error); + } +} + +try { + dropTable($connection, $tbname); + unset($st); + unset($connection); +} catch (PDOException $e) { + var_dump($e->errorInfo); +} + +echo "Done\n"; +?> +--EXPECT-- +Done