From e5a3767089a1d997a0ea292de531ad5ff072089f Mon Sep 17 00:00:00 2001 From: Jenny Tam Date: Fri, 3 Nov 2017 10:00:08 -0700 Subject: [PATCH 1/3] Added error handling for LOB types as output parameters --- source/pdo_sqlsrv/pdo_util.cpp | 4 + source/shared/core_sqlsrv.h | 1 + source/shared/core_stmt.cpp | 6 + source/sqlsrv/util.cpp | 5 + .../srv_231_string_truncation_text.phpt | 133 ++++++++++++++++++ 5 files changed, 149 insertions(+) create mode 100644 test/functional/sqlsrv/srv_231_string_truncation_text.phpt diff --git a/source/pdo_sqlsrv/pdo_util.cpp b/source/pdo_sqlsrv/pdo_util.cpp index 1021fd291..6db8a3638 100644 --- a/source/pdo_sqlsrv/pdo_util.cpp +++ b/source/pdo_sqlsrv/pdo_util.cpp @@ -417,6 +417,10 @@ pdo_error PDO_ERRORS[] = { PDO_SQLSRV_ERROR_CE_EMULATE_PREPARE_UNSUPPORTED, { IMSSP, (SQLCHAR*) "Parameterized statement with attribute PDO::ATTR_EMULATE_PREPARES is not supported in a Column Encryption enabled Connection.", -82, false } }, + { + SQLSRV_ERROR_OUTPUT_PARAM_TYPES_NOT_SUPPORTED, + { IMSSP, (SQLCHAR*) "Stored Procedures do not support text, ntext or image as OUTPUT parameters.", -83, false } + }, { UINT_MAX, {} } }; diff --git a/source/shared/core_sqlsrv.h b/source/shared/core_sqlsrv.h index 16ca57110..bad4b5384 100644 --- a/source/shared/core_sqlsrv.h +++ b/source/shared/core_sqlsrv.h @@ -1689,6 +1689,7 @@ enum SQLSRV_ERROR_CODES { SQLSRV_ERROR_KEYSTORE_PATH_MISSING, SQLSRV_ERROR_KEYSTORE_KEY_MISSING, SQLSRV_ERROR_KEYSTORE_INVALID_VALUE, + SQLSRV_ERROR_OUTPUT_PARAM_TYPES_NOT_SUPPORTED, // Driver specific error codes starts from here. SQLSRV_ERROR_DRIVER_SPECIFIC = 1000, diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index 7dafef7da..1dc1dff32 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -422,6 +422,12 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ // if it's an output parameter and the user asks for a certain type, we have to convert the zval to that type so // when the buffer is filled, the type is correct + CHECK_CUSTOM_ERROR( direction != SQL_PARAM_INPUT && (sql_type == SQL_LONGVARCHAR + || sql_type == SQL_WLONGVARCHAR || sql_type == SQL_LONGVARBINARY), + stmt, SQLSRV_ERROR_OUTPUT_PARAM_TYPES_NOT_SUPPORTED ){ + throw core::CoreException(); + } + if( direction == SQL_PARAM_OUTPUT ){ switch( php_out_type ) { case SQLSRV_PHPTYPE_INT: diff --git a/source/sqlsrv/util.cpp b/source/sqlsrv/util.cpp index b8dd765db..264139ea1 100644 --- a/source/sqlsrv/util.cpp +++ b/source/sqlsrv/util.cpp @@ -408,6 +408,11 @@ ss_error SS_ERRORS[] = { SQLSRV_ERROR_SPECIFIED_DRIVER_NOT_FOUND, { IMSSP, (SQLCHAR*) "The specified ODBC Driver is not found.", -107, false } }, + { + SQLSRV_ERROR_OUTPUT_PARAM_TYPES_NOT_SUPPORTED, + { IMSSP, (SQLCHAR*) "Stored Procedures do not support text, ntext or image as OUTPUT parameters.", -108, false } + }, + // terminate the list of errors/warnings { UINT_MAX, {} } }; diff --git a/test/functional/sqlsrv/srv_231_string_truncation_text.phpt b/test/functional/sqlsrv/srv_231_string_truncation_text.phpt new file mode 100644 index 000000000..51c5e84b6 --- /dev/null +++ b/test/functional/sqlsrv/srv_231_string_truncation_text.phpt @@ -0,0 +1,133 @@ +--TEST-- +GitHub issue #231 - String truncation when binding text/ntext/image to check error messages +--ENV-- +PHPT_EXEC=true +--SKIPIF-- + +--FILE-- + + +--EXPECT-- + +Data Type: text binding as +Output parameter: Stored Procedures do not support text, ntext or image as OUTPUT parameters. +InOut parameter: Stored Procedures do not support text, ntext or image as OUTPUT parameters. + +Data Type: ntext binding as +Output parameter: Stored Procedures do not support text, ntext or image as OUTPUT parameters. +InOut parameter: Stored Procedures do not support text, ntext or image as OUTPUT parameters. + +Data Type: image binding as +Output parameter: Stored Procedures do not support text, ntext or image as OUTPUT parameters. +InOut parameter: Stored Procedures do not support text, ntext or image as OUTPUT parameters. From b44a5dd1fbfbbcf5a60085f96d49039a64f78db9 Mon Sep 17 00:00:00 2001 From: Jenny Tam Date: Fri, 3 Nov 2017 11:14:55 -0700 Subject: [PATCH 2/3] Modified comments as per review feedback --- source/shared/core_stmt.cpp | 9 +++++---- .../sqlsrv/srv_231_string_truncation_text.phpt | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index 1dc1dff32..a871e01a5 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -420,10 +420,11 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ } } - // if it's an output parameter and the user asks for a certain type, we have to convert the zval to that type so - // when the buffer is filled, the type is correct - CHECK_CUSTOM_ERROR( direction != SQL_PARAM_INPUT && (sql_type == SQL_LONGVARCHAR - || sql_type == SQL_WLONGVARCHAR || sql_type == SQL_LONGVARBINARY), + // If the user specifies a certain type for an output parameter, we have to convert the zval + // to that type so that when the buffer is filled, the type is correct. But first, + // should check that if a LOB type is specified. + CHECK_CUSTOM_ERROR( direction != SQL_PARAM_INPUT && ( sql_type == SQL_LONGVARCHAR + || sql_type == SQL_WLONGVARCHAR || sql_type == SQL_LONGVARBINARY ), stmt, SQLSRV_ERROR_OUTPUT_PARAM_TYPES_NOT_SUPPORTED ){ throw core::CoreException(); } diff --git a/test/functional/sqlsrv/srv_231_string_truncation_text.phpt b/test/functional/sqlsrv/srv_231_string_truncation_text.phpt index 51c5e84b6..2e2107c2a 100644 --- a/test/functional/sqlsrv/srv_231_string_truncation_text.phpt +++ b/test/functional/sqlsrv/srv_231_string_truncation_text.phpt @@ -76,7 +76,8 @@ function invokeProc($conn, $procName, $k, $direction, $data) $initData = "ShortString"; $callResult = $initData; - // Make sure not to specify the PHP type + // No need to specify the SQLSRV PHP type but must specify SQLSRV SQL Type + // when AE is enabled $intType = AE\isColEncrypted()? SQLSRV_SQLTYPE_INT : null; $params = array( array( $k, SQLSRV_PARAM_IN, null, $intType ), array( &$callResult, $direction, null, $sqlsrvSQLType )); From ef144000c3caebde9f15338d051a4dbf164cc575 Mon Sep 17 00:00:00 2001 From: Jenny Tam Date: Fri, 3 Nov 2017 12:17:43 -0700 Subject: [PATCH 3/3] Fixed the typo in the comment --- source/shared/core_stmt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index a871e01a5..bf268d8bd 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -422,7 +422,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ // If the user specifies a certain type for an output parameter, we have to convert the zval // to that type so that when the buffer is filled, the type is correct. But first, - // should check that if a LOB type is specified. + // should check if a LOB type is specified. CHECK_CUSTOM_ERROR( direction != SQL_PARAM_INPUT && ( sql_type == SQL_LONGVARCHAR || sql_type == SQL_WLONGVARCHAR || sql_type == SQL_LONGVARBINARY ), stmt, SQLSRV_ERROR_OUTPUT_PARAM_TYPES_NOT_SUPPORTED ){