From bde81001e9f67e01a17f999be91823007b774513 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Thu, 22 Jun 2017 14:04:34 -0700 Subject: [PATCH] added SAL annotations and fixed warnings --- source/pdo_sqlsrv/pdo_dbh.cpp | 106 +++--- source/pdo_sqlsrv/pdo_init.cpp | 10 +- source/pdo_sqlsrv/pdo_parser.cpp | 16 +- source/pdo_sqlsrv/pdo_stmt.cpp | 109 ++++--- source/pdo_sqlsrv/pdo_util.cpp | 24 +- source/pdo_sqlsrv/php_pdo_sqlsrv.h | 56 ++-- source/shared/core_conn.cpp | 72 ++--- source/shared/core_init.cpp | 6 +- source/shared/core_results.cpp | 142 ++++----- source/shared/core_sqlsrv.h | 496 ++++++++++++++--------------- source/shared/core_stmt.cpp | 164 +++++----- source/shared/core_stream.cpp | 12 +- source/shared/core_util.cpp | 40 +-- source/sqlsrv/conn.cpp | 83 ++--- source/sqlsrv/init.cpp | 8 +- source/sqlsrv/php_sqlsrv.h | 44 +-- source/sqlsrv/stmt.cpp | 106 +++--- source/sqlsrv/util.cpp | 33 +- 18 files changed, 778 insertions(+), 749 deletions(-) diff --git a/source/pdo_sqlsrv/pdo_dbh.cpp b/source/pdo_sqlsrv/pdo_dbh.cpp index b0ce8712..8d058907 100644 --- a/source/pdo_sqlsrv/pdo_dbh.cpp +++ b/source/pdo_sqlsrv/pdo_dbh.cpp @@ -96,18 +96,18 @@ const stmt_option PDO_STMT_OPTS[] = { // boolean connection string struct pdo_bool_conn_str_func { - static void func( connection_option const* option, zval* value, sqlsrv_conn* /*conn*/, std::string& conn_str TSRMLS_DC ); + static void func( _In_ connection_option const* option, _Inout_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str TSRMLS_DC ); }; struct pdo_txn_isolation_conn_attr_func { - static void func( connection_option const* /*option*/, zval* value_z, sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ); + static void func( connection_option const* /*option*/, _In_ zval* value_z, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ); }; #ifdef _WIN32 struct pdo_int_conn_str_func { - static void func( connection_option const* option, zval* value, sqlsrv_conn* /*conn*/, std::string& conn_str TSRMLS_DC ) + static void func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str TSRMLS_DC ) { TSRMLS_C; SQLSRV_ASSERT( Z_TYPE_P( value ) == IS_STRING, "Wrong zval type for this keyword" ) @@ -125,7 +125,7 @@ struct pdo_int_conn_str_func { template struct pdo_int_conn_attr_func { - static void func( connection_option const* /*option*/, zval* value, sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) + static void func( connection_option const* /*option*/, _In_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) { try { @@ -143,7 +143,7 @@ struct pdo_int_conn_attr_func { template struct pdo_bool_conn_attr_func { - static void func( connection_option const* /*option*/, zval* value, sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) + static void func( connection_option const* /*option*/, _Inout_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) { try { @@ -157,9 +157,9 @@ struct pdo_bool_conn_attr_func { }; // statement options related functions -void add_stmt_option_key( sqlsrv_context& ctx, size_t key, HashTable* options_ht, - zval** data TSRMLS_DC ); -void validate_stmt_options( sqlsrv_context& ctx, zval* stmt_options, _Inout_ HashTable* pdo_stmt_options_ht TSRMLS_DC ); +void add_stmt_option_key( _Inout_ sqlsrv_context& ctx, _In_ size_t key, _Inout_ HashTable* options_ht, + _Inout_ zval** data TSRMLS_DC ); +void validate_stmt_options( _Inout_ sqlsrv_context& ctx, _In_ zval* stmt_options, _Inout_ HashTable* pdo_stmt_options_ht TSRMLS_DC ); } // namespace @@ -362,34 +362,34 @@ const connection_option PDO_CONN_OPTS[] = { // close the connection -int pdo_sqlsrv_dbh_close( pdo_dbh_t *dbh TSRMLS_DC ); +int pdo_sqlsrv_dbh_close( _Inout_ pdo_dbh_t *dbh TSRMLS_DC ); // execute queries -int pdo_sqlsrv_dbh_prepare( pdo_dbh_t *dbh, const char *sql, - size_t sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC ); -zend_long pdo_sqlsrv_dbh_do( pdo_dbh_t *dbh, const char *sql, size_t sql_len TSRMLS_DC ); +int pdo_sqlsrv_dbh_prepare( _Inout_ pdo_dbh_t *dbh, _In_reads_(sql_len) const char *sql, + _Inout_ size_t sql_len, _Inout_ pdo_stmt_t *stmt, _In_ zval *driver_options TSRMLS_DC ); +zend_long pdo_sqlsrv_dbh_do( _Inout_ pdo_dbh_t *dbh, _In_reads_bytes_(sql_len) const char *sql, _In_ size_t sql_len TSRMLS_DC ); // transaction support functions -int pdo_sqlsrv_dbh_commit( pdo_dbh_t *dbh TSRMLS_DC ); -int pdo_sqlsrv_dbh_begin( pdo_dbh_t *dbh TSRMLS_DC ); -int pdo_sqlsrv_dbh_rollback( pdo_dbh_t *dbh TSRMLS_DC ); +int pdo_sqlsrv_dbh_commit( _In_ pdo_dbh_t *dbh TSRMLS_DC ); +int pdo_sqlsrv_dbh_begin( _In_ pdo_dbh_t *dbh TSRMLS_DC ); +int pdo_sqlsrv_dbh_rollback( _In_ pdo_dbh_t *dbh TSRMLS_DC ); // attribute functions -int pdo_sqlsrv_dbh_set_attr( pdo_dbh_t *dbh, zend_long attr, zval *val TSRMLS_DC ); -int pdo_sqlsrv_dbh_get_attr( pdo_dbh_t *dbh, zend_long attr, zval *return_value TSRMLS_DC ); +int pdo_sqlsrv_dbh_set_attr( _In_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout_ zval *val TSRMLS_DC ); +int pdo_sqlsrv_dbh_get_attr( _In_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout_ zval *return_value TSRMLS_DC ); // return more information -int pdo_sqlsrv_dbh_return_error( pdo_dbh_t *dbh, pdo_stmt_t *stmt, - zval *info TSRMLS_DC); +int pdo_sqlsrv_dbh_return_error( _In_ pdo_dbh_t *dbh, _In_opt_ pdo_stmt_t *stmt, + _Out_ zval *info TSRMLS_DC); // return the last id generated by an executed SQL statement -char * pdo_sqlsrv_dbh_last_id( pdo_dbh_t *dbh, const char *name, size_t* len TSRMLS_DC ); +char * pdo_sqlsrv_dbh_last_id( _Inout_ pdo_dbh_t *dbh, _In_z_ const char *name, _Out_ size_t* len TSRMLS_DC ); // additional methods are supported in this function -pdo_sqlsrv_function_entry *pdo_sqlsrv_get_driver_methods( pdo_dbh_t *dbh, int kind TSRMLS_DC ); +pdo_sqlsrv_function_entry *pdo_sqlsrv_get_driver_methods( _In_ pdo_dbh_t *dbh, int kind TSRMLS_DC ); // quote a string, meaning put quotes around it and escape any quotes within it -int pdo_sqlsrv_dbh_quote( pdo_dbh_t* dbh, const char* unquoted, size_t unquotedlen, char **quoted, size_t* quotedlen, +int pdo_sqlsrv_dbh_quote( pdo_dbh_t* dbh, _In_reads_(unquotedlen) const char* unquoted, _In_ size_t unquotedlen, _Outptr_result_buffer_(*quotedlen) char **quoted, _Out_ size_t* quotedlen, enum pdo_param_type paramtype TSRMLS_DC ); struct pdo_dbh_methods pdo_sqlsrv_dbh_methods = { @@ -434,7 +434,7 @@ struct pdo_dbh_methods pdo_sqlsrv_dbh_methods = { #endif // constructor for the internal object for connections -pdo_sqlsrv_dbh::pdo_sqlsrv_dbh( SQLHANDLE h, error_callback e, void* driver TSRMLS_DC ) : +pdo_sqlsrv_dbh::pdo_sqlsrv_dbh( _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* driver TSRMLS_DC ) : sqlsrv_conn( h, e, driver, SQLSRV_ENCODING_UTF8 TSRMLS_CC ), stmts( NULL ), direct_query( false ), @@ -464,7 +464,7 @@ pdo_sqlsrv_dbh::pdo_sqlsrv_dbh( SQLHANDLE h, error_callback e, void* driver TSRM // driver_options - A HashTable (within the zval) of options to use when creating the connection. // Return: // 0 for failure, 1 for success. -int pdo_sqlsrv_db_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) +int pdo_sqlsrv_db_handle_factory( _Inout_ pdo_dbh_t *dbh, _In_opt_ zval *driver_options TSRMLS_DC) { LOG( SEV_NOTICE, "pdo_sqlsrv_db_handle_factory: entering" ); @@ -566,7 +566,7 @@ int pdo_sqlsrv_db_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) // dbh - The PDO managed connection object. // Return: // Always returns 1 for success. -int pdo_sqlsrv_dbh_close( pdo_dbh_t *dbh TSRMLS_DC ) +int pdo_sqlsrv_dbh_close( _Inout_ pdo_dbh_t *dbh TSRMLS_DC ) { LOG( SEV_NOTICE, "pdo_sqlsrv_dbh_close: entering" ); @@ -597,8 +597,8 @@ int pdo_sqlsrv_dbh_close( pdo_dbh_t *dbh TSRMLS_DC ) // driver_options - User provided list of statement options. // Return: // 0 for failure, 1 for success. -int pdo_sqlsrv_dbh_prepare( pdo_dbh_t *dbh, const char *sql, - size_t sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC ) +int pdo_sqlsrv_dbh_prepare( _Inout_ pdo_dbh_t *dbh, _In_reads_(sql_len) const char *sql, + _Inout_ size_t sql_len, _Inout_ pdo_stmt_t *stmt, _In_ zval *driver_options TSRMLS_DC ) { PDO_RESET_DBH_ERROR; PDO_VALIDATE_CONN; @@ -735,7 +735,7 @@ int pdo_sqlsrv_dbh_prepare( pdo_dbh_t *dbh, const char *sql, // sql_len - length of sql query // Return // # of rows affected, -1 for an error. -zend_long pdo_sqlsrv_dbh_do( pdo_dbh_t *dbh, const char *sql, size_t sql_len TSRMLS_DC ) +zend_long pdo_sqlsrv_dbh_do( _Inout_ pdo_dbh_t *dbh, _In_reads_bytes_(sql_len) const char *sql, _In_ size_t sql_len TSRMLS_DC ) { PDO_RESET_DBH_ERROR; PDO_VALIDATE_CONN; @@ -753,6 +753,7 @@ zend_long pdo_sqlsrv_dbh_do( pdo_dbh_t *dbh, const char *sql, size_t sql_len TSR try { SQLSRV_ASSERT( sql != NULL, "NULL or empty SQL string passed." ); + SQLSRV_ASSERT( driver_dbh != NULL, "pdo_sqlsrv_dbh_do: driver_data object was NULL."); // temp PDO statement used for error handling if something happens pdo_stmt_t temp_stmt; @@ -823,7 +824,7 @@ zend_long pdo_sqlsrv_dbh_do( pdo_dbh_t *dbh, const char *sql, size_t sql_len TSR // dbh - The PDO managed connection object. // Return: // 0 for failure and 1 for success. -int pdo_sqlsrv_dbh_begin( pdo_dbh_t *dbh TSRMLS_DC ) +int pdo_sqlsrv_dbh_begin( _In_ pdo_dbh_t *dbh TSRMLS_DC ) { PDO_RESET_DBH_ERROR; PDO_VALIDATE_CONN; @@ -865,7 +866,7 @@ int pdo_sqlsrv_dbh_begin( pdo_dbh_t *dbh TSRMLS_DC ) // dbh - The PDO managed connection object. // Return: // 0 for failure and 1 for success. -int pdo_sqlsrv_dbh_commit( pdo_dbh_t *dbh TSRMLS_DC ) +int pdo_sqlsrv_dbh_commit( _In_ pdo_dbh_t *dbh TSRMLS_DC ) { PDO_RESET_DBH_ERROR; PDO_VALIDATE_CONN; @@ -905,7 +906,7 @@ int pdo_sqlsrv_dbh_commit( pdo_dbh_t *dbh TSRMLS_DC ) // dbh - The PDO managed connection object. // Return: // 0 for failure and 1 for success. -int pdo_sqlsrv_dbh_rollback( pdo_dbh_t *dbh TSRMLS_DC ) +int pdo_sqlsrv_dbh_rollback( _In_ pdo_dbh_t *dbh TSRMLS_DC ) { PDO_RESET_DBH_ERROR; PDO_VALIDATE_CONN; @@ -944,13 +945,14 @@ int pdo_sqlsrv_dbh_rollback( pdo_dbh_t *dbh TSRMLS_DC ) // val - The value of the attribute to be set. // Return: // 0 for failure, 1 for success. -int pdo_sqlsrv_dbh_set_attr( pdo_dbh_t *dbh, zend_long attr, zval *val TSRMLS_DC ) +int pdo_sqlsrv_dbh_set_attr( _In_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout_ zval *val TSRMLS_DC ) { PDO_RESET_DBH_ERROR; PDO_VALIDATE_CONN; PDO_LOG_DBH_ENTRY; pdo_sqlsrv_dbh* driver_dbh = static_cast( dbh->driver_data ); + SQLSRV_ASSERT( driver_dbh != NULL, "pdo_sqlsrv_dbh_set_attr: driver_data object was NULL."); try { @@ -1059,13 +1061,14 @@ int pdo_sqlsrv_dbh_set_attr( pdo_dbh_t *dbh, zend_long attr, zval *val TSRMLS_DC // return_value - zval in which to return the attribute value. // Return: // 0 for failure, 1 for success. -int pdo_sqlsrv_dbh_get_attr( pdo_dbh_t *dbh, zend_long attr, zval *return_value TSRMLS_DC ) +int pdo_sqlsrv_dbh_get_attr( _In_ pdo_dbh_t *dbh, _In_ zend_long attr, _Inout_ zval *return_value TSRMLS_DC ) { PDO_RESET_DBH_ERROR; PDO_VALIDATE_CONN; PDO_LOG_DBH_ENTRY; pdo_sqlsrv_dbh* driver_dbh = static_cast( dbh->driver_data ); + SQLSRV_ASSERT( driver_dbh != NULL, "pdo_sqlsrv_dbh_get_attr: driver_data object was NULL."); try { @@ -1176,8 +1179,8 @@ int pdo_sqlsrv_dbh_get_attr( pdo_dbh_t *dbh, zend_long attr, zval *return_value // info - zval in which to return the error info. // Return: // 0 for failure, 1 for success. -int pdo_sqlsrv_dbh_return_error( pdo_dbh_t *dbh, pdo_stmt_t *stmt, - zval *info TSRMLS_DC) +int pdo_sqlsrv_dbh_return_error( _In_ pdo_dbh_t *dbh, _In_opt_ pdo_stmt_t *stmt, + _Out_ zval *info TSRMLS_DC) { SQLSRV_ASSERT( dbh != NULL || stmt != NULL, "Either dbh or stmt must not be NULL to dereference the error." ); @@ -1203,7 +1206,7 @@ int pdo_sqlsrv_dbh_return_error( pdo_dbh_t *dbh, pdo_stmt_t *stmt, // len - Length of the name. // Return: // Returns the last insert id as a string. -char * pdo_sqlsrv_dbh_last_id( pdo_dbh_t *dbh, const char *name, _Out_ size_t* len TSRMLS_DC ) +char * pdo_sqlsrv_dbh_last_id( _Inout_ pdo_dbh_t *dbh, _In_z_ const char *name, _Out_ size_t* len TSRMLS_DC ) { PDO_RESET_DBH_ERROR; PDO_VALIDATE_CONN; @@ -1216,6 +1219,7 @@ char * pdo_sqlsrv_dbh_last_id( pdo_dbh_t *dbh, const char *name, _Out_ size_t* l sqlsrv_malloc_auto_ptr driver_stmt; pdo_sqlsrv_dbh* driver_dbh = static_cast( dbh->driver_data ); + SQLSRV_ASSERT( driver_dbh != NULL, "pdo_sqlsrv_dbh_last_id: driver_data object was NULL." ); sqlsrv_malloc_auto_ptr id_str; id_str = reinterpret_cast( sqlsrv_malloc( LAST_INSERT_ID_BUFF_LEN )); @@ -1302,7 +1306,7 @@ char * pdo_sqlsrv_dbh_last_id( pdo_dbh_t *dbh, const char *name, _Out_ size_t* l // quoted_len - Length of the output string. // Return: // 0 for failure, 1 for success. -int pdo_sqlsrv_dbh_quote( pdo_dbh_t* dbh, const char* unquoted, size_t unquoted_len, char **quoted, size_t* quoted_len, +int pdo_sqlsrv_dbh_quote( pdo_dbh_t* dbh, _In_reads_(unquoted_len) const char* unquoted, _In_ size_t unquoted_len, _Outptr_result_buffer_(*quoted_len) char **quoted, _Out_ size_t* quoted_len, enum pdo_param_type /*paramtype*/ TSRMLS_DC ) { PDO_RESET_DBH_ERROR; @@ -1319,15 +1323,16 @@ int pdo_sqlsrv_dbh_quote( pdo_dbh_t* dbh, const char* unquoted, size_t unquoted_ // iterate through parents to find "PDOStatement" bool is_statement = false; - zend_class_entry* curr_class = ( Z_OBJ_P( object ))->ce; - while ( curr_class != NULL ) { - if ( strcmp( reinterpret_cast( curr_class->name->val ), "PDOStatement" ) == 0 ) { - is_statement = true; - break; + if ( object ) { + zend_class_entry* curr_class = ( Z_OBJ_P( object ))->ce; + while ( curr_class != NULL ) { + if ( strcmp( reinterpret_cast( curr_class->name->val ), "PDOStatement" ) == 0 ) { + is_statement = true; + break; + } + curr_class = curr_class->parent; } - curr_class = curr_class->parent; } - // only change the encoding if quote is called from the statement level (which should only be called when a statement // is prepared with emulate prepared on) if ( is_statement ) { @@ -1435,13 +1440,14 @@ int pdo_sqlsrv_dbh_quote( pdo_dbh_t* dbh, const char* unquoted, size_t unquoted_ } // This method is not implemented by this driver. -pdo_sqlsrv_function_entry *pdo_sqlsrv_get_driver_methods( pdo_dbh_t *dbh, int kind TSRMLS_DC ) +pdo_sqlsrv_function_entry *pdo_sqlsrv_get_driver_methods( _In_ pdo_dbh_t *dbh, int kind TSRMLS_DC ) { PDO_RESET_DBH_ERROR; PDO_VALIDATE_CONN; PDO_LOG_DBH_ENTRY; sqlsrv_conn* driver_conn = reinterpret_cast( dbh->driver_data ); + SQLSRV_ASSERT( driver_conn != NULL, "pdo_sqlsrv_get_driver_methods: driver_data object was NULL." ); CHECK_CUSTOM_ERROR( true, driver_conn, PDO_SQLSRV_ERROR_FUNCTION_NOT_IMPLEMENTED ) { return NULL; } @@ -1453,8 +1459,8 @@ namespace { // Maps the PDO driver specific statement option/attribute constants to the core layer // statement option/attribute constants. -void add_stmt_option_key( sqlsrv_context& ctx, size_t key, HashTable* options_ht, - zval* data TSRMLS_DC ) +void add_stmt_option_key( _Inout_ sqlsrv_context& ctx, _In_ size_t key, _Inout_ HashTable* options_ht, + _Inout_ zval* data TSRMLS_DC ) { zend_ulong option_key = -1; switch( key ) { @@ -1517,7 +1523,7 @@ void add_stmt_option_key( sqlsrv_context& ctx, size_t key, HashTable* options_ht // ctx - The current context. // stmt_options - The user provided list of statement options. // pdo_stmt_options_ht - Output hashtable of statement options. -void validate_stmt_options( sqlsrv_context& ctx, zval* stmt_options, _Inout_ HashTable* pdo_stmt_options_ht TSRMLS_DC ) +void validate_stmt_options( _Inout_ sqlsrv_context& ctx, _In_ zval* stmt_options, _Inout_ HashTable* pdo_stmt_options_ht TSRMLS_DC ) { try { @@ -1547,7 +1553,7 @@ void validate_stmt_options( sqlsrv_context& ctx, zval* stmt_options, _Inout_ Has } -void pdo_bool_conn_str_func::func(connection_option const* option, zval* value, sqlsrv_conn* /*conn*/, std::string& conn_str TSRMLS_DC ) +void pdo_bool_conn_str_func::func( _In_ connection_option const* option, _Inout_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str TSRMLS_DC ) { TSRMLS_C; char const* val_str = "no"; @@ -1563,7 +1569,7 @@ void pdo_bool_conn_str_func::func(connection_option const* option, zval* value, conn_str += "};"; } -void pdo_txn_isolation_conn_attr_func::func( connection_option const* /*option*/, zval* value_z, sqlsrv_conn* conn, +void pdo_txn_isolation_conn_attr_func::func( connection_option const* /*option*/, _In_ zval* value_z, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) { try { diff --git a/source/pdo_sqlsrv/pdo_init.cpp b/source/pdo_sqlsrv/pdo_init.cpp index 7799ed1f..c8076e11 100644 --- a/source/pdo_sqlsrv/pdo_init.cpp +++ b/source/pdo_sqlsrv/pdo_init.cpp @@ -47,8 +47,8 @@ pdo_driver_t pdo_sqlsrv_driver = { // functions to register SQLSRV constants with the PDO class // (It's in all CAPS so it looks like the Zend macros that do similar work) -void REGISTER_PDO_SQLSRV_CLASS_CONST_LONG( char const* name, long value TSRMLS_DC ); -void REGISTER_PDO_SQLSRV_CLASS_CONST_STRING( char const* name, char const* value TSRMLS_DC ); +void REGISTER_PDO_SQLSRV_CLASS_CONST_LONG( _In_z_ char const* name, _In_ long value TSRMLS_DC ); +void REGISTER_PDO_SQLSRV_CLASS_CONST_STRING( _In_z_ char const* name, _In_z_ char const* value TSRMLS_DC ); struct sqlsrv_attr_pdo_constant { const char *name; @@ -100,7 +100,7 @@ zend_module_entry g_pdo_sqlsrv_module_entry = }; // called by Zend for each parameter in the g_pdo_errors_ht hash table when it is destroyed -void pdo_error_dtor( zval* elem ) { +void pdo_error_dtor( _Inout_ zval* elem ) { pdo_error* error_to_ignore = reinterpret_cast( Z_PTR_P( elem ) ); pefree( error_to_ignore, 1 ); } @@ -252,7 +252,7 @@ namespace { // mimic the functionality of the REGISTER_PDO_CLASS_CONST_LONG. We use this instead of the macro because // we dynamically link the pdo_get_dbh_class function rather than use the static php_pdo_get_dbh_ce (see MINIT) - void REGISTER_PDO_SQLSRV_CLASS_CONST_LONG( char const* name, long value TSRMLS_DC ) + void REGISTER_PDO_SQLSRV_CLASS_CONST_LONG( _In_z_ char const* name, _In_ long value TSRMLS_DC ) { zend_class_entry* zend_class = php_pdo_get_dbh_ce(); @@ -263,7 +263,7 @@ namespace { } } - void REGISTER_PDO_SQLSRV_CLASS_CONST_STRING( char const* name, char const* value TSRMLS_DC ) + void REGISTER_PDO_SQLSRV_CLASS_CONST_STRING( _In_z_ char const* name, _In_z_ char const* value TSRMLS_DC ) { zend_class_entry* zend_class = php_pdo_get_dbh_ce(); diff --git a/source/pdo_sqlsrv/pdo_parser.cpp b/source/pdo_sqlsrv/pdo_parser.cpp index 3cc8f3b2..56292a31 100644 --- a/source/pdo_sqlsrv/pdo_parser.cpp +++ b/source/pdo_sqlsrv/pdo_parser.cpp @@ -22,7 +22,7 @@ #include "php_pdo_sqlsrv.h" // Constructor -conn_string_parser:: conn_string_parser( sqlsrv_context& ctx, const char* dsn, int len, _Inout_ HashTable* conn_options_ht ) +conn_string_parser:: conn_string_parser( _In_ sqlsrv_context& ctx, _In_ const char* dsn, _In_ int len, _In_ HashTable* conn_options_ht ) { this->orig_str = dsn; this->len = len; @@ -33,7 +33,7 @@ conn_string_parser:: conn_string_parser( sqlsrv_context& ctx, const char* dsn, i this->current_key_name = NULL; } -sql_string_parser:: sql_string_parser( sqlsrv_context& ctx, const char* sql_str, int len, _Inout_ HashTable* placeholders_ht ) +sql_string_parser:: sql_string_parser( _In_ sqlsrv_context& ctx, _In_ const char* sql_str, _In_ int len, _In_ HashTable* placeholders_ht ) { this->orig_str = sql_str; this->len = len; @@ -78,7 +78,7 @@ inline bool string_parser::is_eos( void ) } // Check for white space. -inline bool string_parser::is_white_space( char c ) +inline bool string_parser::is_white_space( _In_ char c ) { if( c == ' ' || c == '\r' || c == '\n' || c == '\t' ) { return true; @@ -87,7 +87,7 @@ inline bool string_parser::is_white_space( char c ) } // Discard any trailing white spaces. -int conn_string_parser::discard_trailing_white_spaces( const char* str, int len ) +int conn_string_parser::discard_trailing_white_spaces( _In_reads_(len) const char* str, _Inout_ int len ) { const char* end = str + ( len - 1 ); @@ -118,7 +118,7 @@ bool string_parser::discard_white_spaces() } // Add a key-value pair to the hashtable -void string_parser::add_key_value_pair( const char* value, int len TSRMLS_DC ) +void string_parser::add_key_value_pair( _In_reads_(len) const char* value, _In_ int len TSRMLS_DC ) { zval value_z; ZVAL_UNDEF( &value_z ); @@ -136,7 +136,7 @@ void string_parser::add_key_value_pair( const char* value, int len TSRMLS_DC ) } // Add a key-value pair to the hashtable with int value -void sql_string_parser::add_key_int_value_pair( unsigned int value TSRMLS_DC ) { +void sql_string_parser::add_key_int_value_pair( _In_ unsigned int value TSRMLS_DC ) { zval value_z; ZVAL_LONG( &value_z, value ); @@ -144,7 +144,7 @@ void sql_string_parser::add_key_int_value_pair( unsigned int value TSRMLS_DC ) { } // Validate a given DSN keyword. -void conn_string_parser::validate_key(const char *key, int key_len TSRMLS_DC ) +void conn_string_parser::validate_key( _In_reads_(key_len) const char *key, _Inout_ int key_len TSRMLS_DC ) { int new_len = discard_trailing_white_spaces( key, key_len ); @@ -169,7 +169,7 @@ void conn_string_parser::validate_key(const char *key, int key_len TSRMLS_DC ) THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_INVALID_DSN_KEY, static_cast( key_name ) ); } -void conn_string_parser::add_key_value_pair( const char* value, int len TSRMLS_DC ) +void conn_string_parser::add_key_value_pair( _In_reads_(len) const char* value, _In_ int len TSRMLS_DC ) { // if the keyword is 'Authentication', check whether the user specified option is supported bool valid = true; diff --git a/source/pdo_sqlsrv/pdo_stmt.cpp b/source/pdo_sqlsrv/pdo_stmt.cpp index d5f98a07..edd73da1 100644 --- a/source/pdo_sqlsrv/pdo_stmt.cpp +++ b/source/pdo_sqlsrv/pdo_stmt.cpp @@ -37,7 +37,7 @@ SQLSMALLINT odbc_fetch_orientation[] = // max length of a field type const int SQL_SERVER_IDENT_SIZE_MAX = 128; -inline SQLSMALLINT pdo_fetch_ori_to_odbc_fetch_ori (enum pdo_fetch_orientation ori) +inline SQLSMALLINT pdo_fetch_ori_to_odbc_fetch_ori ( _In_ enum pdo_fetch_orientation ori ) { SQLSRV_ASSERT( ori >= PDO_FETCH_ORI_NEXT && ori <= PDO_FETCH_ORI_REL, "Fetch orientation out of range."); #ifdef _WIN32 @@ -49,7 +49,7 @@ inline SQLSMALLINT pdo_fetch_ori_to_odbc_fetch_ori (enum pdo_fetch_orientation o // Returns SQLSRV data type for a given PDO type. See pdo_param_type // for list of supported pdo types. -SQLSRV_PHPTYPE pdo_type_to_sqlsrv_php_type( sqlsrv_stmt* driver_stmt, enum pdo_param_type pdo_type TSRMLS_DC ) +SQLSRV_PHPTYPE pdo_type_to_sqlsrv_php_type( _Inout_ sqlsrv_stmt* driver_stmt, _In_ enum pdo_param_type pdo_type TSRMLS_DC ) { switch( pdo_type ) { @@ -80,7 +80,7 @@ SQLSRV_PHPTYPE pdo_type_to_sqlsrv_php_type( sqlsrv_stmt* driver_stmt, enum pdo_p // Returns a pdo type for a given SQL type. See pdo_param_type // for list of supported pdo types. -inline pdo_param_type sql_type_to_pdo_type( SQLSMALLINT sql_type ) +inline pdo_param_type sql_type_to_pdo_type( _In_ SQLSMALLINT sql_type ) { pdo_param_type return_type = PDO_PARAM_STR; @@ -127,7 +127,7 @@ inline pdo_param_type sql_type_to_pdo_type( SQLSMALLINT sql_type ) // Calls core_sqlsrv_set_scrollable function to set cursor. // PDO supports two cursor types: PDO_CURSOR_FWDONLY, PDO_CURSOR_SCROLL. -void set_stmt_cursors( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC ) +void set_stmt_cursors( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z TSRMLS_DC ) { if( Z_TYPE_P( value_z ) != IS_LONG ) { @@ -154,7 +154,7 @@ void set_stmt_cursors( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC ) core_sqlsrv_set_scrollable( stmt, odbc_cursor_type TSRMLS_CC ); } -void set_stmt_cursor_scroll_type( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC ) +void set_stmt_cursor_scroll_type( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z TSRMLS_DC ) { if( Z_TYPE_P( value_z ) != IS_LONG ) { @@ -175,7 +175,7 @@ void set_stmt_cursor_scroll_type( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC ) // Sets the statement encoding. Default encoding on the statement // implies use the connection's encoding. -void set_stmt_encoding( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC ) +void set_stmt_encoding( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z TSRMLS_DC ) { // validate the value if( Z_TYPE_P( value_z ) != IS_LONG ) { @@ -202,7 +202,7 @@ void set_stmt_encoding( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC ) } // internal helper function to free meta data structures allocated -void meta_data_free( field_meta_data* meta ) +void meta_data_free( _Inout_ field_meta_data* meta ) { if( meta->field_name ) { meta->field_name.reset(); @@ -210,9 +210,10 @@ void meta_data_free( field_meta_data* meta ) sqlsrv_free( meta ); } -zval convert_to_zval( SQLSRV_PHPTYPE sqlsrv_php_type, void** in_val, SQLLEN field_len ) +zval convert_to_zval( _In_ SQLSRV_PHPTYPE sqlsrv_php_type, _Inout_ void** in_val, _In_opt_ SQLLEN field_len ) { zval out_zval; + ZVAL_UNDEF( &out_zval ); switch( sqlsrv_php_type ) { @@ -274,20 +275,20 @@ zval convert_to_zval( SQLSRV_PHPTYPE sqlsrv_php_type, void** in_val, SQLLEN fiel } // namespace -int pdo_sqlsrv_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC); -int pdo_sqlsrv_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC); -int pdo_sqlsrv_stmt_fetch(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori, - zend_long offset TSRMLS_DC); -int pdo_sqlsrv_stmt_param_hook(pdo_stmt_t *stmt, - struct pdo_bound_param_data *param, enum pdo_param_event event_type TSRMLS_DC); -int pdo_sqlsrv_stmt_describe_col(pdo_stmt_t *stmt, int colno TSRMLS_DC); -int pdo_sqlsrv_stmt_get_col_data(pdo_stmt_t *stmt, int colno, - char **ptr, size_t *len, int *caller_frees TSRMLS_DC); -int pdo_sqlsrv_stmt_set_attr(pdo_stmt_t *stmt, zend_long attr, zval *val TSRMLS_DC); -int pdo_sqlsrv_stmt_get_attr(pdo_stmt_t *stmt, zend_long attr, zval *return_value TSRMLS_DC); -int pdo_sqlsrv_stmt_get_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *return_value TSRMLS_DC); -int pdo_sqlsrv_stmt_next_rowset(pdo_stmt_t *stmt TSRMLS_DC); -int pdo_sqlsrv_stmt_close_cursor(pdo_stmt_t *stmt TSRMLS_DC); +int pdo_sqlsrv_stmt_dtor( _Inout_ pdo_stmt_t *stmt TSRMLS_DC ); +int pdo_sqlsrv_stmt_execute( _Inout_ pdo_stmt_t *stmt TSRMLS_DC ); +int pdo_sqlsrv_stmt_fetch( _Inout_ pdo_stmt_t *stmt, _In_ enum pdo_fetch_orientation ori, + _In_ zend_long offset TSRMLS_DC ); +int pdo_sqlsrv_stmt_param_hook( _Inout_ pdo_stmt_t *stmt, + _Inout_ struct pdo_bound_param_data *param, _In_ enum pdo_param_event event_type TSRMLS_DC ); +int pdo_sqlsrv_stmt_describe_col( _Inout_ pdo_stmt_t *stmt, _In_ int colno TSRMLS_DC ); +int pdo_sqlsrv_stmt_get_col_data( _In_ pdo_stmt_t *stmt, _In_ int colno, + _Out_writes_bytes_opt_(*len) char **ptr, _Inout_ size_t *len, _Out_opt_ int *caller_frees TSRMLS_DC ); +int pdo_sqlsrv_stmt_set_attr( _In_ pdo_stmt_t *stmt, _In_ zend_long attr, _Inout_ zval *val TSRMLS_DC ); +int pdo_sqlsrv_stmt_get_attr( _In_ pdo_stmt_t *stmt, _In_ zend_long attr, _Inout_ zval *return_value TSRMLS_DC ); +int pdo_sqlsrv_stmt_get_col_meta( _In_ pdo_stmt_t *stmt, _In_ zend_long colno, _Inout_ zval *return_value TSRMLS_DC ); +int pdo_sqlsrv_stmt_next_rowset( _Inout_ pdo_stmt_t *stmt TSRMLS_DC ); +int pdo_sqlsrv_stmt_close_cursor( _In_ pdo_stmt_t *stmt TSRMLS_DC ); struct pdo_stmt_methods pdo_sqlsrv_stmt_methods = { @@ -305,34 +306,34 @@ struct pdo_stmt_methods pdo_sqlsrv_stmt_methods = { }; -void stmt_option_pdo_scrollable:: operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC ) +void stmt_option_pdo_scrollable:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) { set_stmt_cursors( stmt, value_z TSRMLS_CC ); } -void stmt_option_encoding:: operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC ) +void stmt_option_encoding:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) { set_stmt_encoding( stmt, value_z TSRMLS_CC ); } -void stmt_option_direct_query:: operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC ) +void stmt_option_direct_query:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) { pdo_sqlsrv_stmt *pdo_stmt = static_cast( stmt ); pdo_stmt->direct_query = ( zend_is_true( value_z )) ? true : false; } -void stmt_option_cursor_scroll_type:: operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC ) +void stmt_option_cursor_scroll_type:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) { set_stmt_cursor_scroll_type( stmt, value_z TSRMLS_CC ); } -void stmt_option_emulate_prepares:: operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC ) +void stmt_option_emulate_prepares:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) { pdo_stmt_t *pdo_stmt = static_cast( stmt->driver() ); pdo_stmt->supports_placeholders = ( zend_is_true( value_z )) ? PDO_PLACEHOLDER_NONE : PDO_PLACEHOLDER_POSITIONAL; } -void stmt_option_fetch_numeric:: operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC ) +void stmt_option_fetch_numeric:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) { pdo_sqlsrv_stmt *pdo_stmt = static_cast( stmt ); pdo_stmt->fetch_numeric = ( zend_is_true( value_z )) ? true : false; @@ -385,7 +386,7 @@ pdo_sqlsrv_stmt::~pdo_sqlsrv_stmt( void ) // *stmt - Pointer to current statement // Return: // Returns 0 for failure, 1 for success. -int pdo_sqlsrv_stmt_close_cursor(pdo_stmt_t *stmt TSRMLS_DC) +int pdo_sqlsrv_stmt_close_cursor( _In_ pdo_stmt_t *stmt TSRMLS_DC ) { PDO_RESET_STMT_ERROR; PDO_VALIDATE_STMT; @@ -402,9 +403,9 @@ int pdo_sqlsrv_stmt_close_cursor(pdo_stmt_t *stmt TSRMLS_DC) // to "close the cursor" means we make the statement ready for execution again. To do this, we // skip all the result sets on the current statement. // If the statement has not been executed there are no next results to iterate over. - if ( driver_stmt->executed == true ) + if ( driver_stmt && driver_stmt->executed == true ) { - while( driver_stmt->past_next_result_end == false ) { + while( driver_stmt && driver_stmt->past_next_result_end == false ) { core_sqlsrv_next_result( driver_stmt TSRMLS_CC ); } } @@ -429,13 +430,14 @@ int pdo_sqlsrv_stmt_close_cursor(pdo_stmt_t *stmt TSRMLS_DC) // colno - Index of the column which requires description. // Return: // 0 for failure, 1 for success. -int pdo_sqlsrv_stmt_describe_col(pdo_stmt_t *stmt, int colno TSRMLS_DC) +int pdo_sqlsrv_stmt_describe_col( _Inout_ pdo_stmt_t *stmt, _In_ int colno TSRMLS_DC) { PDO_RESET_STMT_ERROR; PDO_VALIDATE_STMT; PDO_LOG_STMT_ENTRY; SQLSRV_ASSERT(( colno >= 0 ), "pdo_sqlsrv_stmt_describe_col: Column number should be >= 0." ); + SQLSRV_ASSERT( stmt->driver_data != NULL, "pdo_sqlsrv_stmt_describe_col: driver_data object was NULL." ); sqlsrv_malloc_auto_ptr core_meta_data; @@ -486,7 +488,7 @@ int pdo_sqlsrv_stmt_describe_col(pdo_stmt_t *stmt, int colno TSRMLS_DC) // *stmt - pointer to current statement // Return: // 1 for success. -int pdo_sqlsrv_stmt_dtor( pdo_stmt_t *stmt TSRMLS_DC ) +int pdo_sqlsrv_stmt_dtor( _Inout_ pdo_stmt_t *stmt TSRMLS_DC ) { pdo_sqlsrv_stmt* driver_stmt = reinterpret_cast( stmt->driver_data ); @@ -519,7 +521,7 @@ int pdo_sqlsrv_stmt_dtor( pdo_stmt_t *stmt TSRMLS_DC ) // *stmt - pointer to the current statement. // Return: // 0 for failure, 1 for success. -int pdo_sqlsrv_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) +int pdo_sqlsrv_stmt_execute( _Inout_ pdo_stmt_t *stmt TSRMLS_DC ) { PDO_RESET_STMT_ERROR; PDO_VALIDATE_STMT; @@ -532,7 +534,7 @@ int pdo_sqlsrv_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) // prepare for execution by flushing anything remaining in the result set if it wasn't already // done before binding parameters - if( driver_stmt->executed && !driver_stmt->past_next_result_end ) { + if( driver_stmt && driver_stmt->executed && !driver_stmt->past_next_result_end ) { while( driver_stmt->past_next_result_end == false ) { @@ -615,8 +617,8 @@ int pdo_sqlsrv_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) // offset - For orientations that use it, offset to move to. // Return: // 0 for failure, 1 for success. -int pdo_sqlsrv_stmt_fetch(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori, - zend_long offset TSRMLS_DC) +int pdo_sqlsrv_stmt_fetch( _Inout_ pdo_stmt_t *stmt, _In_ enum pdo_fetch_orientation ori, + _In_ zend_long offset TSRMLS_DC) { PDO_RESET_STMT_ERROR; PDO_VALIDATE_STMT; @@ -709,8 +711,8 @@ int pdo_sqlsrv_stmt_fetch(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori, // freeing the memory. // Return: // 0 for failure, 1 for success. -int pdo_sqlsrv_stmt_get_col_data(pdo_stmt_t *stmt, int colno, - char **ptr, size_t *len, int *caller_frees TSRMLS_DC) +int pdo_sqlsrv_stmt_get_col_data( _In_ pdo_stmt_t *stmt, _In_ int colno, + _Out_writes_bytes_opt_(*len) char **ptr, _Inout_ size_t *len, _Out_opt_ int *caller_frees TSRMLS_DC) { PDO_RESET_STMT_ERROR; PDO_VALIDATE_STMT; @@ -787,11 +789,12 @@ int pdo_sqlsrv_stmt_get_col_data(pdo_stmt_t *stmt, int colno, core_sqlsrv_get_field( driver_stmt, colno, sqlsrv_php_type, false, *(reinterpret_cast(ptr)), reinterpret_cast( len ), true, &sqlsrv_phptype_out TSRMLS_CC ); - zval* zval_ptr = reinterpret_cast( sqlsrv_malloc( sizeof( zval ))); - *zval_ptr = convert_to_zval( sqlsrv_phptype_out, reinterpret_cast( ptr ), *len ); - *ptr = reinterpret_cast( zval_ptr ); - - *len = sizeof( zval ); + if ( ptr ) { + zval* zval_ptr = reinterpret_cast( sqlsrv_malloc( sizeof( zval ))); + *zval_ptr = convert_to_zval( sqlsrv_phptype_out, reinterpret_cast( ptr ), *len ); + *ptr = reinterpret_cast( zval_ptr ); + *len = sizeof( zval ); + } return 1; } @@ -812,13 +815,14 @@ int pdo_sqlsrv_stmt_get_col_data(pdo_stmt_t *stmt, int colno, // val - Attribute value. // Return: // 0 for failure, 1 for success. -int pdo_sqlsrv_stmt_set_attr(pdo_stmt_t *stmt, zend_long attr, zval *val TSRMLS_DC) +int pdo_sqlsrv_stmt_set_attr( _In_ pdo_stmt_t *stmt, _In_ zend_long attr, _Inout_ zval *val TSRMLS_DC) { PDO_RESET_STMT_ERROR; PDO_VALIDATE_STMT; PDO_LOG_STMT_ENTRY; pdo_sqlsrv_stmt* driver_stmt = static_cast( stmt->driver_data ); + SQLSRV_ASSERT( driver_stmt != NULL, "pdo_sqlsrv_stmt_set_attr: driver_data object was null" ); try { @@ -877,7 +881,7 @@ int pdo_sqlsrv_stmt_set_attr(pdo_stmt_t *stmt, zend_long attr, zval *val TSRMLS_ // return_value - Attribute value. // Return: // 0 for failure, 1 for success. -int pdo_sqlsrv_stmt_get_attr( pdo_stmt_t *stmt, zend_long attr, zval *return_value TSRMLS_DC ) +int pdo_sqlsrv_stmt_get_attr( _In_ pdo_stmt_t *stmt, _In_ zend_long attr, _Inout_ zval *return_value TSRMLS_DC ) { PDO_RESET_STMT_ERROR; PDO_VALIDATE_STMT; @@ -961,7 +965,7 @@ int pdo_sqlsrv_stmt_get_attr( pdo_stmt_t *stmt, zend_long attr, zval *return_val // return_value - zval* consisting of the metadata. // Return: // 0 for failure, 1 for success. -int pdo_sqlsrv_stmt_get_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *return_value TSRMLS_DC) +int pdo_sqlsrv_stmt_get_col_meta( _In_ pdo_stmt_t *stmt, _In_ zend_long colno, _Inout_ zval *return_value TSRMLS_DC) { PDO_RESET_STMT_ERROR; PDO_VALIDATE_STMT; @@ -975,6 +979,7 @@ int pdo_sqlsrv_stmt_get_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *return sqlsrv_malloc_auto_ptr core_meta_data; sqlsrv_stmt* driver_stmt = static_cast( stmt->driver_data ); + SQLSRV_ASSERT( driver_stmt != NULL, "pdo_sqlsrv_stmt_get_col_meta: stmt->driver_data was null"); SQLSRV_ASSERT( colno >= 0 && colno < stmt->column_count, "pdo_sqlsrv_stmt_get_col_meta: invalid column number." ); @@ -1018,7 +1023,7 @@ int pdo_sqlsrv_stmt_get_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *return &out_buff_len, &field_type_num TSRMLS_CC ); add_assoc_string( return_value, "table", table_name ); - if( stmt->columns[ colno ].param_type == PDO_PARAM_ZVAL ) { + if( stmt->columns && stmt->columns[ colno ].param_type == PDO_PARAM_ZVAL ) { add_assoc_long( return_value, "pdo_type", pdo_type ); } @@ -1048,7 +1053,7 @@ int pdo_sqlsrv_stmt_get_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *return // stmt - PDOStatement object containing the result set. // Return: // 0 for failure, 1 for success. -int pdo_sqlsrv_stmt_next_rowset(pdo_stmt_t *stmt TSRMLS_DC) +int pdo_sqlsrv_stmt_next_rowset( _Inout_ pdo_stmt_t *stmt TSRMLS_DC ) { PDO_RESET_STMT_ERROR; PDO_VALIDATE_STMT; @@ -1103,8 +1108,8 @@ int pdo_sqlsrv_stmt_next_rowset(pdo_stmt_t *stmt TSRMLS_DC) // event_type - Event to bind a parameter // Return: // Returns 0 for failure, 1 for success. -int pdo_sqlsrv_stmt_param_hook(pdo_stmt_t *stmt, - struct pdo_bound_param_data *param, enum pdo_param_event event_type TSRMLS_DC) +int pdo_sqlsrv_stmt_param_hook( _Inout_ pdo_stmt_t *stmt, + _Inout_ struct pdo_bound_param_data *param, _In_ enum pdo_param_event event_type TSRMLS_DC) { PDO_RESET_STMT_ERROR; @@ -1306,7 +1311,7 @@ int pdo_sqlsrv_stmt_param_hook(pdo_stmt_t *stmt, // Returns a sqlsrv_phptype for a given SQL Server data type. -sqlsrv_phptype pdo_sqlsrv_stmt::sql_type_to_php_type( SQLINTEGER sql_type, SQLUINTEGER size, bool prefer_string_over_stream ) +sqlsrv_phptype pdo_sqlsrv_stmt::sql_type_to_php_type( _In_ SQLINTEGER sql_type, SQLUINTEGER size, bool prefer_string_over_stream ) { sqlsrv_phptype sqlsrv_phptype; int local_encoding = this->encoding(); diff --git a/source/pdo_sqlsrv/pdo_util.cpp b/source/pdo_sqlsrv/pdo_util.cpp index 46e69868..3e05ff1c 100644 --- a/source/pdo_sqlsrv/pdo_util.cpp +++ b/source/pdo_sqlsrv/pdo_util.cpp @@ -43,10 +43,10 @@ char log_msg[ LOG_MSG_SIZE ]; SQLCHAR INTERNAL_FORMAT_ERROR[] = "An internal error occurred. FormatMessage failed writing an error message."; // Returns a sqlsrv_error for a given error code. -sqlsrv_error_const* get_error_message(unsigned int sqlsrv_error_code); +sqlsrv_error_const* get_error_message( _In_opt_ unsigned int sqlsrv_error_code); // build the object and throw the PDO exception -void pdo_sqlsrv_throw_exception( sqlsrv_error_const* error TSRMLS_DC ); +void pdo_sqlsrv_throw_exception( _In_ sqlsrv_error_const* error TSRMLS_DC ); } @@ -385,8 +385,8 @@ pdo_error PDO_ERRORS[] = { }; // PDO error handler for the environment context. -bool pdo_sqlsrv_handle_env_error( sqlsrv_context& ctx, unsigned int sqlsrv_error_code, bool warning TSRMLS_DC, - va_list* print_args ) +bool pdo_sqlsrv_handle_env_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned int sqlsrv_error_code, _In_opt_ bool warning TSRMLS_DC, + _In_opt_ va_list* print_args ) { SQLSRV_ASSERT(( ctx != NULL ), "pdo_sqlsrv_handle_env_error: sqlsrv_context was null" ); pdo_dbh_t* dbh = reinterpret_cast( ctx.driver()); @@ -428,8 +428,8 @@ bool pdo_sqlsrv_handle_env_error( sqlsrv_context& ctx, unsigned int sqlsrv_error } // pdo error handler for the dbh context. -bool pdo_sqlsrv_handle_dbh_error( sqlsrv_context& ctx, unsigned int sqlsrv_error_code, bool warning TSRMLS_DC, - va_list* print_args ) +bool pdo_sqlsrv_handle_dbh_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned int sqlsrv_error_code, _In_opt_ bool warning TSRMLS_DC, + _In_opt_ va_list* print_args ) { pdo_dbh_t* dbh = reinterpret_cast( ctx.driver()); SQLSRV_ASSERT( dbh != NULL, "pdo_sqlsrv_handle_dbh_error: Null dbh passed" ); @@ -481,8 +481,8 @@ bool pdo_sqlsrv_handle_dbh_error( sqlsrv_context& ctx, unsigned int sqlsrv_error } // PDO error handler for the statement context. -bool pdo_sqlsrv_handle_stmt_error( sqlsrv_context& ctx, unsigned int sqlsrv_error_code, bool warning TSRMLS_DC, - va_list* print_args ) +bool pdo_sqlsrv_handle_stmt_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned int sqlsrv_error_code, _In_opt_ bool warning TSRMLS_DC, + _In_opt_ va_list* print_args ) { pdo_stmt_t* pdo_stmt = reinterpret_cast( ctx.driver()); SQLSRV_ASSERT( pdo_stmt != NULL && pdo_stmt->dbh != NULL, "pdo_sqlsrv_handle_stmt_error: Null statement or dbh passed" ); @@ -529,7 +529,7 @@ bool pdo_sqlsrv_handle_stmt_error( sqlsrv_context& ctx, unsigned int sqlsrv_erro // 1, native message // 2, SQLSTATE of the error (driver specific error messages are 'IMSSP') -void pdo_sqlsrv_retrieve_context_error( sqlsrv_error const* last_error, zval* pdo_zval ) +void pdo_sqlsrv_retrieve_context_error( _In_ sqlsrv_error const* last_error, _Out_ zval* pdo_zval ) { if( last_error ) { // SQLSTATE is already present in the zval. @@ -539,7 +539,7 @@ void pdo_sqlsrv_retrieve_context_error( sqlsrv_error const* last_error, zval* pd } // Formats the error message and writes to the php error log. -void pdo_sqlsrv_log( unsigned int severity TSRMLS_DC, const char* msg, va_list* print_args ) +void pdo_sqlsrv_log( _In_opt_ unsigned int severity TSRMLS_DC, _In_opt_ const char* msg, _In_opt_ va_list* print_args ) { if( (severity & PDO_SQLSRV_G( log_severity )) == 0 ) { return; @@ -560,7 +560,7 @@ namespace { // Workaround for name collision problem between the SQLSRV and PDO_SQLSRV drivers on Mac // Place get_error_message into the anonymous namespace in pdo_util.cpp -sqlsrv_error_const* get_error_message(unsigned int sqlsrv_error_code) { +sqlsrv_error_const* get_error_message( _In_opt_ unsigned int sqlsrv_error_code) { sqlsrv_error_const *error_message = NULL; int zr = (error_message = reinterpret_cast(zend_hash_index_find_ptr(g_pdo_errors_ht, sqlsrv_error_code))) != NULL ? SUCCESS : FAILURE; @@ -573,7 +573,7 @@ sqlsrv_error_const* get_error_message(unsigned int sqlsrv_error_code) { return error_message; } -void pdo_sqlsrv_throw_exception( sqlsrv_error_const* error TSRMLS_DC ) +void pdo_sqlsrv_throw_exception( _In_ sqlsrv_error_const* error TSRMLS_DC ) { zval ex_obj; ZVAL_UNDEF( &ex_obj ); diff --git a/source/pdo_sqlsrv/php_pdo_sqlsrv.h b/source/pdo_sqlsrv/php_pdo_sqlsrv.h index 6fc96e26..e402c2ed 100644 --- a/source/pdo_sqlsrv/php_pdo_sqlsrv.h +++ b/source/pdo_sqlsrv/php_pdo_sqlsrv.h @@ -137,9 +137,9 @@ class string_parser HashTable* element_ht; inline bool next(void); inline bool is_eos(void); - inline bool is_white_space(char c); + inline bool is_white_space( _In_ char c ); bool discard_white_spaces(void); - void add_key_value_pair(const char* value, int len TSRMLS_DC); + void add_key_value_pair( _In_reads_(len) const char* value, _In_ int len TSRMLS_DC ); }; //********************************************************************************************************************************* @@ -162,14 +162,14 @@ class conn_string_parser : private string_parser private: const char* current_key_name; - int discard_trailing_white_spaces(const char* str, int len); - void validate_key(const char *key, int key_len TSRMLS_DC); + int discard_trailing_white_spaces( _In_reads_(len) const char* str, _Inout_ int len ); + void validate_key( _In_reads_(key_len) const char *key, _Inout_ int key_len TSRMLS_DC); protected: - void add_key_value_pair(const char* value, int len TSRMLS_DC); + void add_key_value_pair( _In_reads_(len) const char* value, _In_ int len TSRMLS_DC); public: - conn_string_parser( sqlsrv_context& ctx, const char* dsn, int len, _Inout_ HashTable* conn_options_ht ); + conn_string_parser( _In_ sqlsrv_context& ctx, _In_ const char* dsn, _In_ int len, _In_ HashTable* conn_options_ht ); void parse_conn_string( TSRMLS_D ); }; @@ -183,8 +183,8 @@ class sql_string_parser : private string_parser private: bool is_placeholder_char(char); public: - void add_key_int_value_pair(unsigned int value TSRMLS_DC); - sql_string_parser(sqlsrv_context& ctx, const char* sql_str, int len, _Inout_ HashTable* placeholder_ht); + void add_key_int_value_pair( _In_ unsigned int value TSRMLS_DC ); + sql_string_parser(_In_ sqlsrv_context& ctx, _In_ const char* sql_str, _In_ int len, _In_ HashTable* placeholder_ht); void parse_sql_string(TSRMLS_D); }; @@ -193,7 +193,7 @@ class sql_string_parser : private string_parser //********************************************************************************************************************************* extern const connection_option PDO_CONN_OPTS[]; -int pdo_sqlsrv_db_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC); +int pdo_sqlsrv_db_handle_factory( _Inout_ pdo_dbh_t *dbh, _In_opt_ zval *driver_options TSRMLS_DC); // a core layer pdo dbh object. This object inherits and overrides the statement factory struct pdo_sqlsrv_dbh : public sqlsrv_conn { @@ -204,7 +204,7 @@ struct pdo_sqlsrv_dbh : public sqlsrv_conn { zend_long client_buffer_max_size; bool fetch_numeric; - pdo_sqlsrv_dbh( SQLHANDLE h, error_callback e, void* driver TSRMLS_DC ); + pdo_sqlsrv_dbh( _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* driver TSRMLS_DC ); }; @@ -214,31 +214,31 @@ struct pdo_sqlsrv_dbh : public sqlsrv_conn { struct stmt_option_encoding : public stmt_option_functor { - virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC ); + virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ); }; struct stmt_option_pdo_scrollable : public stmt_option_functor { - virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC ); + virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ); }; struct stmt_option_direct_query : public stmt_option_functor { - virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC ); + virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ); }; struct stmt_option_cursor_scroll_type : public stmt_option_functor { - virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC ); + virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ); }; struct stmt_option_emulate_prepares : public stmt_option_functor { - virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC ); + virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ); }; struct stmt_option_fetch_numeric : public stmt_option_functor { - virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC ); + virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ); }; extern struct pdo_stmt_methods pdo_sqlsrv_stmt_methods; @@ -246,7 +246,7 @@ extern struct pdo_stmt_methods pdo_sqlsrv_stmt_methods; // a core layer pdo stmt object. This object inherits and overrides the callbacks necessary struct pdo_sqlsrv_stmt : public sqlsrv_stmt { - pdo_sqlsrv_stmt( sqlsrv_conn* c, SQLHANDLE handle, error_callback e, void* drv TSRMLS_DC ) : + pdo_sqlsrv_stmt( _In_ sqlsrv_conn* c, _In_ SQLHANDLE handle, _In_ error_callback e, _In_ void* drv TSRMLS_DC ) : sqlsrv_stmt( c, handle, e, drv TSRMLS_CC ), direct_query( false ), direct_query_subst_string( NULL ), @@ -264,7 +264,7 @@ struct pdo_sqlsrv_stmt : public sqlsrv_stmt { // driver specific conversion rules from a SQL Server/ODBC type to one of the SQLSRV_PHPTYPE_* constants // for PDO, everything is a string, so we return SQLSRV_PHPTYPE_STRING for all SQL types - virtual sqlsrv_phptype sql_type_to_php_type( SQLINTEGER sql_type, SQLUINTEGER size, bool prefer_string_to_stream ); + virtual sqlsrv_phptype sql_type_to_php_type( _In_ SQLINTEGER sql_type, SQLUINTEGER size, bool prefer_string_to_stream ); bool direct_query; // flag set if the query should be executed directly or prepared const char* direct_query_subst_string; // if the query is direct, hold the substitution string if using named parameters @@ -292,18 +292,18 @@ struct pdo_error { // called when an error occurs in the core layer. These routines are set as the error_callback in a // context. The context is passed to this function since it contains the function -bool pdo_sqlsrv_handle_env_error( sqlsrv_context& ctx, unsigned int sqlsrv_error_code, bool warning TSRMLS_DC, - va_list* print_args ); -bool pdo_sqlsrv_handle_dbh_error( sqlsrv_context& ctx, unsigned int sqlsrv_error_code, bool warning TSRMLS_DC, - va_list* print_args ); -bool pdo_sqlsrv_handle_stmt_error( sqlsrv_context& ctx, unsigned int sqlsrv_error_code, bool warning TSRMLS_DC, - va_list* print_args ); +bool pdo_sqlsrv_handle_env_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned int sqlsrv_error_code, _In_opt_ bool warning TSRMLS_DC, + _In_opt_ va_list* print_args ); +bool pdo_sqlsrv_handle_dbh_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned int sqlsrv_error_code, _In_opt_ bool warning TSRMLS_DC, + _In_opt_ va_list* print_args ); +bool pdo_sqlsrv_handle_stmt_error( _Inout_ sqlsrv_context& ctx, _In_opt_ unsigned int sqlsrv_error_code, _In_opt_ bool warning TSRMLS_DC, + _In_opt_ va_list* print_args ); // common routine to transfer a sqlsrv_context's error to a PDO zval -void pdo_sqlsrv_retrieve_context_error( sqlsrv_error const* last_error, zval* pdo_zval ); +void pdo_sqlsrv_retrieve_context_error( _In_ sqlsrv_error const* last_error, _Out_ zval* pdo_zval ); // reset the errors from the last operation -inline void pdo_reset_dbh_error( pdo_dbh_t* dbh TSRMLS_DC ) +inline void pdo_reset_dbh_error( _Inout_ pdo_dbh_t* dbh TSRMLS_DC ) { strcpy_s( dbh->error_code, sizeof( dbh->error_code ), "00000" ); // 00000 means no error @@ -328,7 +328,7 @@ inline void pdo_reset_dbh_error( pdo_dbh_t* dbh TSRMLS_DC ) #define PDO_RESET_DBH_ERROR pdo_reset_dbh_error( dbh TSRMLS_CC ); -inline void pdo_reset_stmt_error( pdo_stmt_t* stmt ) +inline void pdo_reset_stmt_error( _Inout_ pdo_stmt_t* stmt ) { strcpy_s( stmt->error_code, sizeof( stmt->error_code ), "00000" ); // 00000 means no error @@ -415,7 +415,7 @@ namespace pdo { } // namespace pdo // logger for pdo_sqlsrv called by the core layer when it wants to log something with the LOG macro -void pdo_sqlsrv_log( unsigned int severity TSRMLS_DC, const char* msg, va_list* print_args ); +void pdo_sqlsrv_log( _In_opt_ unsigned int severity TSRMLS_DC, _In_opt_ const char* msg, _In_opt_ va_list* print_args ); #endif /* PHP_PDO_SQLSRV_H */ diff --git a/source/shared/core_conn.cpp b/source/shared/core_conn.cpp index a2d92aa0..04274576 100644 --- a/source/shared/core_conn.cpp +++ b/source/shared/core_conn.cpp @@ -63,14 +63,14 @@ const char CONNECTION_OPTION_MARS_ON[] = "MARS_Connection={Yes};"; // *** internal function prototypes *** -void build_connection_string_and_set_conn_attr( sqlsrv_conn* conn, const char* server, const char* uid, const char* pwd, - HashTable* options_ht, const connection_option valid_conn_opts[], +void build_connection_string_and_set_conn_attr( _Inout_ sqlsrv_conn* conn, _Inout_z_ const char* server, _Inout_opt_z_ const char* uid, _Inout_opt_z_ const char* pwd, + _Inout_opt_ HashTable* options_ht, _In_ const connection_option valid_conn_opts[], void* driver,_Inout_ std::string& connection_string TSRMLS_DC ); -void determine_server_version( sqlsrv_conn* conn TSRMLS_DC ); +void determine_server_version( _Inout_ sqlsrv_conn* conn TSRMLS_DC ); const char* get_processor_arch( void ); -void get_server_version( sqlsrv_conn* conn, char** server_version, SQLSMALLINT& len TSRMLS_DC ); -connection_option const* get_connection_option( sqlsrv_conn* conn, const char* key, SQLULEN key_len TSRMLS_DC ); -void common_conn_str_append_func( const char* odbc_name, const char* val, size_t val_len, std::string& conn_str TSRMLS_DC ); +void get_server_version( _Inout_ sqlsrv_conn* conn, _Outptr_result_buffer_(len) char** server_version, _Out_ SQLSMALLINT& len TSRMLS_DC ); +connection_option const* get_connection_option( sqlsrv_conn* conn, _In_ const char* key, _In_ SQLULEN key_len TSRMLS_DC ); +void common_conn_str_append_func( _In_z_ const char* odbc_name, _In_reads_(val_len) const char* val, _Inout_ size_t val_len, _Inout_ std::string& conn_str TSRMLS_DC ); } @@ -89,10 +89,10 @@ void common_conn_str_append_func( const char* odbc_name, const char* val, size_t // Return // A sqlsrv_conn structure. An exception is thrown if an error occurs -sqlsrv_conn* core_sqlsrv_connect( sqlsrv_context& henv_cp, sqlsrv_context& henv_ncp, driver_conn_factory conn_factory, - const char* server, const char* uid, const char* pwd, - HashTable* options_ht, error_callback err, const connection_option valid_conn_opts[], - void* driver, const char* driver_func TSRMLS_DC ) +sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_context& henv_ncp, _In_ driver_conn_factory conn_factory, + _Inout_z_ const char* server, _Inout_opt_z_ const char* uid, _Inout_opt_z_ const char* pwd, + _Inout_opt_ HashTable* options_ht, _In_ error_callback err, _In_ const connection_option valid_conn_opts[], + _In_ void* driver, _In_z_ const char* driver_func TSRMLS_DC ) { SQLRETURN r; @@ -181,16 +181,16 @@ sqlsrv_conn* core_sqlsrv_connect( sqlsrv_context& henv_cp, sqlsrv_context& henv_ memset( const_cast(conn_str.c_str()), 0, conn_str.size()); memset( wconn_string, 0, wconn_len * sizeof( SQLWCHAR )); // wconn_len is the number of characters, not bytes conn_str.clear(); - if (!SQL_SUCCEEDED(r)) { + if ( !SQL_SUCCEEDED( r )) { SQLCHAR state[SQL_SQLSTATE_BUFSIZE]; SQLSMALLINT len; - SQLRETURN r = SQLGetDiagField(SQL_HANDLE_DBC, conn->handle(), 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len); - bool missing_driver_error = (SQL_SUCCEEDED(r) && state[0] == 'I' && state[1] == 'M' && state[2] == '0' && state[3] == '0' && state[4] == '2'); + SQLRETURN sr = SQLGetDiagField( SQL_HANDLE_DBC, conn->handle(), 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len ); + bool missing_driver_error = ( SQL_SUCCEEDED( sr ) && state[0] == 'I' && state[1] == 'M' && state[2] == '0' && state[3] == '0' && state[4] == '2' ); // if it's a IM002, meaning that the correct ODBC driver is not installed - CHECK_CUSTOM_ERROR(missing_driver_error && (i == DRIVER_VERSION::MAX), conn, SQLSRV_ERROR_DRIVER_NOT_INSTALLED, get_processor_arch()) { + CHECK_CUSTOM_ERROR(missing_driver_error && ( i == DRIVER_VERSION::MAX ), conn, SQLSRV_ERROR_DRIVER_NOT_INSTALLED, get_processor_arch()) { throw core::CoreException(); } - if (!missing_driver_error) { + if ( !missing_driver_error ) { break; } } @@ -268,7 +268,7 @@ sqlsrv_conn* core_sqlsrv_connect( sqlsrv_context& henv_cp, sqlsrv_context& henv_ // Parameters: // sqlsrv_conn*: The connection with which the transaction is associated. -void core_sqlsrv_begin_transaction( sqlsrv_conn* conn TSRMLS_DC ) +void core_sqlsrv_begin_transaction( _Inout_ sqlsrv_conn* conn TSRMLS_DC ) { try { @@ -291,7 +291,7 @@ void core_sqlsrv_begin_transaction( sqlsrv_conn* conn TSRMLS_DC ) // Parameters: // sqlsrv_conn*: The connection on which the transaction is active. -void core_sqlsrv_commit( sqlsrv_conn* conn TSRMLS_DC ) +void core_sqlsrv_commit( _Inout_ sqlsrv_conn* conn TSRMLS_DC ) { try { @@ -316,7 +316,7 @@ void core_sqlsrv_commit( sqlsrv_conn* conn TSRMLS_DC ) // Parameters: // sqlsrv_conn*: The connection on which the transaction is active. -void core_sqlsrv_rollback( sqlsrv_conn* conn TSRMLS_DC ) +void core_sqlsrv_rollback( _Inout_ sqlsrv_conn* conn TSRMLS_DC ) { try { @@ -337,7 +337,7 @@ void core_sqlsrv_rollback( sqlsrv_conn* conn TSRMLS_DC ) // Called when a connection resource is destroyed by the Zend engine. // Parameters: // conn - The current active connection. -void core_sqlsrv_close( sqlsrv_conn* conn TSRMLS_DC ) +void core_sqlsrv_close( _Inout_opt_ sqlsrv_conn* conn TSRMLS_DC ) { // if the connection wasn't successful, just return. if( conn == NULL ) @@ -371,7 +371,7 @@ void core_sqlsrv_close( sqlsrv_conn* conn TSRMLS_DC ) // sql - T-SQL command to prepare // sql_len - length of the T-SQL string -void core_sqlsrv_prepare( sqlsrv_stmt* stmt, const char* sql, SQLLEN sql_len TSRMLS_DC ) +void core_sqlsrv_prepare( _Inout_ sqlsrv_stmt* stmt, _In_reads_bytes_(sql_len) const char* sql, _In_ SQLLEN sql_len TSRMLS_DC ) { try { @@ -414,7 +414,7 @@ void core_sqlsrv_prepare( sqlsrv_stmt* stmt, const char* sql, SQLLEN sql_len TSR // conn - The connection resource by which the client and server are connected. // *server_version - zval for returning results. -void core_sqlsrv_get_server_version( sqlsrv_conn* conn, _Out_ zval *server_version TSRMLS_DC ) +void core_sqlsrv_get_server_version( _Inout_ sqlsrv_conn* conn, _Inout_ zval* server_version TSRMLS_DC ) { try { @@ -441,7 +441,7 @@ void core_sqlsrv_get_server_version( sqlsrv_conn* conn, _Out_ zval *server_versi // conn - The connection resource by which the client and server are connected. // *server_info - zval for returning results. -void core_sqlsrv_get_server_info( sqlsrv_conn* conn, _Out_ zval *server_info TSRMLS_DC ) +void core_sqlsrv_get_server_info( _Inout_ sqlsrv_conn* conn, _Out_ zval *server_info TSRMLS_DC ) { try { @@ -481,7 +481,7 @@ void core_sqlsrv_get_server_info( sqlsrv_conn* conn, _Out_ zval *server_info TSR // conn - The connection resource by which the client and server are connected. // *client_info - zval for returning the results. -void core_sqlsrv_get_client_info( sqlsrv_conn* conn, _Out_ zval *client_info TSRMLS_DC ) +void core_sqlsrv_get_client_info( _Inout_ sqlsrv_conn* conn, _Out_ zval *client_info TSRMLS_DC ) { try { @@ -527,7 +527,7 @@ void core_sqlsrv_get_client_info( sqlsrv_conn* conn, _Out_ zval *client_info TSR // Properly escaped means that any '}' should be escaped by a prior '}'. It is assumed that // the value will be surrounded by { and } by the caller after it has been validated -bool core_is_conn_opt_value_escaped( const char* value, size_t value_len ) +bool core_is_conn_opt_value_escaped( _In_ const char* value, _Inout_ size_t value_len ) { // if the value is already quoted, then only analyse the part inside the quotes and return it as // unquoted since we quote it when adding it to the connection string. @@ -552,7 +552,7 @@ bool core_is_conn_opt_value_escaped( const char* value, size_t value_len ) // core_is_authentication_option_valid // if the option for the authentication is valid, returns true. This returns false otherwise. -bool core_is_authentication_option_valid(const char* value, size_t value_len) +bool core_is_authentication_option_valid( _In_z_ const char* value, _In_ size_t value_len) { if (value_len <= 0) return false; @@ -569,8 +569,8 @@ bool core_is_authentication_option_valid(const char* value, size_t value_len) namespace { -connection_option const* get_connection_option( sqlsrv_conn* conn, SQLULEN key, - const connection_option conn_opts[] TSRMLS_DC ) +connection_option const* get_connection_option( sqlsrv_conn* conn, _In_ SQLULEN key, + _In_ const connection_option conn_opts[] TSRMLS_DC ) { for( int opt_idx = 0; conn_opts[ opt_idx ].conn_option_key != SQLSRV_CONN_OPTION_INVALID; ++opt_idx ) { @@ -589,9 +589,9 @@ connection_option const* get_connection_option( sqlsrv_conn* conn, SQLULEN key, // passed to the connection, and then break them out ourselves and either set attributes or put the // option in the connection string. -void build_connection_string_and_set_conn_attr( sqlsrv_conn* conn, const char* server, const char* uid, const char* pwd, - HashTable* options, const connection_option valid_conn_opts[], - void* driver,_Inout_ std::string& connection_string TSRMLS_DC ) +void build_connection_string_and_set_conn_attr( _Inout_ sqlsrv_conn* conn, _Inout_z_ const char* server, _Inout_opt_z_ const char* uid, _Inout_opt_z_ const char* pwd, + _Inout_opt_ HashTable* options, _In_ const connection_option valid_conn_opts[], + void* driver, _Inout_ std::string& connection_string TSRMLS_DC ) { bool mars_mentioned = false; connection_option const* conn_opt; @@ -682,7 +682,7 @@ void build_connection_string_and_set_conn_attr( sqlsrv_conn* conn, const char* s // get_server_version // Helper function which returns the version of the SQL Server we are connected to. -void get_server_version( sqlsrv_conn* conn, char** server_version, SQLSMALLINT& len TSRMLS_DC ) +void get_server_version( _Inout_ sqlsrv_conn* conn, _Outptr_result_buffer_(len) char** server_version, _Out_ SQLSMALLINT& len TSRMLS_DC ) { try { @@ -752,7 +752,7 @@ const char* get_processor_arch( void ) // Exception is thrown when the server version is either undetermined // or is invalid (< 2000). -void determine_server_version( sqlsrv_conn* conn TSRMLS_DC ) +void determine_server_version( _Inout_ sqlsrv_conn* conn TSRMLS_DC ) { SQLSMALLINT info_len; char p[ INFO_BUFFER_LEN ]; @@ -776,7 +776,7 @@ void determine_server_version( sqlsrv_conn* conn TSRMLS_DC ) conn->server_version = version_major; } -void common_conn_str_append_func( const char* odbc_name, const char* val, size_t val_len, std::string& conn_str TSRMLS_DC ) +void common_conn_str_append_func( _In_z_ const char* odbc_name, _In_reads_(val_len) const char* val, _Inout_ size_t val_len, _Inout_ std::string& conn_str TSRMLS_DC ) { // wrap a connection option in a quote. It is presumed that any character that need to be escaped will // be escaped, such as a closing }. @@ -795,7 +795,7 @@ void common_conn_str_append_func( const char* odbc_name, const char* val, size_t } // namespace // simply add the parsed value to the connection string -void conn_str_append_func::func( connection_option const* option, zval* value, sqlsrv_conn* /*conn*/, std::string& conn_str +void conn_str_append_func::func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Inout_ std::string& conn_str TSRMLS_DC ) { const char* val_str = Z_STRVAL_P( value ); @@ -815,7 +815,7 @@ void conn_null_func::func( connection_option const* /*option*/, zval* /*value*/, // Values = ("true" or "1") are treated as true values. Everything else is treated as false. // Returns 1 for true and 0 for false. -size_t core_str_zval_is_true( zval* value_z ) +size_t core_str_zval_is_true( _Inout_ zval* value_z ) { SQLSRV_ASSERT( Z_TYPE_P( value_z ) == IS_STRING, "core_str_zval_is_true: This function only accepts zval of type string." ); @@ -824,7 +824,7 @@ size_t core_str_zval_is_true( zval* value_z ) // strip any whitespace at the end (whitespace is the same value in ASCII and UTF-8) size_t last_char = val_len - 1; - while( isspace( value_in[ last_char ] )) { + while( isspace(( unsigned char )value_in[ last_char ] )) { value_in[ last_char ] = '\0'; val_len = last_char; --last_char; diff --git a/source/shared/core_init.cpp b/source/shared/core_init.cpp index 01d54468..724ada5f 100644 --- a/source/shared/core_init.cpp +++ b/source/shared/core_init.cpp @@ -35,7 +35,7 @@ OSVERSIONINFO g_osversion; // henv_cp - Environment handle for pooled connection. // henv_ncp - Environment handle for non-pooled connection. // err - Driver specific error handler which handles any errors during initialization. -void core_sqlsrv_minit( sqlsrv_context** henv_cp, sqlsrv_context** henv_ncp, error_callback err, const char* driver_func TSRMLS_DC ) +void core_sqlsrv_minit( _Outptr_ sqlsrv_context** henv_cp, _Inout_ sqlsrv_context** henv_ncp, _In_ error_callback err, _In_z_ const char* driver_func TSRMLS_DC ) { SQLSRV_STATIC_ASSERT( sizeof( sqlsrv_sqltype ) == sizeof( zend_long ) ); SQLSRV_STATIC_ASSERT( sizeof( sqlsrv_phptype ) == sizeof( zend_long )); @@ -142,7 +142,7 @@ void core_sqlsrv_minit( sqlsrv_context** henv_cp, sqlsrv_context** henv_ncp, err // Parameters: // henv_cp - Pooled environment handle. // henv_ncp - Non-pooled environment handle. -void core_sqlsrv_mshutdown( sqlsrv_context& henv_cp, sqlsrv_context& henv_ncp ) +void core_sqlsrv_mshutdown( _Inout_ sqlsrv_context& henv_cp, _Inout_ sqlsrv_context& henv_ncp ) { if( henv_ncp != SQL_NULL_HANDLE ) { @@ -162,7 +162,7 @@ void core_sqlsrv_mshutdown( sqlsrv_context& henv_cp, sqlsrv_context& henv_ncp ) // DllMain for the extension. #ifdef _WIN32 -BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID ) +BOOL WINAPI DllMain( _In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, LPVOID ) { switch( fdwReason ) { case DLL_PROCESS_ATTACH: diff --git a/source/shared/core_results.cpp b/source/shared/core_results.cpp index 73299952..42f73cdd 100644 --- a/source/shared/core_results.cpp +++ b/source/shared/core_results.cpp @@ -51,7 +51,7 @@ const int INITIAL_FIELD_STRING_LEN = 256; // base allocation size when retrie // return an integral type rounded up to a certain number template -T align_to( T number ) +T align_to( _In_ T number ) { DEBUG_SQLSRV_ASSERT( (number + align) > number, "Number to align overflowed" ); return ((number % align) == 0) ? number : (number + align - (number % align)); @@ -59,14 +59,14 @@ T align_to( T number ) // return a pointer address aligned to a certain address boundary template -T* align_to( T* ptr ) +T* align_to( _In_ T* ptr ) { size_t p_value = (size_t) ptr; return align_to( p_value ); } // set the nth bit of the bitstream starting at ptr -void set_bit( void* ptr, unsigned int bit ) +void set_bit( _In_ void* ptr, _In_ unsigned int bit ) { unsigned char* null_bits = reinterpret_cast( ptr ); null_bits += bit >> 3; @@ -74,7 +74,7 @@ void set_bit( void* ptr, unsigned int bit ) } // retrieve the nth bit from the bitstream starting at ptr -bool get_bit( void* ptr, unsigned int bit ) +bool get_bit( _In_ void* ptr, _In_ unsigned int bit ) { unsigned char* null_bits = reinterpret_cast( ptr ); null_bits += bit >> 3; @@ -82,13 +82,13 @@ bool get_bit( void* ptr, unsigned int bit ) } // read in LOB field during buffered result creation -SQLPOINTER read_lob_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_buffered_result_set::meta_data& meta, - zend_long mem_used TSRMLS_DC ); +SQLPOINTER read_lob_field( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ sqlsrv_buffered_result_set::meta_data& meta, + _In_ zend_long mem_used TSRMLS_DC ); // dtor for each row in the cache -void cache_row_dtor(zval* data); +void cache_row_dtor( _In_ zval* data ); -size_t get_float_precision(SQLLEN buffer_length, size_t unitsize) +size_t get_float_precision( _In_ SQLLEN buffer_length, _In_ size_t unitsize) { SQLSRV_ASSERT(unitsize != 0, "Invalid unit size!"); @@ -121,7 +121,7 @@ size_t get_float_precision(SQLLEN buffer_length, size_t unitsize) #ifndef _WIN32 // copy the number into a char string using the num_put facet template -SQLRETURN get_string_from_stream( Number number_data, std::basic_string &str_num, size_t precision, sqlsrv_error_auto_ptr& last_error) +SQLRETURN get_string_from_stream( _In_ Number number_data, _Out_writes_z_ std::basic_string &str_num, _In_ size_t precision, _Out_ sqlsrv_error_auto_ptr& last_error) { //std::locale loc( std::locale(""), new std::num_put ); // By default, SQL Server doesn't take user's locale into consideration std::locale loc; @@ -144,7 +144,7 @@ SQLRETURN get_string_from_stream( Number number_data, std::basic_string &s // copy the Char string into the output buffer - check first that it will fit template -SQLRETURN copy_buffer( _Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length, std::basic_string &str, sqlsrv_error_auto_ptr& last_error ) +SQLRETURN copy_buffer( _Out_writes_bytes_to_opt_(out_buffer_lenth, out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length, _In_reads_bytes_opt_(out_buffer_length) std::basic_string &str, _Out_ sqlsrv_error_auto_ptr& last_error ) { *out_buffer_length = str.size() * sizeof( Char ); // NULL terminator is provided subsequently @@ -163,7 +163,7 @@ SQLRETURN copy_buffer( _Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* o // There is an extra copy here, but given the size is short (usually <20 bytes) and the complications of // subclassing a new streambuf just to avoid the copy, it's easier to do the copy template -SQLRETURN number_to_string( Number* number_data, _Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length, sqlsrv_error_auto_ptr& last_error ) +SQLRETURN number_to_string( _In_ Number* number_data, _Out_writes_bytes_to_opt_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Inout_ SQLLEN* out_buffer_length, _Inout_ sqlsrv_error_auto_ptr& last_error ) { size_t precision = 0; @@ -239,7 +239,7 @@ SQLRETURN number_to_string( Number* number_data, _Out_ void* buffer, SQLLEN buff #ifndef _WIN32 -std::string getUTF8StringFromString( const SQLWCHAR* source ) +std::string getUTF8StringFromString( _In_z_ const SQLWCHAR* source ) { // convert to regular character string first char c_str[4] = ""; @@ -262,7 +262,7 @@ std::string getUTF8StringFromString( const SQLWCHAR* source ) } -std::string getUTF8StringFromString( const char* source ) +std::string getUTF8StringFromString( _In_z_ const char* source ) { return std::string( source ); } @@ -270,8 +270,8 @@ std::string getUTF8StringFromString( const char* source ) #endif // !_WIN32 template -SQLRETURN string_to_number( Char* string_data, SQLLEN str_len, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length, sqlsrv_error_auto_ptr& last_error ) +SQLRETURN string_to_number( _In_z_ Char* string_data, SQLLEN str_len, _Out_writes_bytes_(*out_buffer_length) void* buffer, SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length, _Inout_ sqlsrv_error_auto_ptr& last_error ) { Number* number_data = reinterpret_cast( buffer ); #ifdef _WIN32 @@ -333,13 +333,13 @@ struct row_dtor_closure { sqlsrv_buffered_result_set* results; BYTE* row_data; - row_dtor_closure( sqlsrv_buffered_result_set* st, BYTE* row ) : + row_dtor_closure( _In_ sqlsrv_buffered_result_set* st, _In_ BYTE* row ) : results( st ), row_data( row ) { } }; -sqlsrv_error* odbc_get_diag_rec( sqlsrv_stmt* odbc, SQLSMALLINT record_number ) +sqlsrv_error* odbc_get_diag_rec( _In_ sqlsrv_stmt* odbc, _In_ SQLSMALLINT record_number ) { SQLWCHAR wsql_state[ SQL_SQLSTATE_BUFSIZE ]; SQLWCHAR wnative_message[ SQL_MAX_MESSAGE_LENGTH + 1 ]; @@ -379,7 +379,7 @@ sqlsrv_error* odbc_get_diag_rec( sqlsrv_stmt* odbc, SQLSMALLINT record_number ) // base class result set -sqlsrv_result_set::sqlsrv_result_set( sqlsrv_stmt* stmt ) : +sqlsrv_result_set::sqlsrv_result_set( _In_ sqlsrv_stmt* stmt ) : odbc( stmt ) { } @@ -388,7 +388,7 @@ sqlsrv_result_set::sqlsrv_result_set( sqlsrv_stmt* stmt ) : // ODBC result set // This object simply wraps ODBC function calls -sqlsrv_odbc_result_set::sqlsrv_odbc_result_set( sqlsrv_stmt* stmt ) : +sqlsrv_odbc_result_set::sqlsrv_odbc_result_set( _In_ sqlsrv_stmt* stmt ) : sqlsrv_result_set( stmt ) { } @@ -397,30 +397,30 @@ sqlsrv_odbc_result_set::~sqlsrv_odbc_result_set( void ) { } -SQLRETURN sqlsrv_odbc_result_set::fetch( SQLSMALLINT orientation, SQLLEN offset TSRMLS_DC ) +SQLRETURN sqlsrv_odbc_result_set::fetch( _In_ SQLSMALLINT orientation, _In_ SQLLEN offset TSRMLS_DC ) { SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" ); return core::SQLFetchScroll( odbc, orientation, offset TSRMLS_CC ); } -SQLRETURN sqlsrv_odbc_result_set::get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type, - _Out_ SQLPOINTER buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length, - bool handle_warning TSRMLS_DC ) +SQLRETURN sqlsrv_odbc_result_set::get_data( _In_ SQLUSMALLINT field_index, _In_ SQLSMALLINT target_type, + _Out_writes_opt_(buffer_length) SQLPOINTER buffer, _In_ SQLLEN buffer_length, _Inout_ SQLLEN* out_buffer_length, + _In_ bool handle_warning TSRMLS_DC ) { SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" ); return core::SQLGetData( odbc, field_index, target_type, buffer, buffer_length, out_buffer_length, handle_warning TSRMLS_CC ); } -SQLRETURN sqlsrv_odbc_result_set::get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier, - _Out_ SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length, - _Out_ SQLSMALLINT* out_buffer_length TSRMLS_DC ) +SQLRETURN sqlsrv_odbc_result_set::get_diag_field( _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier, + _Inout_updates_(buffer_length) SQLPOINTER diag_info_buffer, _In_ SQLSMALLINT buffer_length, + _Inout_ SQLSMALLINT* out_buffer_length TSRMLS_DC ) { SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" ); return core::SQLGetDiagField( odbc, record_number, diag_identifier, diag_info_buffer, buffer_length, out_buffer_length TSRMLS_CC ); } -sqlsrv_error* sqlsrv_odbc_result_set::get_diag_rec( SQLSMALLINT record_number ) +sqlsrv_error* sqlsrv_odbc_result_set::get_diag_rec( _In_ SQLSMALLINT record_number ) { SQLSRV_ASSERT( odbc != NULL, "Invalid statement handle" ); return odbc_get_diag_rec( odbc, record_number ); @@ -436,7 +436,7 @@ SQLLEN sqlsrv_odbc_result_set::row_count( TSRMLS_D ) // Buffered result set // This class holds a result set in memory -sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( sqlsrv_stmt* stmt TSRMLS_DC ) : +sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) : sqlsrv_result_set( stmt ), cache(NULL), col_count(0), @@ -770,7 +770,7 @@ sqlsrv_buffered_result_set::~sqlsrv_buffered_result_set( void ) } } -SQLRETURN sqlsrv_buffered_result_set::fetch( SQLSMALLINT orientation, SQLLEN offset TSRMLS_DC ) +SQLRETURN sqlsrv_buffered_result_set::fetch( _Inout_ SQLSMALLINT orientation, _Inout_opt_ SQLLEN offset TSRMLS_DC ) { last_error = NULL; last_field_index = -1; @@ -823,8 +823,8 @@ SQLRETURN sqlsrv_buffered_result_set::fetch( SQLSMALLINT orientation, SQLLEN off return SQL_SUCCESS; } -SQLRETURN sqlsrv_buffered_result_set::get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type, - _Out_ SQLPOINTER buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length, +SQLRETURN sqlsrv_buffered_result_set::get_data( _In_ SQLUSMALLINT field_index, _In_ SQLSMALLINT target_type, + _Out_writes_bytes_opt_(buffer_length) SQLPOINTER buffer, _In_ SQLLEN buffer_length, _Inout_ SQLLEN* out_buffer_length, bool handle_warning TSRMLS_DC ) { last_error = NULL; @@ -857,9 +857,9 @@ SQLRETURN sqlsrv_buffered_result_set::get_data( SQLUSMALLINT field_index, SQLSMA out_buffer_length ); } -SQLRETURN sqlsrv_buffered_result_set::get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier, - _Out_ SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length, - _Out_ SQLSMALLINT* out_buffer_length TSRMLS_DC ) +SQLRETURN sqlsrv_buffered_result_set::get_diag_field( _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier, + _Inout_updates_(buffer_length) SQLPOINTER diag_info_buffer, _In_ SQLSMALLINT buffer_length, + _Inout_ SQLSMALLINT* out_buffer_length TSRMLS_DC ) { SQLSRV_ASSERT( record_number == 1, "Only record number 1 can be fetched by sqlsrv_buffered_result_set::get_diag_field" ); SQLSRV_ASSERT( diag_identifier == SQL_DIAG_SQLSTATE, @@ -889,7 +889,7 @@ unsigned char* sqlsrv_buffered_result_set::get_row( void ) return cl_ptr->row_data; } -sqlsrv_error* sqlsrv_buffered_result_set::get_diag_rec( SQLSMALLINT record_number ) +sqlsrv_error* sqlsrv_buffered_result_set::get_diag_rec( _In_ SQLSMALLINT record_number ) { // we only hold a single error if there is one, otherwise return the ODBC error(s) if( last_error == 0 ) { @@ -918,9 +918,9 @@ SQLLEN sqlsrv_buffered_result_set::row_count( TSRMLS_D ) // private functions template -SQLRETURN binary_to_string( SQLCHAR* field_data, SQLLEN& read_so_far, _Out_ void* buffer, - SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length, - sqlsrv_error_auto_ptr& out_error ) +SQLRETURN binary_to_string( _Inout_ SQLCHAR* field_data, _Inout_ SQLLEN& read_so_far, _Out_writes_z_(*out_buffer_length) void* buffer, + _In_ SQLLEN buffer_length, _Inout_ SQLLEN* out_buffer_length, + _Inout_ sqlsrv_error_auto_ptr& out_error ) { // hex characters for the conversion loop below static char hex_chars[] = "0123456789ABCDEF"; @@ -979,8 +979,8 @@ SQLRETURN binary_to_string( SQLCHAR* field_data, SQLLEN& read_so_far, _Out_ voi return r; } -SQLRETURN sqlsrv_buffered_result_set::binary_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ) +SQLRETURN sqlsrv_buffered_result_set::binary_to_system_string( _In_ SQLSMALLINT field_index, _Out_writes_z_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ) { SQLCHAR* row = get_row(); SQLCHAR* field_data = NULL; @@ -997,8 +997,8 @@ SQLRETURN sqlsrv_buffered_result_set::binary_to_system_string( SQLSMALLINT field return binary_to_string( field_data, read_so_far, buffer, buffer_length, out_buffer_length, last_error ); } -SQLRETURN sqlsrv_buffered_result_set::binary_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ) +SQLRETURN sqlsrv_buffered_result_set::binary_to_wide_string( _In_ SQLSMALLINT field_index, _Out_writes_z_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ) { SQLCHAR* row = get_row(); SQLCHAR* field_data = NULL; @@ -1016,8 +1016,8 @@ SQLRETURN sqlsrv_buffered_result_set::binary_to_wide_string( SQLSMALLINT field_i } -SQLRETURN sqlsrv_buffered_result_set::double_to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ) +SQLRETURN sqlsrv_buffered_result_set::double_to_long( _In_ SQLSMALLINT field_index, _Inout_updates_bytes_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ) { SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invalid conversion to long" ); SQLSRV_ASSERT( buffer_length >= sizeof(SQLLEN), "Buffer length must be able to find a long in " @@ -1045,8 +1045,8 @@ SQLRETURN sqlsrv_buffered_result_set::double_to_long( SQLSMALLINT field_index, _ return SQL_SUCCESS; } -SQLRETURN sqlsrv_buffered_result_set::double_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ) +SQLRETURN sqlsrv_buffered_result_set::double_to_system_string( _In_ SQLSMALLINT field_index, _Out_writes_bytes_to_opt_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ) { SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invalid conversion to system string" ); SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::double_to_system_string" ); @@ -1062,8 +1062,8 @@ SQLRETURN sqlsrv_buffered_result_set::double_to_system_string( SQLSMALLINT field return r; } -SQLRETURN sqlsrv_buffered_result_set::double_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ) +SQLRETURN sqlsrv_buffered_result_set::double_to_wide_string( _In_ SQLSMALLINT field_index, _Out_writes_bytes_to_opt_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ) { SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invalid conversion to wide string" ); SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::double_to_wide_string" ); @@ -1079,7 +1079,7 @@ SQLRETURN sqlsrv_buffered_result_set::double_to_wide_string( SQLSMALLINT field_i return r; } -SQLRETURN sqlsrv_buffered_result_set::long_to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, +SQLRETURN sqlsrv_buffered_result_set::long_to_double( _In_ SQLSMALLINT field_index, _Out_writes_bytes_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length ) { SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invalid conversion to long" ); @@ -1094,8 +1094,8 @@ SQLRETURN sqlsrv_buffered_result_set::long_to_double( SQLSMALLINT field_index, _ return SQL_SUCCESS; } -SQLRETURN sqlsrv_buffered_result_set::long_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ) +SQLRETURN sqlsrv_buffered_result_set::long_to_system_string( _In_ SQLSMALLINT field_index, _Out_writes_bytes_to_opt_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ) { SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invalid conversion to system string" ); SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::long_to_system_string" ); @@ -1111,8 +1111,8 @@ SQLRETURN sqlsrv_buffered_result_set::long_to_system_string( SQLSMALLINT field_i return r; } -SQLRETURN sqlsrv_buffered_result_set::long_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ) +SQLRETURN sqlsrv_buffered_result_set::long_to_wide_string( _In_ SQLSMALLINT field_index, _Out_writes_bytes_to_opt_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ) { SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invalid conversion to wide string" ); SQLSRV_ASSERT( buffer_length > 0, "Buffer length must be > 0 in sqlsrv_buffered_result_set::long_to_wide_string" ); @@ -1128,8 +1128,8 @@ SQLRETURN sqlsrv_buffered_result_set::long_to_wide_string( SQLSMALLINT field_ind return r; } -SQLRETURN sqlsrv_buffered_result_set::string_to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ) +SQLRETURN sqlsrv_buffered_result_set::string_to_double( _In_ SQLSMALLINT field_index, _Out_writes_bytes_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ) { SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_CHAR, "Invalid conversion from string to double" ); SQLSRV_ASSERT( buffer_length >= sizeof( double ), "Buffer needs to be big enough to hold a double" ); @@ -1140,8 +1140,8 @@ SQLRETURN sqlsrv_buffered_result_set::string_to_double( SQLSMALLINT field_index, return string_to_number( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error ); } -SQLRETURN sqlsrv_buffered_result_set::wstring_to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ) +SQLRETURN sqlsrv_buffered_result_set::wstring_to_double( _In_ SQLSMALLINT field_index, _Out_writes_bytes_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ) { SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_WCHAR, "Invalid conversion from wide string to double" ); SQLSRV_ASSERT( buffer_length >= sizeof( double ), "Buffer needs to be big enough to hold a double" ); @@ -1152,8 +1152,8 @@ SQLRETURN sqlsrv_buffered_result_set::wstring_to_double( SQLSMALLINT field_index return string_to_number( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error ); } -SQLRETURN sqlsrv_buffered_result_set::string_to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ) +SQLRETURN sqlsrv_buffered_result_set::string_to_long( _In_ SQLSMALLINT field_index, _Out_writes_bytes_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ) { SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_CHAR, "Invalid conversion from string to long" ); SQLSRV_ASSERT( buffer_length >= sizeof( LONG ), "Buffer needs to be big enough to hold a long" ); @@ -1164,8 +1164,8 @@ SQLRETURN sqlsrv_buffered_result_set::string_to_long( SQLSMALLINT field_index, _ return string_to_number( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error ); } -SQLRETURN sqlsrv_buffered_result_set::wstring_to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ) +SQLRETURN sqlsrv_buffered_result_set::wstring_to_long( _In_ SQLSMALLINT field_index, _Out_writes_bytes_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ) { SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_WCHAR, "Invalid conversion from wide string to long" ); SQLSRV_ASSERT( buffer_length >= sizeof( LONG ), "Buffer needs to be big enough to hold a long" ); @@ -1176,7 +1176,7 @@ SQLRETURN sqlsrv_buffered_result_set::wstring_to_long( SQLSMALLINT field_index, return string_to_number( string_data, meta[ field_index ].length, buffer, buffer_length, out_buffer_length, last_error ); } -SQLRETURN sqlsrv_buffered_result_set::system_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, +SQLRETURN sqlsrv_buffered_result_set::system_to_wide_string( _In_ SQLSMALLINT field_index, _Out_writes_z_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length ) { SQLSRV_ASSERT( last_error == 0, "Pending error for sqlsrv_buffered_results_set::system_to_wide_string" ); @@ -1276,7 +1276,7 @@ SQLRETURN sqlsrv_buffered_result_set::system_to_wide_string( SQLSMALLINT field_i return r; } -SQLRETURN sqlsrv_buffered_result_set::to_same_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, +SQLRETURN sqlsrv_buffered_result_set::to_same_string( _In_ SQLSMALLINT field_index, _Out_writes_bytes_to_opt_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length ) { SQLSRV_ASSERT( last_error == 0, "Pending error for sqlsrv_buffered_results_set::to_same_string" ); @@ -1346,8 +1346,8 @@ SQLRETURN sqlsrv_buffered_result_set::to_same_string( SQLSMALLINT field_index, _ return r; } -SQLRETURN sqlsrv_buffered_result_set::wide_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ) +SQLRETURN sqlsrv_buffered_result_set::wide_to_system_string( _In_ SQLSMALLINT field_index, _Inout_updates_bytes_to_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ) { SQLSRV_ASSERT( last_error == 0, "Pending error for sqlsrv_buffered_results_set::wide_to_system_string" ); @@ -1440,13 +1440,13 @@ SQLRETURN sqlsrv_buffered_result_set::wide_to_system_string( SQLSMALLINT field_i } -SQLRETURN sqlsrv_buffered_result_set::to_binary_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, +SQLRETURN sqlsrv_buffered_result_set::to_binary_string( _In_ SQLSMALLINT field_index, _Out_writes_bytes_to_opt_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length ) { return to_same_string( field_index, buffer, buffer_length, out_buffer_length ); } -SQLRETURN sqlsrv_buffered_result_set::to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, +SQLRETURN sqlsrv_buffered_result_set::to_long( _In_ SQLSMALLINT field_index, _Out_writes_bytes_to_opt_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length ) { SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_LONG, "Invalid conversion to long" ); @@ -1460,7 +1460,7 @@ SQLRETURN sqlsrv_buffered_result_set::to_long( SQLSMALLINT field_index, _Out_ vo return SQL_SUCCESS; } -SQLRETURN sqlsrv_buffered_result_set::to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, +SQLRETURN sqlsrv_buffered_result_set::to_double( _In_ SQLSMALLINT field_index, _Out_writes_bytes_to_opt_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length ) { SQLSRV_ASSERT( meta[ field_index ].c_type == SQL_C_DOUBLE, "Invalid conversion to double" ); @@ -1477,7 +1477,7 @@ SQLRETURN sqlsrv_buffered_result_set::to_double( SQLSMALLINT field_index, _Out_ namespace { // called for each row in the cache when the cache is destroyed in the destructor -void cache_row_dtor( zval* data ) +void cache_row_dtor( _In_ zval* data ) { row_dtor_closure* cl = reinterpret_cast( Z_PTR_P( data ) ); BYTE* row = cl->row_data; @@ -1497,8 +1497,8 @@ void cache_row_dtor( zval* data ) sqlsrv_free( cl ); } -SQLPOINTER read_lob_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_buffered_result_set::meta_data& meta, - zend_long mem_used TSRMLS_DC ) +SQLPOINTER read_lob_field( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ sqlsrv_buffered_result_set::meta_data& meta, + _In_ zend_long mem_used TSRMLS_DC ) { SQLSMALLINT extra = 0; SQLULEN* output_buffer_len = NULL; diff --git a/source/shared/core_sqlsrv.h b/source/shared/core_sqlsrv.h index 7ddcfa34..719c77c9 100644 --- a/source/shared/core_sqlsrv.h +++ b/source/shared/core_sqlsrv.h @@ -258,7 +258,7 @@ template struct sqlsrv_static_assert; template <> -struct sqlsrv_static_assert { static const int value = 1; }; +struct sqlsrv_static_assert { _In_ static const int value = 1; }; #define SQLSRV_STATIC_ASSERT( c ) (sqlsrv_static_assert<(c) != 0>() ) @@ -271,13 +271,13 @@ struct sqlsrv_static_assert { static const int value = 1; }; // severity - severity of the message: notice, warning, or error // msg - the message to log in a FormatMessage style formatting // print_args - args to the message -typedef void (*log_callback)( unsigned int severity TSRMLS_DC, const char* msg, va_list* print_args ); +typedef void (*log_callback)( _In_ unsigned int severity TSRMLS_DC, _In_ const char* msg, _In_opt_ va_list* print_args ); // each driver must register a log callback. This should be the first thing a driver does. -void core_sqlsrv_register_logger( log_callback ); +void core_sqlsrv_register_logger( _In_ log_callback ); // a simple wrapper around a PHP error logging function. -void write_to_log( unsigned int severity TSRMLS_DC, const char* msg, ... ); +void write_to_log( _In_ unsigned int severity TSRMLS_DC, _In_ const char* msg, ... ); // a macro to make it convenient to use the function. #define LOG( severity, msg, ...) write_to_log( severity TSRMLS_CC, msg, ## __VA_ARGS__ ) @@ -291,7 +291,7 @@ enum logging_severity { }; // Kill the PHP process and log the message to PHP -void die( const char* msg, ... ); +void die( _In_opt_ const char* msg, ... ); #define DIE( msg, ... ) { die( msg, ## __VA_ARGS__ ); } @@ -312,14 +312,14 @@ void die( const char* msg, ... ); // #define SQLSRV_MEM_DEBUG 1 #if defined( PHP_DEBUG ) && !defined( ZTS ) && defined( SQLSRV_MEM_DEBUG ) -inline void* sqlsrv_malloc_trace( size_t size, const char* file, int line ) +inline void* sqlsrv_malloc_trace( _In_ size_t size, _In_ const char* file, _In_ int line ) { void* ptr = emalloc( size ); LOG( SEV_NOTICE, "emalloc returned %4!08x!: %1!d! bytes at %2!s!:%3!d!", size, file, line, ptr ); return ptr; } -inline void* sqlsrv_malloc_trace( size_t element_count, size_t element_size, size_t extra, const char* file, int line ) +inline void* sqlsrv_malloc_trace( _In_ size_t element_count, _In_ size_t element_size, _In_ size_t extra, _In_ const char* file, _In_ int line ) { OACR_WARNING_SUPPRESS( ALLOC_SIZE_OVERFLOW_IN_ALLOC_WRAPPER, "Overflow verified below" ); @@ -341,14 +341,14 @@ inline void* sqlsrv_malloc_trace( size_t element_count, size_t element_size, siz return ptr; } -inline void* sqlsrv_realloc_trace( void* buffer, size_t size, const char* file, int line ) +inline void* sqlsrv_realloc_trace( void* buffer, _In_ size_t size, _In_ const char* file, _In_ int line ) { void* ptr = erealloc( original, size ); LOG( SEV_NOTICE, "erealloc returned %5!08x! from %4!08x!: %1!d! bytes at %2!s!:%3!d!", size, file, line, ptr, original ); return ptr; } -inline void sqlsrv_free_trace( void* ptr, const char* file, int line ) +inline void sqlsrv_free_trace( _Inout_ void* ptr, _In_ const char* file, _In_ int line ) { LOG( SEV_NOTICE, "efree %1!08x! at %2!s!:%3!d!", ptr, file, line ); efree( ptr ); @@ -361,12 +361,12 @@ inline void sqlsrv_free_trace( void* ptr, const char* file, int line ) #else -inline void* sqlsrv_malloc( size_t size ) +inline void* sqlsrv_malloc( _In_ size_t size ) { return emalloc( size ); } -inline void* sqlsrv_malloc( size_t element_count, size_t element_size, size_t extra ) +inline void* sqlsrv_malloc( _In_ size_t element_count, _In_ size_t element_size, _In_ size_t extra ) { OACR_WARNING_SUPPRESS( ALLOC_SIZE_OVERFLOW_IN_ALLOC_WRAPPER, "Overflow verified below" ); @@ -386,12 +386,12 @@ inline void* sqlsrv_malloc( size_t element_count, size_t element_size, size_t ex return emalloc( element_size * element_count + extra ); } -inline void* sqlsrv_realloc( void* buffer, size_t size ) +inline void* sqlsrv_realloc( _Inout_ void* buffer, _In_ size_t size ) { return erealloc( buffer, size ); } -inline void sqlsrv_free( void* ptr ) +inline void sqlsrv_free( _Inout_ void* ptr ) { efree( ptr ); } @@ -436,24 +436,24 @@ struct sqlsrv_allocator { inline sqlsrv_allocator( sqlsrv_allocator const& ) {} // address (doesn't work if the class defines operator&) - inline pointer address( reference r ) + inline pointer address( _In_ reference r ) { return &r; } - inline const_pointer address( const_reference r ) + inline const_pointer address( _In_ const_reference r ) { return &r; } // memory allocation/deallocation - inline pointer allocate( size_type cnt, + inline pointer allocate( _In_ size_type cnt, typename std::allocator::const_pointer = 0 ) { return reinterpret_cast( sqlsrv_malloc(cnt, sizeof (T), 0)); } - inline void deallocate( pointer p, size_type ) + inline void deallocate( _Inout_ pointer p, size_type ) { sqlsrv_free(p); } @@ -465,12 +465,12 @@ struct sqlsrv_allocator { } // object construction/destruction - inline void construct( pointer p, const T& t ) + inline void construct( _In_ pointer p, _In_ const T& t ) { new(p) T(t); } - inline void destroy(pointer p) + inline void destroy( _Inout_ pointer p ) { p->~T(); } @@ -481,7 +481,7 @@ struct sqlsrv_allocator { return true; } - inline bool operator!=( sqlsrv_allocator const& a ) + inline bool operator!=( _In_ sqlsrv_allocator const& a ) { return !operator==(a); } @@ -535,21 +535,21 @@ public: // there are a number of places where we allocate a block intended to be accessed as // an array of elements, so this operator allows us to treat the memory as such. - T& operator[]( int index ) const + T& operator[]( _In_ int index ) const { return _ptr[ index ]; } // there are a number of places where we allocate a block intended to be accessed as // an array of elements, so this operator allows us to treat the memory as such. - T& operator[]( unsigned int index ) const + T& operator[]( _In_ unsigned int index ) const { return _ptr[ index ]; } // there are a number of places where we allocate a block intended to be accessed as // an array of elements, so this operator allows us to treat the memory as such. - T& operator[]( long index ) const + T& operator[]( _In_ long index ) const { return _ptr[ index ]; } @@ -558,7 +558,7 @@ public: #ifdef __WIN64 // there are a number of places where we allocate a block intended to be accessed as // an array of elements, so this operator allows us to treat the memory as such. - T& operator[](std::size_t index) const + T& operator[]( _In_ std::size_t index ) const { return _ptr[index]; } @@ -566,7 +566,7 @@ public: // there are a number of places where we allocate a block intended to be accessed as // an array of elements, so this operator allows us to treat the memory as such. - T& operator[]( unsigned short index ) const + T& operator[]( _In_ unsigned short index ) const { return _ptr[ index ]; } @@ -593,12 +593,12 @@ public: protected: - sqlsrv_auto_ptr( T* ptr ) : + sqlsrv_auto_ptr( _In_opt_ T* ptr ) : _ptr( ptr ) { } - sqlsrv_auto_ptr( sqlsrv_auto_ptr& src ) + sqlsrv_auto_ptr( _Inout_opt_ sqlsrv_auto_ptr& src ) { if( _ptr ) { static_cast(this)->reset( src._ptr ); @@ -608,7 +608,7 @@ protected: // assign a new pointer to the auto_ptr. It will free the previous memory block // because ownership is deemed finished. - T* operator=( T* ptr ) + T* operator=( _In_opt_ T* ptr ) { static_cast( this )->reset( ptr ); @@ -634,25 +634,25 @@ public: { } - sqlsrv_malloc_auto_ptr( const sqlsrv_malloc_auto_ptr& src ) : + sqlsrv_malloc_auto_ptr( _Inout_opt_ const sqlsrv_malloc_auto_ptr& src ) : sqlsrv_auto_ptr >( src ) { } // free the original pointer and assign a new pointer. Use NULL to simply free the pointer. - void reset( T* ptr = NULL ) + void reset( _In_opt_ T* ptr = NULL ) { if( sqlsrv_auto_ptr >::_ptr ) sqlsrv_free( (void*) sqlsrv_auto_ptr >::_ptr ); sqlsrv_auto_ptr >::_ptr = ptr; } - T* operator=( T* ptr ) + T* operator=( _In_opt_ T* ptr ) { return sqlsrv_auto_ptr >::operator=( ptr ); } - void operator=( sqlsrv_malloc_auto_ptr& src ) + void operator=( _Inout_opt_ sqlsrv_malloc_auto_ptr& src ) { T* p = src.get(); src.transferred(); @@ -661,7 +661,7 @@ public: // DO NOT CALL sqlsrv_realloc with a sqlsrv_malloc_auto_ptr. Use the resize member function. // has the same parameter list as sqlsrv_realloc: new_size is the size in bytes of the newly allocated buffer - void resize( size_t new_size ) + void resize( _In_ size_t new_size ) { sqlsrv_auto_ptr >::_ptr = reinterpret_cast( sqlsrv_realloc( sqlsrv_auto_ptr >::_ptr, new_size )); } @@ -682,7 +682,7 @@ public: } // free the original pointer and assign a new pointer. Use NULL to simply free the pointer. - void reset( HashTable* ptr = NULL ) + void reset( _In_opt_ HashTable* ptr = NULL ) { if( _ptr ) { zend_hash_destroy( _ptr ); @@ -691,16 +691,16 @@ public: _ptr = ptr; } - HashTable* operator=( HashTable* ptr ) + HashTable* operator=( _In_opt_ HashTable* ptr ) { return sqlsrv_auto_ptr::operator=( ptr ); } private: - hash_auto_ptr( HashTable const& hash ); + hash_auto_ptr( _In_ HashTable const& hash ); - hash_auto_ptr( hash_auto_ptr const& hash ); + hash_auto_ptr( _In_ hash_auto_ptr const& hash ); }; @@ -717,14 +717,14 @@ public: } // free the original pointer and assign a new pointer. Use NULL to simply free the pointer. - void reset( zval* ptr = NULL ) + void reset( _In_opt_ zval* ptr = NULL ) { if( _ptr ) zval_ptr_dtor(_ptr ); _ptr = ptr; } - zval* operator=( zval* ptr ) + zval* operator=( _In_opt_ zval* ptr ) { return sqlsrv_auto_ptr::operator=( ptr ); } @@ -732,7 +732,7 @@ public: private: - zval_auto_ptr( const zval_auto_ptr& src ); + zval_auto_ptr( _In_ const zval_auto_ptr& src ); }; #pragma pop_macro( "max" ) @@ -767,7 +767,7 @@ struct sqlsrv_error : public sqlsrv_error_const { format = false; } - sqlsrv_error( SQLCHAR* sql_state, SQLCHAR* message, SQLINTEGER code, bool printf_format = false ) + sqlsrv_error( _In_ SQLCHAR* sql_state, _In_ SQLCHAR* message, _In_ SQLINTEGER code, _In_ bool printf_format = false ) { sqlstate = reinterpret_cast( sqlsrv_malloc( SQL_SQLSTATE_BUFSIZE )); native_message = reinterpret_cast( sqlsrv_malloc( SQL_MAX_MESSAGE_LENGTH + 1 )); @@ -777,7 +777,7 @@ struct sqlsrv_error : public sqlsrv_error_const { format = printf_format; } - sqlsrv_error( sqlsrv_error_const const& prototype ) + sqlsrv_error( _In_ sqlsrv_error_const const& prototype ) { sqlsrv_error( prototype.sqlstate, prototype.native_message, prototype.native_code, prototype.format ); } @@ -804,13 +804,13 @@ public: { } - sqlsrv_error_auto_ptr( sqlsrv_error_auto_ptr const& src ) : + sqlsrv_error_auto_ptr( _Inout_opt_ sqlsrv_error_auto_ptr const& src ) : sqlsrv_auto_ptr( (sqlsrv_error_auto_ptr&) src ) { } // free the original pointer and assign a new pointer. Use NULL to simply free the pointer. - void reset( sqlsrv_error* ptr = NULL ) + void reset( _In_opt_ sqlsrv_error* ptr = NULL ) { if( _ptr ) { _ptr->~sqlsrv_error(); @@ -819,14 +819,14 @@ public: _ptr = ptr; } - sqlsrv_error* operator=( sqlsrv_error* ptr ) + sqlsrv_error* operator=( _In_opt_ sqlsrv_error* ptr ) { return sqlsrv_auto_ptr::operator=( ptr ); } // unlike traditional assignment operators, the chained assignment of an auto_ptr doesn't make much // sense. Only the last one would have anything in it. - void operator=( sqlsrv_error_auto_ptr& src ) + void operator=( _Inout_opt_ sqlsrv_error_auto_ptr& src ) { sqlsrv_error* p = src.get(); src.transferred(); @@ -846,7 +846,7 @@ struct sqlsrv_conn; // a driver specific callback for processing errors. // ctx - the context holding the handles // sqlsrv_error_code - specific error code to return. -typedef bool (*error_callback)( sqlsrv_context& ctx, unsigned int sqlsrv_error_code, bool error TSRMLS_DC, va_list* print_args ); +typedef bool (*error_callback)( _Inout_ sqlsrv_context& ctx, _In_ unsigned int sqlsrv_error_code, _In_ bool error TSRMLS_DC, _In_opt_ va_list* print_args ); // sqlsrv_context // a context holds relevant information to be passed with a connection and statement objects. @@ -855,7 +855,7 @@ class sqlsrv_context { public: - sqlsrv_context( SQLSMALLINT type, error_callback e, void* drv, SQLSRV_ENCODING encoding = SQLSRV_ENCODING_INVALID ) : + sqlsrv_context( _In_opt_ SQLSMALLINT type, _In_ error_callback e, _In_opt_ void* drv, _In_ SQLSRV_ENCODING encoding = SQLSRV_ENCODING_INVALID ) : handle_( SQL_NULL_HANDLE ), handle_type_( type ), name_( NULL ), @@ -866,7 +866,7 @@ class sqlsrv_context { { } - sqlsrv_context( SQLHANDLE h, SQLSMALLINT t, error_callback e, void* drv, SQLSRV_ENCODING encoding = SQLSRV_ENCODING_INVALID ) : + sqlsrv_context( _In_ SQLHANDLE h, _In_opt_ SQLSMALLINT t, _In_ error_callback e, _In_opt_ void* drv, _In_ SQLSRV_ENCODING encoding = SQLSRV_ENCODING_INVALID ) : handle_( h ), handle_type_( t ), name_( NULL ), @@ -877,7 +877,7 @@ class sqlsrv_context { { } - sqlsrv_context( sqlsrv_context const& ctx ) : + sqlsrv_context( _In_ sqlsrv_context const& ctx ) : handle_( ctx.handle_ ), handle_type_( ctx.handle_type_ ), name_( ctx.name_ ), @@ -891,12 +891,12 @@ class sqlsrv_context { { } - void set_func( const char* f ) + void set_func( _In_z_ const char* f ) { name_ = f; } - void set_last_error( sqlsrv_error_auto_ptr& last_error ) + void set_last_error( _In_ sqlsrv_error_auto_ptr& last_error ) { last_error_ = last_error; } @@ -938,7 +938,7 @@ class sqlsrv_context { return driver_; } - void set_driver( void* driver ) + void set_driver( _In_ void* driver ) { this->driver_ = driver; } @@ -963,7 +963,7 @@ class sqlsrv_context { return encoding_; } - void set_encoding( SQLSRV_ENCODING e ) + void set_encoding( _In_ SQLSRV_ENCODING e ) { encoding_ = e; } @@ -988,7 +988,7 @@ struct sqlsrv_encoding { unsigned int code_page; bool not_for_connection; - sqlsrv_encoding( const char* iana, unsigned int code_page, bool not_for_conn = false ): + sqlsrv_encoding( _In_ const char* iana, _In_ unsigned int code_page, _In_ bool not_for_conn = false ): iana( iana ), iana_len( strlen( iana )), code_page( code_page ), not_for_connection( not_for_conn ) { } @@ -1003,15 +1003,15 @@ struct sqlsrv_encoding { extern OSVERSIONINFO g_osversion; // used to determine which OS we're running in extern HashTable* g_encodings; // encodings supported by this driver -void core_sqlsrv_minit( sqlsrv_context** henv_cp, sqlsrv_context** henv_ncp, error_callback err, const char* driver_func TSRMLS_DC ); -void core_sqlsrv_mshutdown( sqlsrv_context& henv_cp, sqlsrv_context& henv_ncp ); +void core_sqlsrv_minit( _Outptr_ sqlsrv_context** henv_cp, _Inout_ sqlsrv_context** henv_ncp, _In_ error_callback err, _In_z_ const char* driver_func TSRMLS_DC ); +void core_sqlsrv_mshutdown( _Inout_ sqlsrv_context& henv_cp, _Inout_ sqlsrv_context& henv_ncp ); // environment context used by sqlsrv_connect for when a connection error occurs. struct sqlsrv_henv { sqlsrv_context ctx; - sqlsrv_henv( SQLHANDLE handle, error_callback e, void* drv ) : + sqlsrv_henv( _In_ SQLHANDLE handle, _In_ error_callback e, _In_opt_ void* drv ) : ctx( handle, SQL_HANDLE_ENV, e, drv ) { } @@ -1052,7 +1052,7 @@ struct sqlsrv_conn : public sqlsrv_context { DRIVER_VERSION driver_version; // initialize with default values - sqlsrv_conn( SQLHANDLE h, error_callback e, void* drv, SQLSRV_ENCODING encoding TSRMLS_DC ) : + sqlsrv_conn( _In_ SQLHANDLE h, _In_ error_callback e, _In_opt_ void* drv, _In_ SQLSRV_ENCODING encoding TSRMLS_DC ) : sqlsrv_context( h, SQL_HANDLE_DBC, e, drv, encoding ) { server_version = SERVER_VERSION_UNKNOWN; @@ -1172,7 +1172,7 @@ struct connection_option { // simply add the parsed value to the connection string struct conn_str_append_func { - static void func( connection_option const* option, zval* value, sqlsrv_conn* /*conn*/, std::string& conn_str TSRMLS_DC ); + static void func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Inout_ std::string& conn_str TSRMLS_DC ); }; struct conn_null_func { @@ -1182,24 +1182,24 @@ struct conn_null_func { }; // factory to create a connection (since they are subclassed to instantiate statements) -typedef sqlsrv_conn* (*driver_conn_factory)( SQLHANDLE h, error_callback e, void* drv TSRMLS_DC ); +typedef sqlsrv_conn* (*driver_conn_factory)( _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* drv TSRMLS_DC ); // *** connection functions *** -sqlsrv_conn* core_sqlsrv_connect( sqlsrv_context& henv_cp, sqlsrv_context& henv_ncp, driver_conn_factory conn_factory, - const char* server, const char* uid, const char* pwd, - HashTable* options_ht, error_callback err, const connection_option driver_conn_opt_list[], - void* driver, const char* driver_func TSRMLS_DC ); -void core_sqlsrv_close( sqlsrv_conn* conn TSRMLS_DC ); -void core_sqlsrv_prepare( sqlsrv_stmt* stmt, const char* sql, SQLLEN sql_len TSRMLS_DC ); -void core_sqlsrv_begin_transaction( sqlsrv_conn* conn TSRMLS_DC ); -void core_sqlsrv_commit( sqlsrv_conn* conn TSRMLS_DC ); -void core_sqlsrv_rollback( sqlsrv_conn* conn TSRMLS_DC ); -void core_sqlsrv_get_server_info( sqlsrv_conn* conn, _Out_ zval* server_info TSRMLS_DC ); -void core_sqlsrv_get_server_version( sqlsrv_conn* conn, _Out_ zval *server_version TSRMLS_DC ); -void core_sqlsrv_get_client_info( sqlsrv_conn* conn, _Out_ zval *client_info TSRMLS_DC ); -bool core_is_conn_opt_value_escaped( const char* value, size_t value_len ); -size_t core_str_zval_is_true( zval* str_zval ); -bool core_is_authentication_option_valid( const char* value, size_t value_len ); +sqlsrv_conn* core_sqlsrv_connect( _In_ sqlsrv_context& henv_cp, _In_ sqlsrv_context& henv_ncp, _In_ driver_conn_factory conn_factory, + _Inout_z_ const char* server, _Inout_opt_z_ const char* uid, _Inout_opt_z_ const char* pwd, + _Inout_opt_ HashTable* options_ht, _In_ error_callback err, _In_ const connection_option valid_conn_opts[], + _In_ void* driver, _In_z_ const char* driver_func TSRMLS_DC ); +void core_sqlsrv_close( _Inout_opt_ sqlsrv_conn* conn TSRMLS_DC ); +void core_sqlsrv_prepare( _Inout_ sqlsrv_stmt* stmt, _In_reads_bytes_(sql_len) const char* sql, _In_ SQLLEN sql_len TSRMLS_DC ); +void core_sqlsrv_begin_transaction( _Inout_ sqlsrv_conn* conn TSRMLS_DC ); +void core_sqlsrv_commit( _Inout_ sqlsrv_conn* conn TSRMLS_DC ); +void core_sqlsrv_rollback( _Inout_ sqlsrv_conn* conn TSRMLS_DC ); +void core_sqlsrv_get_server_info( _Inout_ sqlsrv_conn* conn, _Out_ zval* server_info TSRMLS_DC ); +void core_sqlsrv_get_server_version( _Inout_ sqlsrv_conn* conn, _Inout_ zval *server_version TSRMLS_DC ); +void core_sqlsrv_get_client_info( _Inout_ sqlsrv_conn* conn, _Out_ zval *client_info TSRMLS_DC ); +bool core_is_conn_opt_value_escaped( _In_ const char* value, _Inout_ size_t value_len ); +size_t core_str_zval_is_true( _Inout_ zval* str_zval ); +bool core_is_authentication_option_valid( _In_z_ const char* value, _In_ size_t value_len ); //********************************************************************************************************************************* // Statement @@ -1207,22 +1207,22 @@ bool core_is_authentication_option_valid( const char* value, size_t value_len ); struct stmt_option_functor { - virtual void operator()( sqlsrv_stmt* /*stmt*/, stmt_option const* /*opt*/, zval* /*value_z*/ TSRMLS_DC ); + virtual void operator()( _Inout_ sqlsrv_stmt* /*stmt*/, stmt_option const* /*opt*/, _In_ zval* /*value_z*/ TSRMLS_DC ); }; struct stmt_option_query_timeout : public stmt_option_functor { - virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* opt, zval* value_z TSRMLS_DC ); + virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* opt, _In_ zval* value_z TSRMLS_DC ); }; struct stmt_option_send_at_exec : public stmt_option_functor { - virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* opt, zval* value_z TSRMLS_DC ); + virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* opt, _In_ zval* value_z TSRMLS_DC ); }; struct stmt_option_buffered_query_limit : public stmt_option_functor { - virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* opt, zval* value_z TSRMLS_DC ); + virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* opt, _In_ zval* value_z TSRMLS_DC ); }; // used to hold the table for statment options @@ -1244,7 +1244,7 @@ struct sqlsrv_stream { SQLSMALLINT sql_type; sqlsrv_stmt* stmt; - sqlsrv_stream( zval* str_z, SQLSRV_ENCODING enc ) : + sqlsrv_stream( _In_opt_ zval* str_z, _In_ SQLSRV_ENCODING enc ) : stream_z( str_z ), encoding( enc ), field_index( 0 ), sql_type( SQL_UNKNOWN_TYPE ), stmt( NULL ) { } @@ -1274,13 +1274,13 @@ struct sqlsrv_output_param { bool is_bool; // string output param constructor - sqlsrv_output_param( zval* p_z, SQLSRV_ENCODING enc, int num, SQLUINTEGER buffer_len ) : + sqlsrv_output_param( _In_ zval* p_z, _In_ SQLSRV_ENCODING enc, _In_ int num, _In_ SQLUINTEGER buffer_len ) : param_z( p_z ), encoding( enc ), param_num( num ), original_buffer_len( buffer_len ), is_bool( false ) { } // every other type output parameter constructor - sqlsrv_output_param( zval* p_z, int num, bool is_bool ) : + sqlsrv_output_param( _In_ zval* p_z, _In_ int num, _In_ bool is_bool ) : param_z( p_z ), encoding( SQLSRV_ENCODING_INVALID ), param_num( num ), @@ -1329,11 +1329,11 @@ struct sqlsrv_stmt : public sqlsrv_context { zval col_cache; // Used by get_field_as_string not to call SQLColAttribute() after every fetch. zval active_stream; // the currently active stream reading data from the database - sqlsrv_stmt( sqlsrv_conn* c, SQLHANDLE handle, error_callback e, void* drv TSRMLS_DC ); + sqlsrv_stmt( _In_ sqlsrv_conn* c, _In_ SQLHANDLE handle, _In_ error_callback e, _In_opt_ void* drv TSRMLS_DC ); virtual ~sqlsrv_stmt( void ); // driver specific conversion rules from a SQL Server/ODBC type to one of the SQLSRV_PHPTYPE_* constants - virtual sqlsrv_phptype sql_type_to_php_type( SQLINTEGER sql_type, SQLUINTEGER size, bool prefer_string_to_stream ) = 0; + virtual sqlsrv_phptype sql_type_to_php_type( _In_ SQLINTEGER sql_type, _In_ SQLUINTEGER size, _In_ bool prefer_string_to_stream ) = 0; }; @@ -1377,27 +1377,27 @@ const size_t SQLSRV_CURSOR_BUFFERED = 0xfffffffeUL; // arbitrary number that doe typedef sqlsrv_stmt* (*driver_stmt_factory)( sqlsrv_conn* conn, SQLHANDLE h, error_callback e, void* drv TSRMLS_DC ); // *** statement functions *** -sqlsrv_stmt* core_sqlsrv_create_stmt( sqlsrv_conn* conn, driver_stmt_factory stmt_factory, HashTable* options_ht, - const stmt_option valid_stmt_opts[], error_callback const err, void* driver TSRMLS_DC ); -void core_sqlsrv_bind_param( sqlsrv_stmt* stmt, SQLUSMALLINT param_num, SQLSMALLINT direction, zval* param_z, - SQLSRV_PHPTYPE php_out_type, SQLSRV_ENCODING encoding, SQLSMALLINT sql_type, SQLULEN column_size, - SQLSMALLINT decimal_digits TSRMLS_DC ); -SQLRETURN core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql = NULL, int sql_len = 0 ); -field_meta_data* core_sqlsrv_field_metadata( sqlsrv_stmt* stmt, SQLSMALLINT colno TSRMLS_DC ); -bool core_sqlsrv_fetch( sqlsrv_stmt* stmt, SQLSMALLINT fetch_orientation, SQLULEN fetch_offset TSRMLS_DC ); -void core_sqlsrv_get_field(sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype sqlsrv_phptype, bool prefer_string, - _Out_ void*& field_value, _Out_ SQLLEN* field_length, bool cache_field, +sqlsrv_stmt* core_sqlsrv_create_stmt( _Inout_ sqlsrv_conn* conn, _In_ driver_stmt_factory stmt_factory, _In_opt_ HashTable* options_ht, + _In_opt_ const stmt_option valid_stmt_opts[], _In_ error_callback const err, _In_opt_ void* driver TSRMLS_DC ); +void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_num, _In_ SQLSMALLINT direction, _Inout_ zval* param_z, + _In_ SQLSRV_PHPTYPE php_out_type, _In_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, + _Inout_ SQLSMALLINT decimal_digits TSRMLS_DC ); +SQLRETURN core_sqlsrv_execute( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_reads_bytes_(sql_len) const char* sql = NULL, _In_ int sql_len = 0 ); +field_meta_data* core_sqlsrv_field_metadata( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno TSRMLS_DC ); +bool core_sqlsrv_fetch( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT fetch_orientation, _In_ SQLULEN fetch_offset TSRMLS_DC ); +void core_sqlsrv_get_field( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ sqlsrv_phptype sqlsrv_phptype, _In_ bool prefer_string, + _Outref_result_bytebuffer_maybenull_(*field_length) void*& field_value, _Inout_ SQLLEN* field_length, _In_ bool cache_field, _Out_ SQLSRV_PHPTYPE *sqlsrv_php_type_out TSRMLS_DC); -bool core_sqlsrv_has_any_result( sqlsrv_stmt* stmt TSRMLS_DC ); -void core_sqlsrv_next_result( sqlsrv_stmt* stmt TSRMLS_DC, bool finalize_output_params = true, bool throw_on_errors = true ); -void core_sqlsrv_post_param( sqlsrv_stmt* stmt, zend_ulong paramno, zval* param_z TSRMLS_DC ); -void core_sqlsrv_set_scrollable( sqlsrv_stmt* stmt, unsigned long cursor_type TSRMLS_DC ); -void core_sqlsrv_set_query_timeout( sqlsrv_stmt* stmt, long timeout TSRMLS_DC ); -void core_sqlsrv_set_query_timeout( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC ); -void core_sqlsrv_set_send_at_exec( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC ); -bool core_sqlsrv_send_stream_packet( sqlsrv_stmt* stmt TSRMLS_DC ); -void core_sqlsrv_set_buffered_query_limit( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC ); -void core_sqlsrv_set_buffered_query_limit( sqlsrv_stmt* stmt, SQLLEN limit TSRMLS_DC ); +bool core_sqlsrv_has_any_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ); +void core_sqlsrv_next_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_ bool finalize_output_params = true, _In_ bool throw_on_errors = true ); +void core_sqlsrv_post_param( _Inout_ sqlsrv_stmt* stmt, _In_ zend_ulong paramno, zval* param_z TSRMLS_DC ); +void core_sqlsrv_set_scrollable( _Inout_ sqlsrv_stmt* stmt, _In_ unsigned long cursor_type TSRMLS_DC ); +void core_sqlsrv_set_query_timeout( _Inout_ sqlsrv_stmt* stmt, _In_ long timeout TSRMLS_DC ); +void core_sqlsrv_set_query_timeout( _Inout_ sqlsrv_stmt* stmt, _Inout_ zval* value_z TSRMLS_DC ); +void core_sqlsrv_set_send_at_exec( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z TSRMLS_DC ); +bool core_sqlsrv_send_stream_packet( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ); +void core_sqlsrv_set_buffered_query_limit( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z TSRMLS_DC ); +void core_sqlsrv_set_buffered_query_limit( _Inout_ sqlsrv_stmt* stmt, _In_ SQLLEN limit TSRMLS_DC ); //********************************************************************************************************************************* @@ -1415,35 +1415,35 @@ struct sqlsrv_result_set { sqlsrv_stmt* odbc; - explicit sqlsrv_result_set( sqlsrv_stmt* ); + explicit sqlsrv_result_set( _In_ sqlsrv_stmt* ); virtual ~sqlsrv_result_set( void ) { } virtual bool cached( int field_index ) = 0; - virtual SQLRETURN fetch( SQLSMALLINT fetch_orientation, SQLLEN fetch_offset TSRMLS_DC ) = 0; - virtual SQLRETURN get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type, - _Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length, + virtual SQLRETURN fetch( _Inout_ SQLSMALLINT fetch_orientation, _Inout_opt_ SQLLEN fetch_offset TSRMLS_DC ) = 0; + virtual SQLRETURN get_data( _In_ SQLUSMALLINT field_index, _In_ SQLSMALLINT target_type, + _Out_writes_bytes_opt_(buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Inout_ SQLLEN* out_buffer_length, bool handle_warning TSRMLS_DC )= 0; - virtual SQLRETURN get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier, - _Out_ SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length, - _Out_ SQLSMALLINT* out_buffer_length TSRMLS_DC ) = 0; - virtual sqlsrv_error* get_diag_rec( SQLSMALLINT record_number ) = 0; + virtual SQLRETURN get_diag_field( _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier, + _Inout_updates_(buffer_length) SQLPOINTER diag_info_buffer, _In_ SQLSMALLINT buffer_length, + _Inout_ SQLSMALLINT* out_buffer_length TSRMLS_DC ) = 0; + virtual sqlsrv_error* get_diag_rec( _In_ SQLSMALLINT record_number ) = 0; virtual SQLLEN row_count( TSRMLS_D ) = 0; }; struct sqlsrv_odbc_result_set : public sqlsrv_result_set { - explicit sqlsrv_odbc_result_set( sqlsrv_stmt* ); + explicit sqlsrv_odbc_result_set( _In_ sqlsrv_stmt* ); virtual ~sqlsrv_odbc_result_set( void ); virtual bool cached( int field_index ) { return false; } - virtual SQLRETURN fetch( SQLSMALLINT fetch_orientation, SQLLEN fetch_offset TSRMLS_DC ); - virtual SQLRETURN get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type, - _Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length, - bool handle_warning TSRMLS_DC ); - virtual SQLRETURN get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier, - _Out_ SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length, - _Out_ SQLSMALLINT* out_buffer_length TSRMLS_DC ); - virtual sqlsrv_error* get_diag_rec( SQLSMALLINT record_number ); + virtual SQLRETURN fetch( _In_ SQLSMALLINT fetch_orientation, _In_ SQLLEN fetch_offset TSRMLS_DC ); + virtual SQLRETURN get_data( _In_ SQLUSMALLINT field_index, _In_ SQLSMALLINT target_type, + _Out_writes_opt_(buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Inout_ SQLLEN* out_buffer_length, + _In_ bool handle_warning TSRMLS_DC ); + virtual SQLRETURN get_diag_field( _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier, + _Inout_updates_(buffer_length) SQLPOINTER diag_info_buffer, _In_ SQLSMALLINT buffer_length, + _Inout_ SQLSMALLINT* out_buffer_length TSRMLS_DC ); + virtual sqlsrv_error* get_diag_rec( _In_ SQLSMALLINT record_number ); virtual SQLLEN row_count( TSRMLS_D ); private: @@ -1470,18 +1470,18 @@ struct sqlsrv_buffered_result_set : public sqlsrv_result_set { static const zend_long BUFFERED_QUERY_LIMIT_DEFAULT = 10240; // measured in KB static const zend_long BUFFERED_QUERY_LIMIT_INVALID = 0; - explicit sqlsrv_buffered_result_set( sqlsrv_stmt* odbc TSRMLS_DC ); + explicit sqlsrv_buffered_result_set( _Inout_ sqlsrv_stmt* odbc TSRMLS_DC ); virtual ~sqlsrv_buffered_result_set( void ); virtual bool cached( int field_index ) { return true; } - virtual SQLRETURN fetch( SQLSMALLINT fetch_orientation, SQLLEN fetch_offset TSRMLS_DC ); - virtual SQLRETURN get_data( SQLUSMALLINT field_index, SQLSMALLINT target_type, - _Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length, + virtual SQLRETURN fetch( _Inout_ SQLSMALLINT fetch_orientation, _Inout_opt_ SQLLEN fetch_offset TSRMLS_DC ); + virtual SQLRETURN get_data( _In_ SQLUSMALLINT field_index, _In_ SQLSMALLINT target_type, + _Out_writes_bytes_opt_(buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Inout_ SQLLEN* out_buffer_length, bool handle_warning TSRMLS_DC ); - virtual SQLRETURN get_diag_field( SQLSMALLINT record_number, SQLSMALLINT diag_identifier, - _Out_ SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length, - _Out_ SQLSMALLINT* out_buffer_length TSRMLS_DC ); - virtual sqlsrv_error* get_diag_rec( SQLSMALLINT record_number ); + virtual SQLRETURN get_diag_field( _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier, + _Inout_updates_(buffer_length) SQLPOINTER diag_info_buffer, _In_ SQLSMALLINT buffer_length, + _Inout_ SQLSMALLINT* out_buffer_length TSRMLS_DC ); + virtual sqlsrv_error* get_diag_rec( _In_ SQLSMALLINT record_number ); virtual SQLLEN row_count( TSRMLS_D ); // buffered result set specific @@ -1511,55 +1511,55 @@ struct sqlsrv_buffered_result_set : public sqlsrv_result_set { sqlsrv_malloc_auto_ptr temp_string; // temp buffer to hold a converted field while in use SQLLEN temp_length; // number of bytes in the temp conversion buffer - typedef SQLRETURN (sqlsrv_buffered_result_set::*conv_fn)( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ); + typedef SQLRETURN (sqlsrv_buffered_result_set::*conv_fn)( _In_ SQLSMALLINT field_index, _Out_writes_z_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ); typedef std::map< SQLINTEGER, std::map< SQLINTEGER, conv_fn > > conv_matrix_t; // two dimentional sparse matrix that holds the [from][to] functions that do conversions static conv_matrix_t conv_matrix; // string conversion functions - SQLRETURN binary_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, + SQLRETURN binary_to_wide_string( _In_ SQLSMALLINT field_index, _Out_writes_z_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ); + SQLRETURN binary_to_system_string( _In_ SQLSMALLINT field_index, _Out_writes_z_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ); + SQLRETURN system_to_wide_string( _In_ SQLSMALLINT field_index, _Out_writes_z_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length ); - SQLRETURN binary_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ); - SQLRETURN system_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ); - SQLRETURN to_binary_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, + SQLRETURN to_binary_string( _In_ SQLSMALLINT field_index, _Out_writes_bytes_to_opt_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length ); - SQLRETURN to_same_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, + SQLRETURN to_same_string( _In_ SQLSMALLINT field_index, _Out_writes_bytes_to_opt_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length ); - SQLRETURN wide_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ); + SQLRETURN wide_to_system_string( _In_ SQLSMALLINT field_index, _Inout_updates_bytes_to_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ); // long conversion functions - SQLRETURN to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length ); - SQLRETURN long_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ); - SQLRETURN long_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ); - SQLRETURN long_to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, + SQLRETURN to_long( _In_ SQLSMALLINT field_index, _Out_writes_bytes_to_opt_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length ); + SQLRETURN long_to_system_string( _In_ SQLSMALLINT field_index, _Out_writes_bytes_to_opt_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ); + SQLRETURN long_to_wide_string( _In_ SQLSMALLINT field_index, _Out_writes_bytes_to_opt_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ); + SQLRETURN long_to_double( _In_ SQLSMALLINT field_index, _Out_writes_bytes_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length ); // double conversion functions - SQLRETURN to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length ); - SQLRETURN double_to_system_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ); - SQLRETURN double_to_wide_string( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ); - SQLRETURN double_to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ); + SQLRETURN to_double( _In_ SQLSMALLINT field_index, _Out_writes_bytes_to_opt_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length ); + SQLRETURN double_to_system_string( _In_ SQLSMALLINT field_index, _Out_writes_bytes_to_opt_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ); + SQLRETURN double_to_wide_string( _In_ SQLSMALLINT field_index, _Out_writes_bytes_to_opt_(buffer_length, *out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ); + SQLRETURN double_to_long( _In_ SQLSMALLINT field_index, _Inout_updates_bytes_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ); // string to number conversion functions // Future: See if these can be converted directly to template member functions - SQLRETURN string_to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ); - SQLRETURN string_to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ); - SQLRETURN wstring_to_double( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ); - SQLRETURN wstring_to_long( SQLSMALLINT field_index, _Out_ void* buffer, SQLLEN buffer_length, - _Out_ SQLLEN* out_buffer_length ); + SQLRETURN string_to_double( _In_ SQLSMALLINT field_index, _Out_writes_bytes_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ); + SQLRETURN string_to_long( _In_ SQLSMALLINT field_index, _Out_writes_bytes_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ); + SQLRETURN wstring_to_double( _In_ SQLSMALLINT field_index, _Out_writes_bytes_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ); + SQLRETURN wstring_to_long( _In_ SQLSMALLINT field_index, _Out_writes_bytes_(*out_buffer_length) void* buffer, _In_ SQLLEN buffer_length, + _Inout_ SQLLEN* out_buffer_length ); // utility functions for conversions unsigned char* get_row( void ); @@ -1577,11 +1577,11 @@ struct sqlsrv_buffered_result_set : public sqlsrv_result_set { #define MEMCHECK_SILENT 1 // utility functions shared by multiple callers across files -bool convert_string_from_utf16_inplace( SQLSRV_ENCODING encoding, char** string, SQLLEN& len); -bool convert_zval_string_from_utf16(SQLSRV_ENCODING encoding, zval* value_z, SQLLEN& len); -bool validate_string(char* string, SQLLEN& len); -bool convert_string_from_utf16( SQLSRV_ENCODING encoding, const SQLWCHAR* inString, SQLINTEGER cchInLen, char** outString, SQLLEN& cchOutLen ); -SQLWCHAR* utf16_string_from_mbcs_string( SQLSRV_ENCODING php_encoding, const char* mbcs_string, unsigned int mbcs_len, _Out_ unsigned int* utf16_len ); +bool convert_string_from_utf16_inplace( _In_ SQLSRV_ENCODING encoding, _Inout_updates_z_(len) char** string, _Inout_ SQLLEN& len); +bool convert_zval_string_from_utf16( _In_ SQLSRV_ENCODING encoding, _Inout_ zval* value_z, _Inout_ SQLLEN& len); +bool validate_string( _In_ char* string, _In_ SQLLEN& len); +bool convert_string_from_utf16( _In_ SQLSRV_ENCODING encoding, _In_reads_bytes_(cchInLen) const SQLWCHAR* inString, _In_ SQLINTEGER cchInLen, _Inout_updates_bytes_(cchOutLen) char** outString, _Out_ SQLLEN& cchOutLen ); +SQLWCHAR* utf16_string_from_mbcs_string( _In_ SQLSRV_ENCODING php_encoding, _In_reads_bytes_(mbcs_len) const char* mbcs_string, _In_ unsigned int mbcs_len, _Out_ unsigned int* utf16_len ); //********************************************************************************************************************************* // Error handling routines and Predefined Errors @@ -1659,24 +1659,24 @@ enum error_handling_flags { // 2/code) driver specific error code // 3/message) driver specific error message // The fetch type determines if the indices are numeric, associative, or both. -bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, _Out_ sqlsrv_error_auto_ptr& error, - logging_severity severity TSRMLS_DC ); +bool core_sqlsrv_get_odbc_error( _Inout_ sqlsrv_context& ctx, _In_ int record_number, _Inout_ sqlsrv_error_auto_ptr& error, + _In_ logging_severity severity TSRMLS_DC ); // format and return a driver specfic error -void core_sqlsrv_format_driver_error( sqlsrv_context& ctx, sqlsrv_error_const const* custom_error, - sqlsrv_error_auto_ptr& formatted_error, logging_severity severity TSRMLS_DC, va_list* args ); +void core_sqlsrv_format_driver_error( _In_ sqlsrv_context& ctx, _In_ sqlsrv_error_const const* custom_error, + _Out_ sqlsrv_error_auto_ptr& formatted_error, _In_ logging_severity severity TSRMLS_DC, _In_opt_ va_list* args ); // return the message for the HRESULT returned by GetLastError. Some driver errors use this to // return the Windows error, e.g, when a UTF-8 <-> UTF-16 conversion fails. -const char* get_last_error_message( DWORD last_error = 0 ); +const char* get_last_error_message( _Inout_ DWORD last_error = 0 ); // a wrapper around FormatMessage that can take variadic args rather than a a va_arg pointer -DWORD core_sqlsrv_format_message( char* output_buffer, unsigned output_len, const char* format, ... ); +DWORD core_sqlsrv_format_message( _Out_ char* output_buffer, _In_ unsigned output_len, _In_opt_ const char* format, ... ); // convenience functions that overload either a reference or a pointer so we can use // either in the CHECK_* functions. -inline bool call_error_handler( sqlsrv_context& ctx, unsigned long sqlsrv_error_code TSRMLS_DC, bool warning, ... ) +inline bool call_error_handler( _Inout_ sqlsrv_context& ctx, _In_ unsigned long sqlsrv_error_code TSRMLS_DC, _In_ bool warning, ... ) { va_list print_params; va_start( print_params, warning ); @@ -1685,7 +1685,7 @@ inline bool call_error_handler( sqlsrv_context& ctx, unsigned long sqlsrv_error_ return ignored; } -inline bool call_error_handler( sqlsrv_context* ctx, unsigned long sqlsrv_error_code TSRMLS_DC, bool warning, ... ) +inline bool call_error_handler( _Inout_ sqlsrv_context* ctx, _In_ unsigned long sqlsrv_error_code TSRMLS_DC, _In_ bool warning, ... ) { va_list print_params; va_start( print_params, warning ); @@ -1713,7 +1713,7 @@ inline bool call_error_handler( sqlsrv_context* ctx, unsigned long sqlsrv_error_ #endif // check to see if the sqlstate is 01004, truncated field retrieved. Used for retrieving large fields. -inline bool is_truncated_warning( SQLCHAR* state ) +inline bool is_truncated_warning( _In_ SQLCHAR* state ) { #if defined(ZEND_DEBUG) if( state == NULL || strlen( reinterpret_cast( state )) != 5 ) { \ @@ -1798,7 +1798,7 @@ namespace core { } }; - inline void check_for_mars_error( sqlsrv_stmt* stmt, SQLRETURN r TSRMLS_DC ) + inline void check_for_mars_error( _Inout_ sqlsrv_stmt* stmt, _In_ SQLRETURN r TSRMLS_DC ) { // We check for the 'connection busy' error caused by having MultipleActiveResultSets off // and return a more helpful message prepended to the ODBC errors if that error occurs @@ -1830,9 +1830,9 @@ namespace core { // These functions take the sqlsrv_context type. However, since the error handling code can alter // the context to hold the error, they are not passed as const. - inline SQLRETURN SQLGetDiagField( sqlsrv_context* ctx, SQLSMALLINT record_number, SQLSMALLINT diag_identifier, - _Out_ SQLPOINTER diag_info_buffer, SQLSMALLINT buffer_length, - _Out_ SQLSMALLINT* out_buffer_length TSRMLS_DC ) + inline SQLRETURN SQLGetDiagField( _Inout_ sqlsrv_context* ctx, _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier, + _Out_writes_opt_(buffer_length) SQLPOINTER diag_info_buffer, _In_ SQLSMALLINT buffer_length, + _Out_opt_ SQLSMALLINT* out_buffer_length TSRMLS_DC ) { SQLRETURN r = ::SQLGetDiagField( ctx->handle_type(), ctx->handle(), record_number, diag_identifier, diag_info_buffer, buffer_length, out_buffer_length ); @@ -1844,8 +1844,8 @@ namespace core { return r; } - inline void SQLAllocHandle( SQLSMALLINT HandleType, sqlsrv_context& InputHandle, - _Out_writes_(1) SQLHANDLE* OutputHandlePtr TSRMLS_DC ) + inline void SQLAllocHandle( _In_ SQLSMALLINT HandleType, _Inout_ sqlsrv_context& InputHandle, + _Out_ SQLHANDLE* OutputHandlePtr TSRMLS_DC ) { SQLRETURN r; r = ::SQLAllocHandle( HandleType, InputHandle.handle(), OutputHandlePtr ); @@ -1854,16 +1854,16 @@ namespace core { } } - inline void SQLBindParameter( sqlsrv_stmt* stmt, - SQLUSMALLINT ParameterNumber, - SQLSMALLINT InputOutputType, - SQLSMALLINT ValueType, - SQLSMALLINT ParameterType, - SQLULEN ColumnSize, - SQLSMALLINT DecimalDigits, - _Inout_ SQLPOINTER ParameterValuePtr, - SQLLEN BufferLength, - _Inout_ SQLLEN * StrLen_Or_IndPtr + inline void SQLBindParameter( _Inout_ sqlsrv_stmt* stmt, + _In_ SQLUSMALLINT ParameterNumber, + _In_ SQLSMALLINT InputOutputType, + _In_ SQLSMALLINT ValueType, + _In_ SQLSMALLINT ParameterType, + _In_ SQLULEN ColumnSize, + _In_ SQLSMALLINT DecimalDigits, + _Inout_opt_ SQLPOINTER ParameterValuePtr, + _Inout_ SQLLEN BufferLength, + _Inout_ SQLLEN * StrLen_Or_IndPtr TSRMLS_DC ) { SQLRETURN r; @@ -1876,9 +1876,9 @@ namespace core { } - inline void SQLColAttribute( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, SQLUSMALLINT field_identifier, - _Out_ SQLPOINTER field_type_char, SQLSMALLINT buffer_length, - _Out_ SQLSMALLINT* out_buffer_length, _Out_ SQLLEN* field_type_num TSRMLS_DC ) + inline void SQLColAttribute( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ SQLUSMALLINT field_identifier, + _Out_writes_bytes_opt_(buffer_length) SQLPOINTER field_type_char, _In_ SQLSMALLINT buffer_length, + _Out_opt_ SQLSMALLINT* out_buffer_length, _Out_opt_ SQLLEN* field_type_num TSRMLS_DC ) { SQLRETURN r = ::SQLColAttribute( stmt->handle(), field_index, field_identifier, field_type_char, buffer_length, out_buffer_length, field_type_num ); @@ -1888,9 +1888,9 @@ namespace core { } } - inline void SQLColAttributeW( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, SQLUSMALLINT field_identifier, - _Out_ SQLPOINTER field_type_char, SQLSMALLINT buffer_length, - _Out_ SQLSMALLINT* out_buffer_length, _Out_ SQLLEN* field_type_num TSRMLS_DC ) + inline void SQLColAttributeW( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ SQLUSMALLINT field_identifier, + _Out_writes_bytes_opt_(buffer_length) SQLPOINTER field_type_char, _In_ SQLSMALLINT buffer_length, + _Out_opt_ SQLSMALLINT* out_buffer_length, _Out_opt_ SQLLEN* field_type_num TSRMLS_DC ) { SQLRETURN r = ::SQLColAttributeW( stmt->handle(), field_index, field_identifier, field_type_char, buffer_length, out_buffer_length, field_type_num ); @@ -1900,9 +1900,9 @@ namespace core { } } - inline void SQLDescribeCol( sqlsrv_stmt* stmt, SQLSMALLINT colno, _Out_ SQLCHAR* col_name, SQLSMALLINT col_name_length, - _Out_ SQLSMALLINT* col_name_length_out, SQLSMALLINT* data_type, _Out_ SQLULEN* col_size, - _Out_ SQLSMALLINT* decimal_digits, _Out_ SQLSMALLINT* nullable TSRMLS_DC ) + inline void SQLDescribeCol( sqlsrv_stmt* stmt, SQLSMALLINT colno, _Out_writes_opt_(col_name_length) SQLCHAR* col_name, SQLSMALLINT col_name_length, + _Out_opt_ SQLSMALLINT* col_name_length_out, _Out_opt_ SQLSMALLINT* data_type, _Out_opt_ SQLULEN* col_size, + _Out_opt_ SQLSMALLINT* decimal_digits, _Out_opt_ SQLSMALLINT* nullable TSRMLS_DC ) { SQLRETURN r; r = ::SQLDescribeCol( stmt->handle(), colno, col_name, col_name_length, col_name_length_out, @@ -1913,9 +1913,9 @@ namespace core { } } - inline void SQLDescribeColW( sqlsrv_stmt* stmt, SQLSMALLINT colno, _Out_ SQLWCHAR* col_name, SQLSMALLINT col_name_length, - _Out_ SQLSMALLINT* col_name_length_out, SQLSMALLINT* data_type, _Out_ SQLULEN* col_size, - _Out_ SQLSMALLINT* decimal_digits, _Out_ SQLSMALLINT* nullable TSRMLS_DC ) + inline void SQLDescribeColW( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno, _Out_writes_opt_(col_name_length) SQLWCHAR* col_name, _In_ SQLSMALLINT col_name_length, + _Out_opt_ SQLSMALLINT* col_name_length_out, _Out_opt_ SQLSMALLINT* data_type, _Out_opt_ SQLULEN* col_size, + _Out_opt_ SQLSMALLINT* decimal_digits, _Out_opt_ SQLSMALLINT* nullable TSRMLS_DC ) { SQLRETURN r; r = ::SQLDescribeColW( stmt->handle(), colno, col_name, col_name_length, col_name_length_out, @@ -1926,7 +1926,7 @@ namespace core { } } - inline void SQLEndTran( SQLSMALLINT handleType, sqlsrv_conn* conn, SQLSMALLINT completionType TSRMLS_DC ) + inline void SQLEndTran( _In_ SQLSMALLINT handleType, _Inout_ sqlsrv_conn* conn, _In_ SQLSMALLINT completionType TSRMLS_DC ) { SQLRETURN r = ::SQLEndTran( handleType, conn->handle(), completionType ); @@ -1936,7 +1936,7 @@ namespace core { } // SQLExecDirect returns the status code since it returns either SQL_NEED_DATA or SQL_NO_DATA besides just errors/success - inline SQLRETURN SQLExecDirect( sqlsrv_stmt* stmt, char* sql TSRMLS_DC ) + inline SQLRETURN SQLExecDirect( _Inout_ sqlsrv_stmt* stmt, _In_ char* sql TSRMLS_DC ) { SQLRETURN r = ::SQLExecDirect( stmt->handle(), reinterpret_cast( sql ), SQL_NTS ); @@ -1949,7 +1949,7 @@ namespace core { return r; } - inline SQLRETURN SQLExecDirectW( sqlsrv_stmt* stmt, SQLWCHAR* wsql TSRMLS_DC ) + inline SQLRETURN SQLExecDirectW( _Inout_ sqlsrv_stmt* stmt, _In_ SQLWCHAR* wsql TSRMLS_DC ) { SQLRETURN r; r = ::SQLExecDirectW( stmt->handle(), reinterpret_cast( wsql ), SQL_NTS ); @@ -1963,7 +1963,7 @@ namespace core { } // SQLExecute returns the status code since it returns either SQL_NEED_DATA or SQL_NO_DATA besides just errors/success - inline SQLRETURN SQLExecute( sqlsrv_stmt* stmt TSRMLS_DC ) + inline SQLRETURN SQLExecute( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) { SQLRETURN r; r = ::SQLExecute( stmt->handle() ); @@ -1977,7 +1977,7 @@ namespace core { return r; } - inline SQLRETURN SQLFetchScroll( sqlsrv_stmt* stmt, SQLSMALLINT fetch_orientation, SQLLEN fetch_offset TSRMLS_DC ) + inline SQLRETURN SQLFetchScroll( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT fetch_orientation, _In_ SQLLEN fetch_offset TSRMLS_DC ) { SQLRETURN r = ::SQLFetchScroll( stmt->handle(), fetch_orientation, fetch_offset ); @@ -1989,16 +1989,16 @@ namespace core { // wrap SQLFreeHandle and report any errors, but don't actually signal an error to the calling routine - inline void SQLFreeHandle( sqlsrv_context& ctx TSRMLS_DC ) + inline void SQLFreeHandle( _Inout_ sqlsrv_context& ctx TSRMLS_DC ) { SQLRETURN r; r = ::SQLFreeHandle( ctx.handle_type(), ctx.handle() ); CHECK_SQL_ERROR_OR_WARNING( r, ctx ) {} } - inline SQLRETURN SQLGetData( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, SQLSMALLINT target_type, - _Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length, - bool handle_warning TSRMLS_DC ) + inline SQLRETURN SQLGetData( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ SQLSMALLINT target_type, + _Out_writes_opt_(buffer_length) void* buffer, _In_ SQLLEN buffer_length, _Out_opt_ SQLLEN* out_buffer_length, + _In_ bool handle_warning TSRMLS_DC ) { SQLRETURN r = ::SQLGetData( stmt->handle(), field_index, target_type, buffer, buffer_length, out_buffer_length ); @@ -2019,8 +2019,8 @@ namespace core { } - inline void SQLGetInfo( sqlsrv_conn* conn, SQLUSMALLINT info_type, _Out_ SQLPOINTER info_value, SQLSMALLINT buffer_len, - _Out_ SQLSMALLINT* str_len TSRMLS_DC ) + inline void SQLGetInfo( _Inout_ sqlsrv_conn* conn, _In_ SQLUSMALLINT info_type, _Out_writes_bytes_opt_(buffer_len) SQLPOINTER info_value, _In_ SQLSMALLINT buffer_len, + _Out_opt_ SQLSMALLINT* str_len TSRMLS_DC ) { SQLRETURN r; r = ::SQLGetInfo( conn->handle(), info_type, info_value, buffer_len, str_len ); @@ -2031,7 +2031,7 @@ namespace core { } - inline void SQLGetTypeInfo( sqlsrv_stmt* stmt, SQLUSMALLINT data_type TSRMLS_DC ) + inline void SQLGetTypeInfo( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT data_type TSRMLS_DC ) { SQLRETURN r; r = ::SQLGetTypeInfo( stmt->handle(), data_type ); @@ -2043,7 +2043,7 @@ namespace core { // SQLMoreResults returns the status code since it returns SQL_NO_DATA when there is no more data in a result set. - inline SQLRETURN SQLMoreResults( sqlsrv_stmt* stmt TSRMLS_DC ) + inline SQLRETURN SQLMoreResults( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) { SQLRETURN r = ::SQLMoreResults( stmt->handle() ); @@ -2054,7 +2054,7 @@ namespace core { return r; } - inline SQLSMALLINT SQLNumResultCols( sqlsrv_stmt* stmt TSRMLS_DC ) + inline SQLSMALLINT SQLNumResultCols( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) { SQLRETURN r; SQLSMALLINT num_cols; @@ -2069,7 +2069,7 @@ namespace core { // SQLParamData returns the status code since it returns either SQL_NEED_DATA or SQL_NO_DATA when there are more // parameters or when the parameters are all processed. - inline SQLRETURN SQLParamData( sqlsrv_stmt* stmt, _Out_ SQLPOINTER* value_ptr_ptr TSRMLS_DC ) + inline SQLRETURN SQLParamData( _Inout_ sqlsrv_stmt* stmt, _Out_opt_ SQLPOINTER* value_ptr_ptr TSRMLS_DC ) { SQLRETURN r; r = ::SQLParamData( stmt->handle(), value_ptr_ptr ); @@ -2079,7 +2079,7 @@ namespace core { return r; } - inline void SQLPrepareW( sqlsrv_stmt* stmt, SQLWCHAR * sql, SQLINTEGER sql_len TSRMLS_DC ) + inline void SQLPrepareW( _Inout_ sqlsrv_stmt* stmt, _In_reads_(sql_len) SQLWCHAR * sql, _In_ SQLINTEGER sql_len TSRMLS_DC ) { SQLRETURN r; r = ::SQLPrepareW( stmt->handle(), sql, sql_len ); @@ -2089,7 +2089,7 @@ namespace core { } - inline void SQLPutData( sqlsrv_stmt* stmt, SQLPOINTER data_ptr, SQLLEN strlen_or_ind TSRMLS_DC ) + inline void SQLPutData( _Inout_ sqlsrv_stmt* stmt, _In_reads_(strlen_or_ind) SQLPOINTER data_ptr, _In_ SQLLEN strlen_or_ind TSRMLS_DC ) { SQLRETURN r; r = ::SQLPutData( stmt->handle(), data_ptr, strlen_or_ind ); @@ -2099,7 +2099,7 @@ namespace core { } - inline SQLLEN SQLRowCount( sqlsrv_stmt* stmt TSRMLS_DC ) + inline SQLLEN SQLRowCount( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) { SQLRETURN r; SQLLEN rows_affected; @@ -2126,7 +2126,7 @@ namespace core { } - inline void SQLSetConnectAttr( sqlsrv_context& ctx, SQLINTEGER attr, SQLPOINTER value_ptr, SQLINTEGER str_len TSRMLS_DC ) + inline void SQLSetConnectAttr( _Inout_ sqlsrv_context& ctx, _In_ SQLINTEGER attr, _In_reads_bytes_opt_(str_len) SQLPOINTER value_ptr, _In_ SQLINTEGER str_len TSRMLS_DC ) { SQLRETURN r; r = ::SQLSetConnectAttr( ctx.handle(), attr, value_ptr, str_len ); @@ -2137,7 +2137,7 @@ namespace core { } - inline void SQLSetEnvAttr( sqlsrv_context& ctx, SQLINTEGER attr, SQLPOINTER value_ptr, SQLINTEGER str_len TSRMLS_DC ) + inline void SQLSetEnvAttr( _Inout_ sqlsrv_context& ctx, _In_ SQLINTEGER attr, _In_reads_bytes_opt_(str_len) SQLPOINTER value_ptr, _In_ SQLINTEGER str_len TSRMLS_DC ) { SQLRETURN r; r = ::SQLSetEnvAttr( ctx.handle(), attr, value_ptr, str_len ); @@ -2146,7 +2146,7 @@ namespace core { } } - inline void SQLSetConnectAttr( sqlsrv_conn* conn, SQLINTEGER attribute, SQLPOINTER value_ptr, SQLINTEGER value_len TSRMLS_DC ) + inline void SQLSetConnectAttr( _Inout_ sqlsrv_conn* conn, _In_ SQLINTEGER attribute, _In_reads_bytes_opt_(value_len) SQLPOINTER value_ptr, _In_ SQLINTEGER value_len TSRMLS_DC ) { SQLRETURN r = ::SQLSetConnectAttr( conn->handle(), attribute, value_ptr, value_len ); @@ -2155,7 +2155,7 @@ namespace core { } } - inline void SQLSetStmtAttr( sqlsrv_stmt* stmt, SQLINTEGER attr, SQLPOINTER value_ptr, SQLINTEGER str_len TSRMLS_DC ) + inline void SQLSetStmtAttr( _Inout_ sqlsrv_stmt* stmt, _In_ SQLINTEGER attr, _In_reads_(str_len) SQLPOINTER value_ptr, _In_ SQLINTEGER str_len TSRMLS_DC ) { SQLRETURN r; r = ::SQLSetStmtAttr( stmt->handle(), attr, value_ptr, str_len ); @@ -2172,7 +2172,7 @@ namespace core { // wrapper for ZVAL_STRINGL macro. ZVAL_STRINGL always allocates memory when initialzing new string from char string // so allocated memory inside of value_z should be released before assigning it to the new string - inline void sqlsrv_zval_stringl(zval* value_z, const char* str, const std::size_t str_len) + inline void sqlsrv_zval_stringl( _Inout_ zval* value_z, _In_reads_(str_len) const char* str, _In_ const std::size_t str_len) { if (Z_TYPE_P(value_z) == IS_STRING && Z_STR_P(value_z) != NULL) { zend_string* temp_zstr = zend_string_init(str, str_len, 0); @@ -2193,7 +2193,7 @@ namespace core { // If there is a zend function in the source that isn't found here, it is because it returns void and there is no error // that can be thrown from it. - inline void sqlsrv_add_index_zval( sqlsrv_context& ctx, zval* array, zend_ulong index, zval* value TSRMLS_DC) + inline void sqlsrv_add_index_zval( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array, _In_ zend_ulong index, _In_ zval* value TSRMLS_DC) { int zr = ::add_index_zval( array, index, value ); CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { @@ -2201,7 +2201,7 @@ namespace core { } } - inline void sqlsrv_add_next_index_zval( sqlsrv_context& ctx, zval* array, zval* value TSRMLS_DC) + inline void sqlsrv_add_next_index_zval( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array, _In_ zval* value TSRMLS_DC) { int zr = ::add_next_index_zval( array, value ); CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { @@ -2209,7 +2209,7 @@ namespace core { } } - inline void sqlsrv_add_assoc_null( sqlsrv_context& ctx, zval* array_z, const char* key TSRMLS_DC ) + inline void sqlsrv_add_assoc_null( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array_z, _In_ const char* key TSRMLS_DC ) { int zr = ::add_assoc_null( array_z, key ); CHECK_ZEND_ERROR (zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { @@ -2217,7 +2217,7 @@ namespace core { } } - inline void sqlsrv_add_assoc_long( sqlsrv_context& ctx, zval* array_z, const char* key, zend_long val TSRMLS_DC ) + inline void sqlsrv_add_assoc_long( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array_z, _In_ const char* key, _In_ zend_long val TSRMLS_DC ) { int zr = ::add_assoc_long( array_z, key, val ); CHECK_ZEND_ERROR (zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { @@ -2225,7 +2225,7 @@ namespace core { } } - inline void sqlsrv_add_assoc_string( sqlsrv_context& ctx, zval* array_z, const char* key, char* val, bool duplicate TSRMLS_DC ) + inline void sqlsrv_add_assoc_string( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array_z, _In_ const char* key, _Inout_z_ char* val, _In_ bool duplicate TSRMLS_DC ) { int zr = ::add_assoc_string(array_z, key, val); CHECK_ZEND_ERROR (zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { @@ -2236,7 +2236,7 @@ namespace core { } } - inline void sqlsrv_array_init( sqlsrv_context& ctx, _Out_ zval* new_array TSRMLS_DC) + inline void sqlsrv_array_init( _Inout_ sqlsrv_context& ctx, _Out_ zval* new_array TSRMLS_DC) { int zr = ::array_init(new_array); CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { @@ -2244,7 +2244,7 @@ namespace core { } } - inline void sqlsrv_php_stream_from_zval_no_verify( sqlsrv_context& ctx, php_stream*& stream, zval* stream_z TSRMLS_DC ) + inline void sqlsrv_php_stream_from_zval_no_verify( _Inout_ sqlsrv_context& ctx, _Outref_result_maybenull_ php_stream*& stream, _In_opt_ zval* stream_z TSRMLS_DC ) { // this duplicates the macro php_stream_from_zval_no_verify, which we can't use because it has an assignment php_stream_from_zval_no_verify( stream, stream_z ); @@ -2253,7 +2253,7 @@ namespace core { } } - inline void sqlsrv_zend_hash_get_current_data(sqlsrv_context& ctx, HashTable* ht, _Out_ zval*& output_data TSRMLS_DC) + inline void sqlsrv_zend_hash_get_current_data( _In_ sqlsrv_context& ctx, _In_ HashTable* ht, _Outref_result_maybenull_ zval*& output_data TSRMLS_DC) { int zr = (output_data = ::zend_hash_get_current_data(ht)) != NULL ? SUCCESS : FAILURE; CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { @@ -2261,7 +2261,7 @@ namespace core { } } - inline void sqlsrv_zend_hash_get_current_data_ptr(sqlsrv_context& ctx, HashTable* ht, _Out_ void*& output_data TSRMLS_DC) + inline void sqlsrv_zend_hash_get_current_data_ptr( _Inout_ sqlsrv_context& ctx, _In_ HashTable* ht, _Outref_result_maybenull_ void*& output_data TSRMLS_DC) { int zr = (output_data = ::zend_hash_get_current_data_ptr(ht)) != NULL ? SUCCESS : FAILURE; CHECK_ZEND_ERROR(zr, ctx, SQLSRV_ERROR_ZEND_HASH) { @@ -2269,7 +2269,7 @@ namespace core { } } - inline void sqlsrv_zend_hash_index_del( sqlsrv_context& ctx, HashTable* ht, zend_ulong index TSRMLS_DC ) + inline void sqlsrv_zend_hash_index_del( _Inout_ sqlsrv_context& ctx, _Inout_ HashTable* ht, _In_ zend_ulong index TSRMLS_DC ) { int zr = ::zend_hash_index_del( ht, index ); CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { @@ -2277,7 +2277,7 @@ namespace core { } } - inline void sqlsrv_zend_hash_index_update( sqlsrv_context& ctx, HashTable* ht, zend_ulong index, zval* data_z TSRMLS_DC ) + inline void sqlsrv_zend_hash_index_update( _Inout_ sqlsrv_context& ctx, _Inout_ HashTable* ht, _In_ zend_ulong index, _In_ zval* data_z TSRMLS_DC ) { int zr = (data_z = ::zend_hash_index_update(ht, index, data_z)) != NULL ? SUCCESS : FAILURE; CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { @@ -2285,7 +2285,7 @@ namespace core { } } - inline void sqlsrv_zend_hash_index_update_ptr(sqlsrv_context& ctx, HashTable* ht, zend_ulong index, void* pData TSRMLS_DC) + inline void sqlsrv_zend_hash_index_update_ptr( _Inout_ sqlsrv_context& ctx, _Inout_ HashTable* ht, _In_ zend_ulong index, _In_ void* pData TSRMLS_DC) { int zr = (pData = ::zend_hash_index_update_ptr(ht, index, pData)) != NULL ? SUCCESS : FAILURE; CHECK_ZEND_ERROR(zr, ctx, SQLSRV_ERROR_ZEND_HASH) { @@ -2294,7 +2294,7 @@ namespace core { } - inline void sqlsrv_zend_hash_index_update_mem(sqlsrv_context& ctx, HashTable* ht, zend_ulong index, void* pData, std::size_t size TSRMLS_DC) + inline void sqlsrv_zend_hash_index_update_mem( _Inout_ sqlsrv_context& ctx, _Inout_ HashTable* ht, _In_ zend_ulong index, _In_reads_bytes_(size) void* pData, _In_ std::size_t size TSRMLS_DC) { int zr = (pData = ::zend_hash_index_update_mem(ht, index, pData, size)) != NULL ? SUCCESS : FAILURE; CHECK_ZEND_ERROR(zr, ctx, SQLSRV_ERROR_ZEND_HASH) { @@ -2302,7 +2302,7 @@ namespace core { } } - inline void sqlsrv_zend_hash_next_index_insert( sqlsrv_context& ctx, HashTable* ht, zval* data TSRMLS_DC ) + inline void sqlsrv_zend_hash_next_index_insert( _Inout_ sqlsrv_context& ctx, _Inout_ HashTable* ht, _In_ zval* data TSRMLS_DC ) { int zr = (data = ::zend_hash_next_index_insert(ht, data)) != NULL ? SUCCESS : FAILURE; CHECK_ZEND_ERROR( zr, ctx, SQLSRV_ERROR_ZEND_HASH ) { @@ -2310,7 +2310,7 @@ namespace core { } } - inline void sqlsrv_zend_hash_next_index_insert_mem(sqlsrv_context& ctx, HashTable* ht, void* data, uint data_size TSRMLS_DC) + inline void sqlsrv_zend_hash_next_index_insert_mem( _Inout_ sqlsrv_context& ctx, _In_ HashTable* ht, _In_reads_bytes_(data_size) void* data, _In_ uint data_size TSRMLS_DC) { int zr = (data = ::zend_hash_next_index_insert_mem(ht, data, data_size)) != NULL ? SUCCESS : FAILURE; CHECK_ZEND_ERROR(zr, ctx, SQLSRV_ERROR_ZEND_HASH) { @@ -2318,7 +2318,7 @@ namespace core { } } - inline void sqlsrv_zend_hash_next_index_insert_ptr(sqlsrv_context& ctx, HashTable* ht, void* data TSRMLS_DC) + inline void sqlsrv_zend_hash_next_index_insert_ptr( _Inout_ sqlsrv_context& ctx, _Inout_ HashTable* ht, _In_ void* data TSRMLS_DC) { int zr = (data = ::zend_hash_next_index_insert_ptr(ht, data)) != NULL ? SUCCESS : FAILURE; CHECK_ZEND_ERROR(zr, ctx, SQLSRV_ERROR_ZEND_HASH) { @@ -2326,20 +2326,20 @@ namespace core { } } - inline void sqlsrv_zend_hash_init(sqlsrv_context& ctx, HashTable* ht, uint32_t initial_size, - dtor_func_t dtor_fn, zend_bool persistent TSRMLS_DC ) + inline void sqlsrv_zend_hash_init(sqlsrv_context& ctx, _Inout_ HashTable* ht, _Inout_ uint32_t initial_size, + _In_ dtor_func_t dtor_fn, _In_ zend_bool persistent TSRMLS_DC ) { ::zend_hash_init(ht, initial_size, NULL, dtor_fn, persistent); } template -sqlsrv_stmt* allocate_stmt( sqlsrv_conn* conn, SQLHANDLE h, error_callback e, void* driver TSRMLS_DC ) +sqlsrv_stmt* allocate_stmt( _In_ sqlsrv_conn* conn, _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* driver TSRMLS_DC ) { return new ( sqlsrv_malloc( sizeof( Statement ))) Statement( conn, h, e, driver TSRMLS_CC ); } template -sqlsrv_conn* allocate_conn( SQLHANDLE h, error_callback e, void* driver TSRMLS_DC ) +sqlsrv_conn* allocate_conn( _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* driver TSRMLS_DC ) { return new ( sqlsrv_malloc( sizeof( Connection ))) Connection( h, e, driver TSRMLS_CC ); } @@ -2350,7 +2350,7 @@ sqlsrv_conn* allocate_conn( SQLHANDLE h, error_callback e, void* driver TSRMLS_D template struct str_conn_attr_func { - static void func( connection_option const* /*option*/, zval* value, sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) + static void func( connection_option const* /*option*/, zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) { try { core::SQLSetConnectAttr( conn, Attr, reinterpret_cast( Z_STRVAL_P( value )), diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index 49114d92..54c44fe5 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -29,7 +29,7 @@ struct field_cache { SQLLEN len; sqlsrv_phptype type; - field_cache( void* field_value, SQLLEN field_len, sqlsrv_phptype t ) + field_cache( _In_reads_bytes_opt_(field_len) void* field_value, _In_ SQLLEN field_len, _In_ sqlsrv_phptype t ) : type( t ) { // if the value is NULL, then just record a NULL pointer @@ -53,7 +53,7 @@ struct col_cache { SQLLEN sql_type; SQLLEN display_size; - col_cache( SQLLEN col_sql_type, SQLLEN col_display_size ) + col_cache( _In_ SQLLEN col_sql_type, _In_ SQLLEN col_display_size ) { sql_type = col_sql_type; display_size = col_display_size; @@ -88,43 +88,43 @@ const size_t DATE_FORMAT_LEN = sizeof( DATE_FORMAT ); // *** internal functions *** // Only declarations are put here. Functions contain the documentation they need at their definition sites. -void calc_string_size( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, SQLLEN sql_type, _Out_ SQLLEN& size TSRMLS_DC ); -size_t calc_utf8_missing( sqlsrv_stmt* stmt, const char* buffer, size_t buffer_end TSRMLS_DC ); -bool check_for_next_stream_parameter( sqlsrv_stmt* stmt TSRMLS_DC ); -bool convert_input_param_to_utf16( zval* input_param_z, zval* convert_param_z ); -void core_get_field_common(_Inout_ sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype - sqlsrv_php_type, _Out_ void*& field_value, _Out_ SQLLEN* field_len TSRMLS_DC); +void calc_string_size( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ SQLLEN sql_type, _Inout_ SQLLEN& size TSRMLS_DC ); +size_t calc_utf8_missing( _Inout_ sqlsrv_stmt* stmt, _In_reads_(buffer_end) const char* buffer, _In_ size_t buffer_end TSRMLS_DC ); +bool check_for_next_stream_parameter( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ); +bool convert_input_param_to_utf16( _In_ zval* input_param_z, _Inout_ zval* convert_param_z ); +void core_get_field_common(_Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _Inout_ sqlsrv_phptype + sqlsrv_php_type, _Inout_updates_bytes_(*field_len) void*& field_value, _Inout_ SQLLEN* field_len TSRMLS_DC); // returns the ODBC C type constant that matches the PHP type and encoding given -SQLSMALLINT default_c_type( sqlsrv_stmt* stmt, SQLULEN paramno, zval const* param_z, SQLSRV_ENCODING encoding TSRMLS_DC ); -void default_sql_size_and_scale( sqlsrv_stmt* stmt, unsigned int paramno, zval* param_z, SQLSRV_ENCODING encoding, +SQLSMALLINT default_c_type( _Inout_ sqlsrv_stmt* stmt, _In_opt_ SQLULEN paramno, _In_ zval const* param_z, _In_ SQLSRV_ENCODING encoding TSRMLS_DC ); +void default_sql_size_and_scale( _Inout_ sqlsrv_stmt* stmt, _In_opt_ unsigned int paramno, _In_ zval* param_z, _In_ SQLSRV_ENCODING encoding, _Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits TSRMLS_DC ); // given a zval and encoding, determine the appropriate sql type, column size, and decimal scale (if appropriate) -void default_sql_type( sqlsrv_stmt* stmt, SQLULEN paramno, zval* param_z, SQLSRV_ENCODING encoding, +void default_sql_type( _Inout_ sqlsrv_stmt* stmt, _In_opt_ SQLULEN paramno, _In_ zval* param_z, _In_ SQLSRV_ENCODING encoding, _Out_ SQLSMALLINT& sql_type TSRMLS_DC ); -void col_cache_dtor( zval* data_z ); -void field_cache_dtor( zval* data_z ); -void finalize_output_parameters( sqlsrv_stmt* stmt TSRMLS_DC ); -void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype sqlsrv_php_type, - _Out_ void*& field_value, _Out_ SQLLEN* field_len TSRMLS_DC ); -stmt_option const* get_stmt_option( sqlsrv_conn const* conn, zend_ulong key, const stmt_option stmt_opts[] TSRMLS_DC ); -bool is_valid_sqlsrv_phptype( sqlsrv_phptype type ); +void col_cache_dtor( _Inout_ zval* data_z ); +void field_cache_dtor( _Inout_ zval* data_z ); +void finalize_output_parameters( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ); +void get_field_as_string( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _Inout_ sqlsrv_phptype sqlsrv_php_type, + _Inout_updates_bytes_(*field_len) void*& field_value, _Inout_ SQLLEN* field_len TSRMLS_DC ); +stmt_option const* get_stmt_option( sqlsrv_conn const* conn, _In_ zend_ulong key, _In_ const stmt_option stmt_opts[] TSRMLS_DC ); +bool is_valid_sqlsrv_phptype( _In_ sqlsrv_phptype type ); // assure there is enough space for the output parameter string -void resize_output_buffer_if_necessary( sqlsrv_stmt* stmt, zval* param_z, SQLULEN paramno, SQLSRV_ENCODING encoding, - SQLSMALLINT c_type, SQLSMALLINT sql_type, SQLULEN column_size, SQLPOINTER& buffer, - SQLLEN& buffer_len TSRMLS_DC ); -void save_output_param_for_later( sqlsrv_stmt* stmt, sqlsrv_output_param& param TSRMLS_DC ); +void resize_output_buffer_if_necessary( _Inout_ sqlsrv_stmt* stmt, _Inout_ zval* param_z, _In_ SQLULEN paramno, SQLSRV_ENCODING encoding, + _In_ SQLSMALLINT c_type, _In_ SQLSMALLINT sql_type, _In_ SQLULEN column_size, _Out_writes_(buffer_len) SQLPOINTER& buffer, + _Out_ SQLLEN& buffer_len TSRMLS_DC ); +void save_output_param_for_later( _Inout_ sqlsrv_stmt* stmt, _Inout_ sqlsrv_output_param& param TSRMLS_DC ); // send all the stream data -void send_param_streams( sqlsrv_stmt* stmt TSRMLS_DC ); +void send_param_streams( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ); // called when a bound output string parameter is to be destroyed -void sqlsrv_output_param_dtor( zval* data ); +void sqlsrv_output_param_dtor( _Inout_ zval* data ); // called when a bound stream parameter is to be destroyed. -void sqlsrv_stream_dtor( zval* data ); -bool is_streamable_type( SQLINTEGER sql_type ); +void sqlsrv_stream_dtor( _Inout_ zval* data ); +bool is_streamable_type( _In_ SQLINTEGER sql_type ); } // constructor for sqlsrv_stmt. Here so that we can use functions declared earlier. -sqlsrv_stmt::sqlsrv_stmt( sqlsrv_conn* c, SQLHANDLE handle, error_callback e, void* drv TSRMLS_DC ) : +sqlsrv_stmt::sqlsrv_stmt( _In_ sqlsrv_conn* c, _In_ SQLHANDLE handle, _In_ error_callback e, _In_opt_ void* drv TSRMLS_DC ) : sqlsrv_context( handle, SQL_HANDLE_STMT, e, drv, SQLSRV_ENCODING_DEFAULT ), conn( c ), executed( false ), @@ -251,8 +251,8 @@ void sqlsrv_stmt::new_result_set( TSRMLS_D ) // Return // Returns the created statement -sqlsrv_stmt* core_sqlsrv_create_stmt( sqlsrv_conn* conn, driver_stmt_factory stmt_factory, HashTable* options_ht, - const stmt_option valid_stmt_opts[], error_callback const err, void* driver TSRMLS_DC ) +sqlsrv_stmt* core_sqlsrv_create_stmt( _Inout_ sqlsrv_conn* conn, _In_ driver_stmt_factory stmt_factory, _In_opt_ HashTable* options_ht, + _In_opt_ const stmt_option valid_stmt_opts[], _In_ error_callback const err, _In_opt_ void* driver TSRMLS_DC ) { sqlsrv_malloc_auto_ptr stmt; SQLHANDLE stmt_h = SQL_NULL_HANDLE; @@ -271,7 +271,7 @@ sqlsrv_stmt* core_sqlsrv_create_stmt( sqlsrv_conn* conn, driver_stmt_factory stm stmt_h = SQL_NULL_HANDLE; // process the options array given to core_sqlsrv_prepare. - if( options_ht && zend_hash_num_elements( options_ht ) > 0 ) { + if( options_ht && zend_hash_num_elements( options_ht ) > 0 && valid_stmt_opts ) { zend_ulong index = -1; zend_string *key = NULL; zval* value_z = NULL; @@ -336,9 +336,9 @@ sqlsrv_stmt* core_sqlsrv_create_stmt( sqlsrv_conn* conn, driver_stmt_factory stm // The php type of the parameter is taken from the zval. // The sql type is given as a hint if the driver provides it. -void core_sqlsrv_bind_param( sqlsrv_stmt* stmt, SQLUSMALLINT param_num, SQLSMALLINT direction, zval* param_z, - SQLSRV_PHPTYPE php_out_type, SQLSRV_ENCODING encoding, SQLSMALLINT sql_type, SQLULEN column_size, - SQLSMALLINT decimal_digits TSRMLS_DC ) +void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_num, _In_ SQLSMALLINT direction, _Inout_ zval* param_z, + _In_ SQLSRV_PHPTYPE php_out_type, _In_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, + _Inout_ SQLSMALLINT decimal_digits TSRMLS_DC ) { SQLSMALLINT c_type; SQLPOINTER buffer = NULL; @@ -594,7 +594,7 @@ void core_sqlsrv_bind_param( sqlsrv_stmt* stmt, SQLUSMALLINT param_num, SQLSMALL zend_class_entry *class_entry = Z_OBJCE_P( param_z TSRMLS_CC ); while( class_entry != NULL ) { - + SQLSRV_ASSERT( class_entry->name != NULL, "core_sqlsrv_bind_param: class_entry->name is NULL." ); if( class_entry->name->len == DateTime::DATETIME_CLASS_NAME_LEN && class_entry->name != NULL && stricmp( class_entry->name->val, DateTime::DATETIME_CLASS_NAME ) == 0 ) { valid_class_name_found = true; @@ -676,7 +676,7 @@ void core_sqlsrv_bind_param( sqlsrv_stmt* stmt, SQLUSMALLINT param_num, SQLSMALL // Return: // true if there is data, false if there is not -SQLRETURN core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql, int sql_len ) +SQLRETURN core_sqlsrv_execute( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_reads_bytes_(sql_len) const char* sql, _In_ int sql_len ) { SQLRETURN r = SQL_ERROR; @@ -757,7 +757,7 @@ SQLRETURN core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql, int // Nothing, exception thrown if an error. stmt->past_fetch_end is set to true if the // user scrolls past a non-scrollable result set -bool core_sqlsrv_fetch( sqlsrv_stmt* stmt, SQLSMALLINT fetch_orientation, SQLULEN fetch_offset TSRMLS_DC ) +bool core_sqlsrv_fetch( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT fetch_orientation, _In_ SQLULEN fetch_offset TSRMLS_DC ) { // pre-condition check SQLSRV_ASSERT( fetch_orientation >= SQL_FETCH_NEXT || fetch_orientation <= SQL_FETCH_RELATIVE, @@ -827,7 +827,7 @@ bool core_sqlsrv_fetch( sqlsrv_stmt* stmt, SQLSMALLINT fetch_orientation, SQLULE // Return: // A field_meta_data* consisting of the field metadata. -field_meta_data* core_sqlsrv_field_metadata( sqlsrv_stmt* stmt, SQLSMALLINT colno TSRMLS_DC ) +field_meta_data* core_sqlsrv_field_metadata( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno TSRMLS_DC ) { // pre-condition check SQLSRV_ASSERT( colno >= 0, "core_sqlsrv_field_metadata: Invalid column number provided." ); @@ -882,7 +882,7 @@ field_meta_data* core_sqlsrv_field_metadata( sqlsrv_stmt* stmt, SQLSMALLINT coln } // Set the field name lenth - meta_data->field_name_len = field_name_len; + meta_data->field_name_len = static_cast( field_name_len ); field_meta_data* result_field_meta_data = meta_data; meta_data.transferred(); @@ -901,8 +901,8 @@ field_meta_data* core_sqlsrv_field_metadata( sqlsrv_stmt* stmt, SQLSMALLINT coln // Returns: // Nothing, excpetion thrown if an error occurs -void core_sqlsrv_get_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype sqlsrv_php_type_in, bool prefer_string, - _Out_ void*& field_value, _Out_ SQLLEN* field_len, bool cache_field, +void core_sqlsrv_get_field( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ sqlsrv_phptype sqlsrv_php_type_in, _In_ bool prefer_string, + _Outref_result_bytebuffer_maybenull_(*field_len) void*& field_value, _Inout_ SQLLEN* field_len, _In_ bool cache_field, _Out_ SQLSRV_PHPTYPE *sqlsrv_php_type_out TSRMLS_DC) { try { @@ -1004,7 +1004,7 @@ void core_sqlsrv_get_field( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_ // Return: // true if any results are present, false otherwise. -bool core_sqlsrv_has_any_result( sqlsrv_stmt* stmt TSRMLS_DC ) +bool core_sqlsrv_has_any_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) { // Use SQLNumResultCols to determine if we have rows or not. SQLSMALLINT num_cols = core::SQLNumResultCols( stmt TSRMLS_CC ); @@ -1020,7 +1020,7 @@ bool core_sqlsrv_has_any_result( sqlsrv_stmt* stmt TSRMLS_DC ) // Returns // Nothing, exception thrown if problem occurs -void core_sqlsrv_next_result( sqlsrv_stmt* stmt TSRMLS_DC, bool finalize_output_params, bool throw_on_errors ) +void core_sqlsrv_next_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_ bool finalize_output_params, _In_ bool throw_on_errors ) { try { @@ -1077,7 +1077,7 @@ void core_sqlsrv_next_result( sqlsrv_stmt* stmt TSRMLS_DC, bool finalize_output_ // Returns: // Nothing, exception thrown if problem occurs -void core_sqlsrv_post_param( sqlsrv_stmt* stmt, zend_ulong param_num, zval* param_z TSRMLS_DC ) +void core_sqlsrv_post_param( _Inout_ sqlsrv_stmt* stmt, _In_ zend_ulong param_num, zval* param_z TSRMLS_DC ) { SQLSRV_ASSERT( Z_TYPE( stmt->param_input_strings ) == IS_ARRAY, "Statement input parameter UTF-16 buffers array invalid." ); SQLSRV_ASSERT( Z_TYPE( stmt->param_streams ) == IS_ARRAY, "Statement input parameter streams array invalid." ); @@ -1096,7 +1096,7 @@ void core_sqlsrv_post_param( sqlsrv_stmt* stmt, zend_ulong param_num, zval* para } //Calls SQLSetStmtAttr to set a cursor. -void core_sqlsrv_set_scrollable( sqlsrv_stmt* stmt, unsigned long cursor_type TSRMLS_DC ) +void core_sqlsrv_set_scrollable( _Inout_ sqlsrv_stmt* stmt, _In_ unsigned long cursor_type TSRMLS_DC ) { try { @@ -1140,7 +1140,7 @@ void core_sqlsrv_set_scrollable( sqlsrv_stmt* stmt, unsigned long cursor_type TS } } -void core_sqlsrv_set_buffered_query_limit( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC ) +void core_sqlsrv_set_buffered_query_limit( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z TSRMLS_DC ) { if( Z_TYPE_P( value_z ) != IS_LONG ) { @@ -1150,7 +1150,7 @@ void core_sqlsrv_set_buffered_query_limit( sqlsrv_stmt* stmt, zval* value_z TSRM core_sqlsrv_set_buffered_query_limit( stmt, Z_LVAL_P( value_z ) TSRMLS_CC ); } -void core_sqlsrv_set_buffered_query_limit( sqlsrv_stmt* stmt, SQLLEN limit TSRMLS_DC ) +void core_sqlsrv_set_buffered_query_limit( _Inout_ sqlsrv_stmt* stmt, _In_ SQLLEN limit TSRMLS_DC ) { if( limit <= 0 ) { @@ -1164,7 +1164,7 @@ void core_sqlsrv_set_buffered_query_limit( sqlsrv_stmt* stmt, SQLLEN limit TSRML // Overloaded. Extracts the long value and calls the core_sqlsrv_set_query_timeout // which accepts timeout parameter as a long. If the zval is not of type long // than throws error. -void core_sqlsrv_set_query_timeout( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC ) +void core_sqlsrv_set_query_timeout( _Inout_ sqlsrv_stmt* stmt, _Inout_ zval* value_z TSRMLS_DC ) { try { @@ -1183,7 +1183,7 @@ void core_sqlsrv_set_query_timeout( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC ) } // Overloaded. Accepts the timeout as a long. -void core_sqlsrv_set_query_timeout( sqlsrv_stmt* stmt, long timeout TSRMLS_DC ) +void core_sqlsrv_set_query_timeout( _Inout_ sqlsrv_stmt* stmt, _In_ long timeout TSRMLS_DC ) { try { @@ -1212,7 +1212,7 @@ void core_sqlsrv_set_query_timeout( sqlsrv_stmt* stmt, long timeout TSRMLS_DC ) } } -void core_sqlsrv_set_send_at_exec( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC ) +void core_sqlsrv_set_send_at_exec( _Inout_ sqlsrv_stmt* stmt, _In_ zval* value_z TSRMLS_DC ) { TSRMLS_C; @@ -1232,7 +1232,7 @@ void core_sqlsrv_set_send_at_exec( sqlsrv_stmt* stmt, zval* value_z TSRMLS_DC ) // Returns: // true if more data remains to be sent, false if all data processed -bool core_sqlsrv_send_stream_packet( sqlsrv_stmt* stmt TSRMLS_DC ) +bool core_sqlsrv_send_stream_packet( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) { // if there no current parameter to process, get the next one // (probably because this is the first call to sqlsrv_send_stream_data) @@ -1341,7 +1341,7 @@ bool core_sqlsrv_send_stream_packet( sqlsrv_stmt* stmt TSRMLS_DC ) return true; } -void stmt_option_functor::operator()( sqlsrv_stmt* /*stmt*/, stmt_option const* /*opt*/, zval* /*value_z*/ TSRMLS_DC ) +void stmt_option_functor::operator()( _Inout_ sqlsrv_stmt* /*stmt*/, stmt_option const* /*opt*/, _In_ zval* /*value_z*/ TSRMLS_DC ) { TSRMLS_C; @@ -1349,17 +1349,17 @@ void stmt_option_functor::operator()( sqlsrv_stmt* /*stmt*/, stmt_option const* DIE( "Not implemented." ); } -void stmt_option_query_timeout:: operator()( sqlsrv_stmt* stmt, stmt_option const* /**/, zval* value_z TSRMLS_DC ) +void stmt_option_query_timeout:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /**/, _In_ zval* value_z TSRMLS_DC ) { core_sqlsrv_set_query_timeout( stmt, value_z TSRMLS_CC ); } -void stmt_option_send_at_exec:: operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC ) +void stmt_option_send_at_exec:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) { core_sqlsrv_set_send_at_exec( stmt, value_z TSRMLS_CC ); } -void stmt_option_buffered_query_limit:: operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC ) +void stmt_option_buffered_query_limit:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) { core_sqlsrv_set_buffered_query_limit( stmt, value_z TSRMLS_CC ); } @@ -1391,7 +1391,7 @@ void close_active_stream( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) namespace { -bool is_streamable_type( SQLLEN sql_type ) +bool is_streamable_type( _In_ SQLLEN sql_type ) { switch( sql_type ) { case SQL_CHAR: @@ -1410,7 +1410,7 @@ bool is_streamable_type( SQLLEN sql_type ) return false; } -void calc_string_size( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, SQLLEN sql_type, _Out_ SQLLEN& size TSRMLS_DC ) +void calc_string_size( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ SQLLEN sql_type, _Inout_ SQLLEN& size TSRMLS_DC ) { try { @@ -1471,7 +1471,7 @@ void calc_string_size( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, SQLLEN sql_t // calculates how many characters were cut off from the end of a buffer when reading // in UTF-8 encoded text -size_t calc_utf8_missing( sqlsrv_stmt* stmt, const char* buffer, size_t buffer_end TSRMLS_DC ) +size_t calc_utf8_missing( _Inout_ sqlsrv_stmt* stmt, _In_reads_(buffer_end) const char* buffer, _In_ size_t buffer_end TSRMLS_DC ) { const char* last_char = buffer + buffer_end - 1; size_t need_to_read = 0; @@ -1509,8 +1509,8 @@ size_t calc_utf8_missing( sqlsrv_stmt* stmt, const char* buffer, size_t buffer_e // The memory allocation has to happen in the core layer because otherwise // the driver layer would have to calculate size of the field_value // to decide the amount of memory allocation. -void core_get_field_common( _Inout_ sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype - sqlsrv_php_type, _Out_ void*& field_value, _Out_ SQLLEN* field_len TSRMLS_DC ) +void core_get_field_common( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _Inout_ sqlsrv_phptype + sqlsrv_php_type, _Inout_updates_bytes_(*field_len) void*& field_value, _Inout_ SQLLEN* field_len TSRMLS_DC ) { try { @@ -1738,7 +1738,7 @@ bool check_for_next_stream_parameter( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) // utility routine to convert an input parameter from UTF-8 to UTF-16 -bool convert_input_param_to_utf16( zval* input_param_z, zval* converted_param_z ) +bool convert_input_param_to_utf16( _In_ zval* input_param_z, _Inout_ zval* converted_param_z ) { SQLSRV_ASSERT( input_param_z == converted_param_z || Z_TYPE_P( converted_param_z ) == IS_NULL, "convert_input_param_z called with invalid parameter states" ); @@ -1795,7 +1795,7 @@ bool convert_input_param_to_utf16( zval* input_param_z, zval* converted_param_z // returns the ODBC C type constant that matches the PHP type and encoding given -SQLSMALLINT default_c_type( sqlsrv_stmt* stmt, SQLULEN paramno, zval const* param_z, SQLSRV_ENCODING encoding TSRMLS_DC ) +SQLSMALLINT default_c_type( _Inout_ sqlsrv_stmt* stmt, _In_opt_ SQLULEN paramno, _In_ zval const* param_z, _In_ SQLSRV_ENCODING encoding TSRMLS_DC ) { SQLSMALLINT sql_c_type = SQL_UNKNOWN_TYPE; int php_type = Z_TYPE_P( param_z ); @@ -1865,7 +1865,7 @@ SQLSMALLINT default_c_type( sqlsrv_stmt* stmt, SQLULEN paramno, zval const* para // given a zval and encoding, determine the appropriate sql type -void default_sql_type( sqlsrv_stmt* stmt, SQLULEN paramno, zval* param_z, SQLSRV_ENCODING encoding, +void default_sql_type( _Inout_ sqlsrv_stmt* stmt, _In_opt_ SQLULEN paramno, _In_ zval* param_z, _In_ SQLSRV_ENCODING encoding, _Out_ SQLSMALLINT& sql_type TSRMLS_DC ) { sql_type = SQL_UNKNOWN_TYPE; @@ -1943,7 +1943,7 @@ void default_sql_type( sqlsrv_stmt* stmt, SQLULEN paramno, zval* param_z, SQLSRV // given a zval and encoding, determine the appropriate column size, and decimal scale (if appropriate) -void default_sql_size_and_scale( sqlsrv_stmt* stmt, unsigned int paramno, zval* param_z, SQLSRV_ENCODING encoding, +void default_sql_size_and_scale( _Inout_ sqlsrv_stmt* stmt, _In_opt_ unsigned int paramno, _In_ zval* param_z, _In_ SQLSRV_ENCODING encoding, _Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits TSRMLS_DC ) { int php_type = Z_TYPE_P( param_z ); @@ -1996,13 +1996,13 @@ void default_sql_size_and_scale( sqlsrv_stmt* stmt, unsigned int paramno, zval* } } -void col_cache_dtor( zval* data_z ) +void col_cache_dtor( _Inout_ zval* data_z ) { col_cache* cache = static_cast( Z_PTR_P( data_z )); sqlsrv_free( cache ); } -void field_cache_dtor( zval* data_z ) +void field_cache_dtor( _Inout_ zval* data_z ) { field_cache* cache = static_cast( Z_PTR_P( data_z )); if( cache->value ) @@ -2019,7 +2019,7 @@ void field_cache_dtor( zval* data_z ) // parameters passed to SQLBindParameter. It also converts output strings from UTF-16 to UTF-8 if necessary. // For integer or float parameters, it sets those to NULL if a NULL was returned by SQL Server -void finalize_output_parameters( sqlsrv_stmt* stmt TSRMLS_DC ) +void finalize_output_parameters( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) { if( Z_ISUNDEF(stmt->output_params) ) return; @@ -2127,14 +2127,14 @@ void finalize_output_parameters( sqlsrv_stmt* stmt TSRMLS_DC ) return; } -void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype sqlsrv_php_type, - _Out_ void*& field_value, _Out_ SQLLEN* field_len TSRMLS_DC ) +void get_field_as_string( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _Inout_ sqlsrv_phptype sqlsrv_php_type, + _Inout_updates_bytes_(*field_len) void*& field_value, _Inout_ SQLLEN* field_len TSRMLS_DC ) { SQLRETURN r; SQLSMALLINT c_type; SQLLEN sql_field_type = 0; SQLSMALLINT extra = 0; - SQLLEN field_len_temp; + SQLLEN field_len_temp = 0; SQLLEN sql_display_size = 0; char* field_value_temp = NULL; @@ -2205,8 +2205,8 @@ void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_ph if( r == SQL_SUCCESS_WITH_INFO ) { - SQLCHAR state[ SQL_SQLSTATE_BUFSIZE ]; - SQLSMALLINT len; + SQLCHAR state[SQL_SQLSTATE_BUFSIZE] = { 0 }; + SQLSMALLINT len = 0; stmt->current_results->get_diag_field( 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len TSRMLS_CC ); @@ -2218,7 +2218,7 @@ void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_ph if( is_truncated_warning( state ) ) { #endif // !_WIN32 - SQLLEN dummy_field_len; + SQLLEN dummy_field_len = 0; // for XML (and possibly other conditions) the field length returned is not the real field length, so // in every pass, we double the allocation size to retrieve all the contents. @@ -2391,7 +2391,7 @@ void get_field_as_string( sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_ph // return the option from the stmt_opts array that matches the key. If no option found, // NULL is returned. -stmt_option const* get_stmt_option( sqlsrv_conn const* conn, zend_ulong key, const stmt_option stmt_opts[] TSRMLS_DC ) +stmt_option const* get_stmt_option( sqlsrv_conn const* conn, _In_ zend_ulong key, _In_ const stmt_option stmt_opts[] TSRMLS_DC ) { for( int i = 0; stmt_opts[ i ].key != SQLSRV_STMT_OPTION_INVALID; ++i ) { @@ -2407,7 +2407,7 @@ stmt_option const* get_stmt_option( sqlsrv_conn const* conn, zend_ulong key, con // is_fixed_size_type // returns true if the SQL data type is a fixed length, as opposed to a variable length data type such as varchar or varbinary -bool is_fixed_size_type( SQLINTEGER sql_type ) +bool is_fixed_size_type( _In_ SQLINTEGER sql_type ) { switch( sql_type ) { @@ -2428,7 +2428,7 @@ bool is_fixed_size_type( SQLINTEGER sql_type ) return true; } -bool is_valid_sqlsrv_phptype( sqlsrv_phptype type ) +bool is_valid_sqlsrv_phptype( _In_ sqlsrv_phptype type ) { switch( type.typeinfo.type ) { @@ -2457,9 +2457,9 @@ bool is_valid_sqlsrv_phptype( sqlsrv_phptype type ) // string is place in the stmt->output_params. param_z is modified to hold the new buffer, and buffer, buffer_len and // stmt->param_ind_ptrs are modified to hold the correct values for SQLBindParameter -void resize_output_buffer_if_necessary( sqlsrv_stmt* stmt, zval* param_z, SQLULEN paramno, SQLSRV_ENCODING encoding, - SQLSMALLINT c_type, SQLSMALLINT sql_type, SQLULEN column_size, SQLPOINTER& buffer, - SQLLEN& buffer_len TSRMLS_DC ) +void resize_output_buffer_if_necessary( _Inout_ sqlsrv_stmt* stmt, _Inout_ zval* param_z, _In_ SQLULEN paramno, SQLSRV_ENCODING encoding, + _In_ SQLSMALLINT c_type, _In_ SQLSMALLINT sql_type, _In_ SQLULEN column_size, _Out_writes_(buffer_len) SQLPOINTER& buffer, + _Out_ SQLLEN& buffer_len TSRMLS_DC ) { SQLSRV_ASSERT( column_size != SQLSRV_UNKNOWN_SIZE, "column size should be set to a known value." ); buffer_len = Z_STRLEN_P( param_z ); @@ -2528,7 +2528,7 @@ void resize_output_buffer_if_necessary( sqlsrv_stmt* stmt, zval* param_z, SQLULE // while the query is executed and processed. They are saved in the statement so that // their reference count may be decremented later (after results are processed) -void save_output_param_for_later( sqlsrv_stmt* stmt, sqlsrv_output_param& param TSRMLS_DC ) +void save_output_param_for_later( _Inout_ sqlsrv_stmt* stmt, _Inout_ sqlsrv_output_param& param TSRMLS_DC ) { HashTable* param_ht = Z_ARRVAL( stmt->output_params ); zend_ulong paramno = static_cast( param.param_num ); @@ -2539,14 +2539,14 @@ void save_output_param_for_later( sqlsrv_stmt* stmt, sqlsrv_output_param& param // send all the stream data -void send_param_streams( sqlsrv_stmt* stmt TSRMLS_DC ) +void send_param_streams( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) { while( core_sqlsrv_send_stream_packet( stmt TSRMLS_CC )) { } } // called by Zend for each parameter in the sqlsrv_stmt::output_params hash table when it is cleaned/destroyed -void sqlsrv_output_param_dtor( zval* data ) +void sqlsrv_output_param_dtor( _Inout_ zval* data ) { sqlsrv_output_param *output_param = static_cast( Z_PTR_P( data )); zval_ptr_dtor( output_param->param_z ); // undo the reference to the string we will no longer hold @@ -2554,7 +2554,7 @@ void sqlsrv_output_param_dtor( zval* data ) } // called by Zend for each stream in the sqlsrv_stmt::param_streams hash table when it is cleaned/destroyed -void sqlsrv_stream_dtor( zval* data ) +void sqlsrv_stream_dtor( _Inout_ zval* data ) { sqlsrv_stream* stream_encoding = static_cast( Z_PTR_P( data )); zval_ptr_dtor( stream_encoding->stream_z ); // undo the reference to the stream we will no longer hold diff --git a/source/shared/core_stream.cpp b/source/shared/core_stream.cpp index a29ec086..4fc1cfe3 100644 --- a/source/shared/core_stream.cpp +++ b/source/shared/core_stream.cpp @@ -23,7 +23,7 @@ namespace { // close a stream and free the PHP resources used by it -int sqlsrv_stream_close( php_stream* stream, int /*close_handle*/ TSRMLS_DC ) +int sqlsrv_stream_close( _Inout_ php_stream* stream, int /*close_handle*/ TSRMLS_DC ) { sqlsrv_stream* ss = static_cast( stream->abstract ); SQLSRV_ASSERT( ss != NULL, "sqlsrv_stream_close: sqlsrv_stream* ss was null." ); @@ -44,7 +44,7 @@ int sqlsrv_stream_close( php_stream* stream, int /*close_handle*/ TSRMLS_DC ) // read from a sqlsrv stream into the buffer provided by Zend. The parameters for binary vs. char are // set when sqlsrv_get_field is called by the user specifying which field type they want. -size_t sqlsrv_stream_read( php_stream* stream, _Out_writes_bytes_(count) char* buf, size_t count TSRMLS_DC ) +size_t sqlsrv_stream_read( _Inout_ php_stream* stream, _Out_writes_bytes_(count) char* buf, _Inout_ size_t count TSRMLS_DC ) { SQLLEN read = 0; SQLSMALLINT c_type = SQL_C_CHAR; @@ -106,8 +106,8 @@ size_t sqlsrv_stream_read( php_stream* stream, _Out_writes_bytes_(count) char* b // if it's not a binary encoded field if( r == SQL_SUCCESS_WITH_INFO ) { - SQLCHAR state[ SQL_SQLSTATE_BUFSIZE ]; - SQLSMALLINT len; + SQLCHAR state[SQL_SQLSTATE_BUFSIZE] = { 0 }; + SQLSMALLINT len = 0; ss->stmt->current_results->get_diag_field( 1, SQL_DIAG_SQLSTATE, state, SQL_SQLSTATE_BUFSIZE, &len TSRMLS_CC ); @@ -211,8 +211,8 @@ php_stream_ops sqlsrv_stream_ops = { // open a stream and return the sqlsrv_stream_ops function table as part of the // return value. There is only one valid way to open a stream, using sqlsrv_get_field on // certain field types. A sqlsrv stream may only be opened in read mode. -static php_stream* sqlsrv_stream_opener( php_stream_wrapper* wrapper, _In_ const char*, _In_ const char* mode, - int options, _In_ zend_string **, php_stream_context* STREAMS_DC TSRMLS_DC ) +static php_stream* sqlsrv_stream_opener( _In_opt_ php_stream_wrapper* wrapper, _In_ const char*, _In_ const char* mode, + _In_opt_ int options, _In_ zend_string **, php_stream_context* STREAMS_DC TSRMLS_DC ) { #if ZEND_DEBUG diff --git a/source/shared/core_util.cpp b/source/shared/core_util.cpp index 202e23fb..a003f718 100644 --- a/source/shared/core_util.cpp +++ b/source/shared/core_util.cpp @@ -31,10 +31,10 @@ SQLCHAR INTERNAL_FORMAT_ERROR[] = "An internal error occurred. FormatMessage fa char last_err_msg[ 2048 ]; // 2k to hold the error messages // routine used by utf16_string_from_mbcs_string -unsigned int convert_string_from_default_encoding( unsigned int php_encoding, _In_reads_bytes_(mbcs_len) char const* mbcs_in_string, - unsigned int mbcs_len, +unsigned int convert_string_from_default_encoding( _In_ unsigned int php_encoding, _In_reads_bytes_(mbcs_len) char const* mbcs_in_string, + _In_ unsigned int mbcs_len, _Out_writes_(utf16_len) __transfer( mbcs_in_string ) SQLWCHAR* utf16_out_string, - unsigned int utf16_len ); + _In_ unsigned int utf16_len ); } // SQLSTATE for all internal errors @@ -45,7 +45,7 @@ SQLCHAR SSPWARN[] = "01SSP"; // write to the php log if the severity and subsystem match the filters currently set in the INI or // the script (sqlsrv_configure). -void write_to_log( unsigned int severity TSRMLS_DC, const char* msg, ...) +void write_to_log( _In_ unsigned int severity TSRMLS_DC, _In_ const char* msg, ...) { SQLSRV_ASSERT( !(g_driver_log == NULL), "Must register a driver log function." ); @@ -57,7 +57,7 @@ void write_to_log( unsigned int severity TSRMLS_DC, const char* msg, ...) va_end( args ); } -void core_sqlsrv_register_logger( log_callback driver_logger ) +void core_sqlsrv_register_logger( _In_ log_callback driver_logger ) { g_driver_log = driver_logger; } @@ -68,7 +68,7 @@ void core_sqlsrv_register_logger( log_callback driver_logger ) // utf-16 string is released by this function if no errors occurred. Otherwise the parameters are not changed // and false is returned. -bool convert_string_from_utf16_inplace( SQLSRV_ENCODING encoding, char** string, SQLLEN& len) +bool convert_string_from_utf16_inplace( _In_ SQLSRV_ENCODING encoding, _Inout_updates_z_(len) char** string, _Inout_ SQLLEN& len) { SQLSRV_ASSERT( string != NULL, "String must be specified" ); @@ -91,7 +91,7 @@ bool convert_string_from_utf16_inplace( SQLSRV_ENCODING encoding, char** string, return result; } -bool convert_zval_string_from_utf16(SQLSRV_ENCODING encoding, zval* value_z, SQLLEN& len) +bool convert_zval_string_from_utf16( _In_ SQLSRV_ENCODING encoding, _Inout_ zval* value_z, _Inout_ SQLLEN& len) { char* string = Z_STRVAL_P(value_z); @@ -110,7 +110,7 @@ bool convert_zval_string_from_utf16(SQLSRV_ENCODING encoding, zval* value_z, SQL return result; } -bool validate_string(char* string, SQLLEN& len) +bool validate_string( _In_ char* string, _In_ SQLLEN& len ) { SQLSRV_ASSERT(string != NULL, "String must be specified"); @@ -125,7 +125,7 @@ bool validate_string(char* string, SQLLEN& len) return false; } -bool convert_string_from_utf16( SQLSRV_ENCODING encoding, const SQLWCHAR* inString, SQLINTEGER cchInLen, char** outString, SQLLEN& cchOutLen ) +bool convert_string_from_utf16( _In_ SQLSRV_ENCODING encoding, _In_reads_bytes_(cchInLen) const SQLWCHAR* inString, _In_ SQLINTEGER cchInLen, _Inout_updates_bytes_(cchOutLen) char** outString, _Out_ SQLLEN& cchOutLen ) { SQLSRV_ASSERT( inString != NULL, "Input string must be specified" ); SQLSRV_ASSERT( outString != NULL, "Output buffer pointer must be specified" ); @@ -182,8 +182,8 @@ bool convert_string_from_utf16( SQLSRV_ENCODING encoding, const SQLWCHAR* inStri // thin wrapper around convert_string_from_default_encoding that handles // allocation of the destination string. An empty string passed in returns // failure since it's a failure case for convert_string_from_default_encoding. -SQLWCHAR* utf16_string_from_mbcs_string( SQLSRV_ENCODING php_encoding, const char* mbcs_string, unsigned int mbcs_len, - unsigned int* utf16_len ) +SQLWCHAR* utf16_string_from_mbcs_string( _In_ SQLSRV_ENCODING php_encoding, _In_reads_bytes_(mbcs_len) const char* mbcs_string, _In_ unsigned int mbcs_len, + _Out_ unsigned int* utf16_len ) { *utf16_len = (mbcs_len + 1); SQLWCHAR* utf16_string = reinterpret_cast( sqlsrv_malloc( *utf16_len * sizeof( SQLWCHAR ))); @@ -207,7 +207,7 @@ SQLWCHAR* utf16_string_from_mbcs_string( SQLSRV_ENCODING php_encoding, const cha // 3/message) driver specific error message // The fetch type determines if the indices are numeric, associative, or both. -bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, sqlsrv_error_auto_ptr& error, logging_severity severity +bool core_sqlsrv_get_odbc_error( _Inout_ sqlsrv_context& ctx, _In_ int record_number, _Inout_ sqlsrv_error_auto_ptr& error, _In_ logging_severity severity TSRMLS_DC ) { SQLHANDLE h = ctx.handle(); @@ -284,8 +284,8 @@ bool core_sqlsrv_get_odbc_error( sqlsrv_context& ctx, int record_number, sqlsrv_ } // format and return a driver specfic error -void core_sqlsrv_format_driver_error( sqlsrv_context& ctx, sqlsrv_error_const const* custom_error, - sqlsrv_error_auto_ptr& formatted_error, logging_severity severity TSRMLS_DC, va_list* args ) +void core_sqlsrv_format_driver_error( _In_ sqlsrv_context& ctx, _In_ sqlsrv_error_const const* custom_error, + _Out_ sqlsrv_error_auto_ptr& formatted_error, _In_ logging_severity severity TSRMLS_DC, _In_opt_ va_list* args ) { // allocate space for the formatted message formatted_error = new (sqlsrv_malloc( sizeof( sqlsrv_error ))) sqlsrv_error(); @@ -309,7 +309,7 @@ void core_sqlsrv_format_driver_error( sqlsrv_context& ctx, sqlsrv_error_const co LOG( severity, "%1!s!: message = %2!s!", ctx.func(), formatted_error->native_message ); } -DWORD core_sqlsrv_format_message( char* output_buffer, unsigned output_len, const char* format, ... ) +DWORD core_sqlsrv_format_message( _Out_ char* output_buffer, _In_ unsigned output_len, _In_opt_ const char* format, ... ) { va_list format_args; va_start( format_args, format ); @@ -321,7 +321,7 @@ DWORD core_sqlsrv_format_message( char* output_buffer, unsigned output_len, cons // return an error message for GetLastError using FormatMessage. // this function returns the msg pointer so that it may be used within // another function call such as handle_error -const char* get_last_error_message( DWORD last_error ) +const char* get_last_error_message( _Inout_ DWORD last_error ) { if( last_error == 0 ) { last_error = GetLastError(); @@ -346,7 +346,7 @@ const char* get_last_error_message( DWORD last_error ) // places where we were using the FormatMessage syntax inadvertently with DIE which left messages without // proper information. Rather than convert those messages and try and remember the difference between LOG and // DIE, it is simpler to make the format syntax common between them. -void die( const char* msg, ... ) +void die( _In_opt_ const char* msg, ... ) { va_list format_args; va_start( format_args, msg ); @@ -367,9 +367,9 @@ namespace { // returned in utf16_out_string. An empty string passed in will result as // a failure since MBTWC returns 0 for both an empty string and failure // to convert. -unsigned int convert_string_from_default_encoding( unsigned int php_encoding, _In_reads_bytes_(mbcs_len) char const* mbcs_in_string, - unsigned int mbcs_len, _Out_writes_(utf16_len) __transfer( mbcs_in_string ) SQLWCHAR* utf16_out_string, - unsigned int utf16_len ) +unsigned int convert_string_from_default_encoding( _In_ unsigned int php_encoding, _In_reads_bytes_(mbcs_len) char const* mbcs_in_string, + _In_ unsigned int mbcs_len, _Out_writes_(utf16_len) __transfer( mbcs_in_string ) SQLWCHAR* utf16_out_string, + _In_ unsigned int utf16_len ) { unsigned int win_encoding = CP_ACP; switch( php_encoding ) { diff --git a/source/sqlsrv/conn.cpp b/source/sqlsrv/conn.cpp index 8a9d6da6..c578188c 100644 --- a/source/sqlsrv/conn.cpp +++ b/source/sqlsrv/conn.cpp @@ -31,7 +31,7 @@ unsigned int current_log_subsystem = LOG_CONN; struct date_as_string_func { - static void func( connection_option const* /*option*/, zval* value, sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) + static void func( connection_option const* /*option*/, _In_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) { TSRMLS_C; // show as used to avoid a warning @@ -48,7 +48,7 @@ struct date_as_string_func { struct conn_char_set_func { - static void func( connection_option const* /*option*/, zval* value, sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) + static void func( connection_option const* /*option*/, _Inout_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) { convert_to_string( value ); const char* encoding = Z_STRVAL_P( value ); @@ -78,7 +78,7 @@ struct conn_char_set_func { struct bool_conn_str_func { - static void func( connection_option const* option, zval* value, sqlsrv_conn* /*conn*/, std::string& conn_str TSRMLS_DC ) + static void func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str TSRMLS_DC ) { TSRMLS_C; char const* val_str; @@ -98,7 +98,7 @@ struct bool_conn_str_func { #ifdef _WIN32 struct int_conn_str_func { - static void func( connection_option const* option, zval* value, sqlsrv_conn* /*conn*/, std::string& conn_str TSRMLS_DC ) + static void func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str TSRMLS_DC ) { TSRMLS_C; SQLSRV_ASSERT( Z_TYPE_P( value ) == IS_LONG, "An integer is expected for this keyword" ) @@ -116,7 +116,7 @@ struct int_conn_str_func { template struct int_conn_attr_func { - static void func( connection_option const* /*option*/, zval* value, sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) + static void func( connection_option const* /*option*/, _In_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) { try { @@ -131,7 +131,7 @@ struct int_conn_attr_func { template struct bool_conn_attr_func { - static void func( connection_option const* /*option*/, zval* value, sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) + static void func( connection_option const* /*option*/, _In_ zval* value, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ) { try { core::SQLSetConnectAttr(conn, Attr, reinterpret_cast((zend_long)zend_is_true(value)), @@ -147,15 +147,15 @@ struct bool_conn_attr_func { //// *** internal functions *** -void sqlsrv_conn_close_stmts( ss_sqlsrv_conn* conn TSRMLS_DC ); -void validate_conn_options( sqlsrv_context& ctx, zval* user_options_z, _Out_ char** uid, _Out_ char** pwd, +void sqlsrv_conn_close_stmts( _Inout_ ss_sqlsrv_conn* conn TSRMLS_DC ); +void validate_conn_options( _Inout_ sqlsrv_context& ctx, _In_ zval* user_options_z, _Inout_ char** uid, _Inout_ char** pwd, _Inout_ HashTable* ss_conn_options_ht TSRMLS_DC ); -void validate_stmt_options( sqlsrv_context& ctx, zval* stmt_options, _Inout_ HashTable* ss_stmt_options_ht TSRMLS_DC ); -void add_conn_option_key( sqlsrv_context& ctx, zend_string* key, size_t key_len, - HashTable* options_ht, zval* data TSRMLS_DC ); -void add_stmt_option_key( sqlsrv_context& ctx, zend_string* key, size_t key_len, HashTable* options_ht, zval* data TSRMLS_DC ); -int get_conn_option_key( sqlsrv_context& ctx, zend_string* key, size_t key_len, zval const* value_z TSRMLS_DC ); -int get_stmt_option_key( zend_string* key, size_t key_len TSRMLS_DC ); +void validate_stmt_options( _Inout_ sqlsrv_context& ctx, _In_ zval* stmt_options, _Inout_ HashTable* ss_stmt_options_ht TSRMLS_DC ); +void add_conn_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In_ size_t key_len, + _Inout_ HashTable* options_ht, _Inout_ zval* data TSRMLS_DC ); +void add_stmt_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In_ size_t key_len, _Inout_ HashTable* options_ht, _Inout_ zval* data TSRMLS_DC ); +int get_conn_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In_ size_t key_len, _In_ zval const* value_z TSRMLS_DC ); +int get_stmt_option_key( _In_ zend_string* key, _In_ size_t key_len TSRMLS_DC ); } @@ -647,7 +647,7 @@ PHP_FUNCTION( sqlsrv_close ) THROW_CORE_ERROR( error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ ); } } - + SQLSRV_ASSERT( conn_r != NULL, "sqlsrv_close: conn_r was null" ); conn = static_cast( zend_fetch_resource( Z_RES_P( conn_r ) TSRMLS_CC, ss_sqlsrv_conn::resource_name, ss_sqlsrv_conn::descriptor )); // if sqlsrv_close was called on an already closed connection then we just return success. @@ -687,7 +687,7 @@ PHP_FUNCTION( sqlsrv_close ) } } -void __cdecl sqlsrv_conn_dtor( zend_resource *rsrc TSRMLS_DC ) +void __cdecl sqlsrv_conn_dtor( _Inout_ zend_resource *rsrc TSRMLS_DC ) { LOG_FUNCTION( "sqlsrv_conn_dtor" ); @@ -1125,7 +1125,7 @@ PHP_FUNCTION( sqlsrv_query ) } } -void free_stmt_resource( zval* stmt_z TSRMLS_DC ) +void free_stmt_resource( _Inout_ zval* stmt_z TSRMLS_DC ) { if( FAILURE == zend_list_close( Z_RES_P( stmt_z ))) { LOG(SEV_ERROR, "Failed to remove stmt resource %1!d!", Z_RES_HANDLE_P(stmt_z)); @@ -1141,7 +1141,7 @@ namespace { // must close all statement handles opened by this connection before closing the connection // no errors are returned, since close should always succeed -void sqlsrv_conn_close_stmts( ss_sqlsrv_conn* conn TSRMLS_DC ) +void sqlsrv_conn_close_stmts( _Inout_ ss_sqlsrv_conn* conn TSRMLS_DC ) { //pre-condition check SQLSRV_ASSERT(( conn->handle() != NULL ), "sqlsrv_conn_close_stmts: Connection handle is NULL. Trying to destroy an " @@ -1189,7 +1189,7 @@ void sqlsrv_conn_close_stmts( ss_sqlsrv_conn* conn TSRMLS_DC ) conn->stmts = NULL; } -int get_conn_option_key( sqlsrv_context& ctx, zend_string* key, size_t key_len, zval const* value_z TSRMLS_DC ) +int get_conn_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In_ size_t key_len, _In_ zval const* value_z TSRMLS_DC ) { for( int i=0; SS_CONN_OPTS[ i ].conn_option_key != SQLSRV_CONN_OPTION_INVALID; ++i ) { @@ -1250,7 +1250,7 @@ int get_conn_option_key( sqlsrv_context& ctx, zend_string* key, size_t key_len, return SQLSRV_CONN_OPTION_INVALID; } -int get_stmt_option_key( zend_string* key, size_t key_len TSRMLS_DC ) +int get_stmt_option_key( _In_ zend_string* key, _In_ size_t key_len TSRMLS_DC ) { for( int i = 0; SS_STMT_OPTS[ i ].key != SQLSRV_STMT_OPTION_INVALID; ++i ) { @@ -1261,8 +1261,8 @@ int get_stmt_option_key( zend_string* key, size_t key_len TSRMLS_DC ) return SQLSRV_STMT_OPTION_INVALID; } -void add_stmt_option_key( sqlsrv_context& ctx, zend_string* key, size_t key_len, - HashTable* options_ht, zval* data TSRMLS_DC ) +void add_stmt_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In_ size_t key_len, + _Inout_ HashTable* options_ht, _Inout_ zval* data TSRMLS_DC ) { int option_key = ::get_stmt_option_key( key, key_len TSRMLS_CC ); @@ -1275,8 +1275,8 @@ void add_stmt_option_key( sqlsrv_context& ctx, zend_string* key, size_t key_len, core::sqlsrv_zend_hash_index_update( ctx, options_ht, option_key, data TSRMLS_CC ); } -void add_conn_option_key( sqlsrv_context& ctx, zend_string* key, size_t key_len, - HashTable* options_ht, zval* data TSRMLS_DC ) +void add_conn_option_key( _Inout_ sqlsrv_context& ctx, _In_ zend_string* key, _In_ size_t key_len, + _Inout_ HashTable* options_ht, _Inout_ zval* data TSRMLS_DC ) { int option_key = ::get_conn_option_key( ctx, key, key_len, data TSRMLS_CC ); CHECK_CUSTOM_ERROR((option_key == SQLSRV_STMT_OPTION_INVALID ), ctx, SS_SQLSRV_ERROR_INVALID_OPTION, ZSTR_VAL( key ) ) { @@ -1292,7 +1292,7 @@ void add_conn_option_key( sqlsrv_context& ctx, zend_string* key, size_t key_len, // against the list of supported statement options by this driver. After validation // creates a Hashtable of statement options to be sent to the core layer for processing. -void validate_stmt_options( sqlsrv_context& ctx, zval* stmt_options, _Inout_ HashTable* ss_stmt_options_ht TSRMLS_DC ) +void validate_stmt_options( _Inout_ sqlsrv_context& ctx, _In_ zval* stmt_options, _Inout_ HashTable* ss_stmt_options_ht TSRMLS_DC ) { try { if( stmt_options ) { @@ -1312,8 +1312,13 @@ void validate_stmt_options( sqlsrv_context& ctx, zval* stmt_options, _Inout_ Has throw core::CoreException(); } } - key_len = ZSTR_LEN(key) + 1; - add_stmt_option_key( ctx, key, key_len, ss_stmt_options_ht, data TSRMLS_CC ); + else if ( key != NULL ) { + key_len = ZSTR_LEN( key ) + 1; + add_stmt_option_key( ctx, key, key_len, ss_stmt_options_ht, data TSRMLS_CC ); + } + else { + DIE( "validate_stmt_options: key was null." ); + } } ZEND_HASH_FOREACH_END(); } } @@ -1327,7 +1332,7 @@ void validate_stmt_options( sqlsrv_context& ctx, zval* stmt_options, _Inout_ Has // against the predefined list of supported connection options by this driver. After validation // creates a Hashtable of connection options to be sent to the core layer for processing. -void validate_conn_options( sqlsrv_context& ctx, zval* user_options_z, _Out_ char** uid, _Out_ char** pwd, _Inout_ HashTable* ss_conn_options_ht TSRMLS_DC ) +void validate_conn_options( _Inout_ sqlsrv_context& ctx, _In_ zval* user_options_z, _Inout_ char** uid, _Inout_ char** pwd, _Inout_ HashTable* ss_conn_options_ht TSRMLS_DC ) { try { @@ -1348,21 +1353,25 @@ void validate_conn_options( sqlsrv_context& ctx, zval* user_options_z, _Out_ cha CHECK_CUSTOM_ERROR(( type != HASH_KEY_IS_STRING ), ctx, SS_SQLSRV_ERROR_INVALID_CONNECTION_KEY ) { throw ss::SSException(); } + if ( key != NULL ) { + // Length of the key string does not include the null terminator in PHP7, +1 has to be added + size_t key_len = ZSTR_LEN( key ) + 1; + if ( key_len == sizeof( SSConnOptionNames::UID ) && !stricmp( ZSTR_VAL( key ), SSConnOptionNames::UID )) { - // Length of the key string does not include the null terminator in PHP7, +1 has to be added - size_t key_len = ZSTR_LEN(key) + 1; - if( key_len == sizeof(SSConnOptionNames::UID) && !stricmp(ZSTR_VAL(key), SSConnOptionNames::UID )) { + *uid = Z_STRVAL_P( data ); + } - *uid = Z_STRVAL_P( data ); - } + else if ( key_len == sizeof( SSConnOptionNames::PWD ) && !stricmp( ZSTR_VAL( key ), SSConnOptionNames::PWD )) { - else if( key_len == sizeof( SSConnOptionNames::PWD ) && !stricmp( ZSTR_VAL( key ), SSConnOptionNames::PWD )) { + *pwd = Z_STRVAL_P( data ); + } + else { - *pwd = Z_STRVAL_P( data ); + ::add_conn_option_key( ctx, key, key_len, ss_conn_options_ht, data TSRMLS_CC ); + } } else { - - ::add_conn_option_key( ctx, key, key_len, ss_conn_options_ht, data TSRMLS_CC ); + DIE( "validate_conn_options: key was null." ); } } ZEND_HASH_FOREACH_END(); } diff --git a/source/sqlsrv/init.cpp b/source/sqlsrv/init.cpp index 84cc153a..f6626122 100644 --- a/source/sqlsrv/init.cpp +++ b/source/sqlsrv/init.cpp @@ -37,8 +37,8 @@ HashTable* g_ss_warnings_to_ignore_ht = NULL; HashTable* g_ss_encodings_ht = NULL; // Destructors called by Zend for each element in the hashtable -void sqlsrv_error_const_dtor( zval* element ); -void sqlsrv_encoding_dtor( zval* element ); +void sqlsrv_error_const_dtor( _Inout_ zval* element ); +void sqlsrv_encoding_dtor( _Inout_ zval* element ); // henv context for creating connections sqlsrv_context* g_ss_henv_cp; @@ -569,13 +569,13 @@ PHP_MINIT_FUNCTION(sqlsrv) } // called by Zend for each parameter in the g_ss_warnings_to_ignore_ht and g_ss_errors_ht hash table when it is destroyed -void sqlsrv_error_const_dtor( zval* elem ) { +void sqlsrv_error_const_dtor( _Inout_ zval* elem ) { sqlsrv_error_const* error_to_ignore = static_cast( Z_PTR_P(elem) ); pefree(error_to_ignore, 1); } // called by Zend for each parameter in the g_ss_encodings_ht hash table when it is destroyed -void sqlsrv_encoding_dtor( zval* elem ) { +void sqlsrv_encoding_dtor( _Inout_ zval* elem ) { sqlsrv_encoding* sql_enc = static_cast( Z_PTR_P(elem) ); pefree(sql_enc, 1); } diff --git a/source/sqlsrv/php_sqlsrv.h b/source/sqlsrv/php_sqlsrv.h index 988254f4..59ed2c5f 100644 --- a/source/sqlsrv/php_sqlsrv.h +++ b/source/sqlsrv/php_sqlsrv.h @@ -138,7 +138,7 @@ struct ss_sqlsrv_conn : sqlsrv_conn static int descriptor; // initialize with default values - ss_sqlsrv_conn( SQLHANDLE h, error_callback e, void* drv TSRMLS_DC ) : + ss_sqlsrv_conn( _In_ SQLHANDLE h, _In_ error_callback e, _In_ void* drv TSRMLS_DC ) : sqlsrv_conn( h, e, drv, SQLSRV_ENCODING_SYSTEM TSRMLS_CC ), stmts( NULL ), date_as_string( false ), @@ -148,7 +148,7 @@ struct ss_sqlsrv_conn : sqlsrv_conn }; // resource destructor -void __cdecl sqlsrv_conn_dtor( zend_resource *rsrc TSRMLS_DC ); +void __cdecl sqlsrv_conn_dtor( _Inout_ zend_resource *rsrc TSRMLS_DC ); //********************************************************************************************************************************* // Statement @@ -162,20 +162,20 @@ struct sqlsrv_fetch_field_name { struct stmt_option_ss_scrollable : public stmt_option_functor { - virtual void operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC ); + virtual void operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ); }; // This object inherits and overrides the callbacks necessary struct ss_sqlsrv_stmt : public sqlsrv_stmt { - ss_sqlsrv_stmt( sqlsrv_conn* c, SQLHANDLE handle, error_callback e, void* drv TSRMLS_DC ); + ss_sqlsrv_stmt( _In_ sqlsrv_conn* c, _In_ SQLHANDLE handle, _In_ error_callback e, _In_ void* drv TSRMLS_DC ); virtual ~ss_sqlsrv_stmt( void ); void new_result_set( TSRMLS_D ); // driver specific conversion rules from a SQL Server/ODBC type to one of the SQLSRV_PHPTYPE_* constants - sqlsrv_phptype sql_type_to_php_type( SQLINTEGER sql_type, SQLUINTEGER size, bool prefer_string_to_stream ); + sqlsrv_phptype sql_type_to_php_type( _In_ SQLINTEGER sql_type, _In_ SQLUINTEGER size, _In_ bool prefer_string_to_stream ); bool prepared; // whether the statement has been prepared yet (used for error messages) zend_ulong conn_index; // index into the connection hash that contains this statement structure @@ -200,7 +200,7 @@ struct sqlsrv_stream_encoding { zval* stream_z; unsigned int encoding; - sqlsrv_stream_encoding( zval* str_z, unsigned int enc ) : + sqlsrv_stream_encoding( _In_ zval* str_z, _In_ unsigned int enc ) : stream_z( str_z ), encoding( enc ) { } @@ -223,14 +223,14 @@ PHP_FUNCTION(sqlsrv_rows_affected); PHP_FUNCTION(sqlsrv_send_stream_data); // resource destructor -void __cdecl sqlsrv_stmt_dtor( zend_resource *rsrc TSRMLS_DC ); +void __cdecl sqlsrv_stmt_dtor( _Inout_ zend_resource *rsrc TSRMLS_DC ); // "internal" statement functions shared by functions in conn.cpp and stmt.cpp -void bind_params( ss_sqlsrv_stmt* stmt TSRMLS_DC ); +void bind_params( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC ); bool sqlsrv_stmt_common_execute( sqlsrv_stmt* s, const SQLCHAR* sql_string, int sql_len, bool direct, const char* function TSRMLS_DC ); void free_odbc_resources( ss_sqlsrv_stmt* stmt TSRMLS_DC ); -void free_stmt_resource( zval* stmt_z TSRMLS_DC ); +void free_stmt_resource( _Inout_ zval* stmt_z TSRMLS_DC ); //********************************************************************************************************************************* // Type Functions @@ -358,7 +358,7 @@ enum SS_ERROR_CODES { extern ss_error SS_ERRORS[]; -bool ss_error_handler( sqlsrv_context& ctx, unsigned int sqlsrv_error_code, bool warning TSRMLS_DC, va_list* print_args ); +bool ss_error_handler( _Inout_ sqlsrv_context& ctx, _In_ unsigned int sqlsrv_error_code, _In_ bool warning TSRMLS_DC, _In_opt_ va_list* print_args ); // *** extension error functions *** PHP_FUNCTION(sqlsrv_errors); @@ -367,14 +367,14 @@ PHP_FUNCTION(sqlsrv_errors); // connection option to UTF-16. mbcs_len and utf16_len are sizes in // bytes. The return is the number of UTF-16 characters in the string // returned in utf16_out_string. -unsigned int convert_string_from_default_encoding( unsigned int php_encoding, char const* mbcs_in_string, - unsigned int mbcs_len, _Out_ wchar_t* utf16_out_string, - unsigned int utf16_len ); +unsigned int convert_string_from_default_encoding( _In_ unsigned int php_encoding, _In_reads_bytes_(mbcs_len) char const* mbcs_in_string, + _In_ unsigned int mbcs_len, _Out_writes_(utf16_len) __transfer(mbcs_in_string) wchar_t* utf16_out_string, + _In_ unsigned int utf16_len ); // create a wide char string from the passed in mbcs string. NULL is returned if the string // could not be created. No error is posted by this function. utf16_len is the number of // wchar_t characters, not the number of bytes. -SQLWCHAR* utf16_string_from_mbcs_string( unsigned int php_encoding, const char* mbcs_string, - unsigned int mbcs_len, _Out_ unsigned int* utf16_len ); +SQLWCHAR* utf16_string_from_mbcs_string( _In_ unsigned int php_encoding, _In_reads_bytes_(mbcs_len) const char* mbcs_string, + _In_ unsigned int mbcs_len, _Out_ unsigned int* utf16_len ); // *** internal error macros and functions *** bool handle_error( sqlsrv_context const* ctx, int log_subsystem, const char* function, @@ -420,13 +420,13 @@ public: { } - sqlsrv_context_auto_ptr( const sqlsrv_context_auto_ptr& src ) : + sqlsrv_context_auto_ptr( _Inout_opt_ const sqlsrv_context_auto_ptr& src ) : sqlsrv_auto_ptr< sqlsrv_context, sqlsrv_context_auto_ptr >( src ) { } // free the original pointer and assign a new pointer. Use NULL to simply free the pointer. - void reset( sqlsrv_context* ptr = NULL ) + void reset( _In_opt_ sqlsrv_context* ptr = NULL ) { if( _ptr ) { _ptr->~sqlsrv_context(); @@ -435,12 +435,12 @@ public: _ptr = ptr; } - sqlsrv_context* operator=( sqlsrv_context* ptr ) + sqlsrv_context* operator=( _In_opt_ sqlsrv_context* ptr ) { return sqlsrv_auto_ptr< sqlsrv_context, sqlsrv_context_auto_ptr >::operator=( ptr ); } - void operator=( sqlsrv_context_auto_ptr& src ) + void operator=( _Inout_opt_ sqlsrv_context_auto_ptr& src ) { sqlsrv_context* p = src.get(); src.transferred(); @@ -464,7 +464,7 @@ public: } // logger for ss_sqlsrv called by the core layer when it wants to log something with the LOG macro -void ss_sqlsrv_log( unsigned int severity TSRMLS_DC, const char* msg, va_list* print_args ); +void ss_sqlsrv_log( _In_ unsigned int severity TSRMLS_DC, _In_opt_ const char* msg, _In_opt_ va_list* print_args ); // subsystems that may report log messages. These may be used to filter which systems write to the log to prevent noise. enum logging_subsystems { @@ -490,7 +490,7 @@ namespace ss { } }; - inline void zend_register_resource(_Out_ zval& rsrc_result, void* rsrc_pointer, int rsrc_type, const char* rsrc_name TSRMLS_DC) + inline void zend_register_resource( _Inout_ zval& rsrc_result, _Inout_ void* rsrc_pointer, _In_ int rsrc_type, _In_opt_ const char* rsrc_name TSRMLS_DC) { int zr = (NULL != (Z_RES(rsrc_result) = ::zend_register_resource(rsrc_pointer, rsrc_type)) ? SUCCESS : FAILURE); CHECK_CUSTOM_ERROR(( zr == FAILURE ), reinterpret_cast( rsrc_pointer ), SS_SQLSRV_ERROR_REGISTER_RESOURCE, @@ -508,7 +508,7 @@ namespace ss { // generic function used to validate parameters to a PHP function. // Register an invalid parameter error and returns NULL when parameters don't match the spec given. template -inline H* process_params( INTERNAL_FUNCTION_PARAMETERS, char const* param_spec, const char* calling_func, size_t param_count, ... ) +inline H* process_params( INTERNAL_FUNCTION_PARAMETERS, _In_ char const* param_spec, _In_ const char* calling_func, _In_ size_t param_count, ... ) { SQLSRV_UNUSED( return_value ); diff --git a/source/sqlsrv/stmt.cpp b/source/sqlsrv/stmt.cpp index c08b4570..1155782b 100644 --- a/source/sqlsrv/stmt.cpp +++ b/source/sqlsrv/stmt.cpp @@ -90,23 +90,23 @@ const char SS_SQLSRV_WARNING_PARAM_VAR_NOT_REF[] = "Variable parameter %d not pa /* internal functions */ -void convert_to_zval( sqlsrv_stmt* stmt, SQLSRV_PHPTYPE sqlsrv_php_type, void* in_val, SQLLEN field_len, zval& out_zval ); +void convert_to_zval( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSRV_PHPTYPE sqlsrv_php_type, _In_opt_ void* in_val, _In_ SQLLEN field_len, _Inout_ zval& out_zval ); -void fetch_fields_common( _Inout_ ss_sqlsrv_stmt* stmt, zend_long fetch_type, _Out_ zval& fields, bool allow_empty_field_names +void fetch_fields_common( _Inout_ ss_sqlsrv_stmt* stmt, _In_ zend_long fetch_type, _Out_ zval& fields, _In_ bool allow_empty_field_names TSRMLS_DC ); -bool determine_column_size_or_precision( sqlsrv_stmt const* stmt, sqlsrv_sqltype sqlsrv_type, _Out_ SQLULEN* column_size, +bool determine_column_size_or_precision( sqlsrv_stmt const* stmt, _In_ sqlsrv_sqltype sqlsrv_type, _Inout_ SQLULEN* column_size, _Out_ SQLSMALLINT* decimal_digits ); sqlsrv_phptype determine_sqlsrv_php_type( sqlsrv_stmt const* stmt, SQLINTEGER sql_type, SQLUINTEGER size, bool prefer_string ); -void determine_stmt_has_rows( ss_sqlsrv_stmt* stmt TSRMLS_DC ); -bool is_valid_sqlsrv_phptype( sqlsrv_phptype type ); -bool is_valid_sqlsrv_sqltype( sqlsrv_sqltype type ); -void parse_param_array( ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array, zend_ulong index, _Out_ SQLSMALLINT& direction, +void determine_stmt_has_rows( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC ); +bool is_valid_sqlsrv_phptype( _In_ sqlsrv_phptype type ); +bool is_valid_sqlsrv_sqltype( _In_ sqlsrv_sqltype type ); +void parse_param_array( _Inout_ ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array, zend_ulong index, _Out_ SQLSMALLINT& direction, _Out_ SQLSRV_PHPTYPE& php_out_type, _Out_ SQLSRV_ENCODING& encoding, _Out_ SQLSMALLINT& sql_type, _Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits TSRMLS_DC ); -void type_and_encoding( INTERNAL_FUNCTION_PARAMETERS, int type ); -void type_and_size_calc( INTERNAL_FUNCTION_PARAMETERS, int type ); -void type_and_precision_calc( INTERNAL_FUNCTION_PARAMETERS, int type ); -bool verify_and_set_encoding( const char* encoding_string, _Out_ sqlsrv_phptype& phptype_encoding TSRMLS_DC ); +void type_and_encoding( INTERNAL_FUNCTION_PARAMETERS, _In_ int type ); +void type_and_size_calc( INTERNAL_FUNCTION_PARAMETERS, _In_ int type ); +void type_and_precision_calc( INTERNAL_FUNCTION_PARAMETERS, _In_ int type ); +bool verify_and_set_encoding( _In_ const char* encoding_string, _Inout_ sqlsrv_phptype& phptype_encoding TSRMLS_DC ); } @@ -120,7 +120,7 @@ namespace SSCursorTypes { const char QUERY_OPTION_SCROLLABLE_BUFFERED[] = "buffered"; } -ss_sqlsrv_stmt::ss_sqlsrv_stmt( sqlsrv_conn* c, SQLHANDLE handle, error_callback e, void* drv TSRMLS_DC ) : +ss_sqlsrv_stmt::ss_sqlsrv_stmt( _In_ sqlsrv_conn* c, _In_ SQLHANDLE handle, _In_ error_callback e, _In_ void* drv TSRMLS_DC ) : sqlsrv_stmt( c, handle, e, drv TSRMLS_CC ), prepared( false ), conn_index( -1 ), @@ -166,7 +166,7 @@ void ss_sqlsrv_stmt::new_result_set( TSRMLS_D ) } // Returns a php type for a given sql type. Also sets the encoding wherever applicable. -sqlsrv_phptype ss_sqlsrv_stmt::sql_type_to_php_type( SQLINTEGER sql_type, SQLUINTEGER size, bool prefer_string_to_stream ) +sqlsrv_phptype ss_sqlsrv_stmt::sql_type_to_php_type( _In_ SQLINTEGER sql_type, _In_ SQLUINTEGER size, _In_ bool prefer_string_to_stream ) { sqlsrv_phptype ss_phptype; ss_phptype.typeinfo.type = SQLSRV_PHPTYPE_INVALID; @@ -1168,7 +1168,7 @@ PHP_FUNCTION(SQLSRV_SQLTYPE_VARCHAR) type_and_size_calc( INTERNAL_FUNCTION_PARAM_PASSTHRU, SQL_VARCHAR ); } -void bind_params( ss_sqlsrv_stmt* stmt TSRMLS_DC ) +void bind_params( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC ) { // if there's nothing to do, just return if( stmt->params_z == NULL ) { @@ -1225,6 +1225,7 @@ void bind_params( ss_sqlsrv_stmt* stmt TSRMLS_DC ) value_z = param_z; } // bind the parameter + SQLSRV_ASSERT( value_z != NULL, "bind_params: value_z is null." ); core_sqlsrv_bind_param( stmt, index, direction, value_z, php_out_type, encoding, sql_type, column_size, decimal_digits TSRMLS_CC ); @@ -1282,7 +1283,7 @@ PHP_FUNCTION( sqlsrv_cancel ) } } -void __cdecl sqlsrv_stmt_dtor(zend_resource *rsrc TSRMLS_DC) +void __cdecl sqlsrv_stmt_dtor( _Inout_ zend_resource *rsrc TSRMLS_DC ) { LOG_FUNCTION( "sqlsrv_stmt_dtor" ); @@ -1362,6 +1363,7 @@ PHP_FUNCTION( sqlsrv_free_stmt ) // if sqlsrv_free_stmt was called on an already closed statment then we just return success. // zend_list_close sets the type of the closed statment to -1. + SQLSRV_ASSERT( stmt_r != NULL, "sqlsrv_free_stmt: stmt_r is null." ); if ( Z_RES_TYPE_P( stmt_r ) == RSRC_INVALID_TYPE ) { RETURN_TRUE; } @@ -1396,7 +1398,7 @@ PHP_FUNCTION( sqlsrv_free_stmt ) } } -void stmt_option_ss_scrollable:: operator()( sqlsrv_stmt* stmt, stmt_option const* /*opt*/, zval* value_z TSRMLS_DC ) +void stmt_option_ss_scrollable:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_option const* /*opt*/, _In_ zval* value_z TSRMLS_DC ) { CHECK_CUSTOM_ERROR(( Z_TYPE_P( value_z ) != IS_STRING ), stmt, SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE ) { throw ss::SSException(); @@ -1442,7 +1444,7 @@ void stmt_option_ss_scrollable:: operator()( sqlsrv_stmt* stmt, stmt_option cons namespace { -void convert_to_zval(sqlsrv_stmt* stmt, SQLSRV_PHPTYPE sqlsrv_php_type, void* in_val, SQLLEN field_len, zval& out_zval) +void convert_to_zval( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSRV_PHPTYPE sqlsrv_php_type, _In_opt_ void* in_val, _In_ SQLLEN field_len, _Inout_ zval& out_zval) { if ( in_val == NULL ) { ZVAL_NULL( &out_zval); @@ -1498,7 +1500,7 @@ void convert_to_zval(sqlsrv_stmt* stmt, SQLSRV_PHPTYPE sqlsrv_php_type, void* in // put in the column size and scale/decimal digits of the sql server type // these values are taken from the MSDN page at http://msdn2.microsoft.com/en-us/library/ms711786(VS.85).aspx // for SQL_VARBINARY, SQL_VARCHAR, and SQL_WLONGVARCHAR types, see https://msdn.microsoft.com/en-CA/library/ms187993.aspx -bool determine_column_size_or_precision( sqlsrv_stmt const* stmt, sqlsrv_sqltype sqlsrv_type, _Out_ SQLULEN* column_size, +bool determine_column_size_or_precision( sqlsrv_stmt const* stmt, _In_ sqlsrv_sqltype sqlsrv_type, _Inout_ SQLULEN* column_size, _Out_ SQLSMALLINT* decimal_digits ) { *decimal_digits = 0; @@ -1603,7 +1605,7 @@ bool determine_column_size_or_precision( sqlsrv_stmt const* stmt, sqlsrv_sqltype // given a SQL Server type, return a sqlsrv php type -sqlsrv_phptype determine_sqlsrv_php_type( ss_sqlsrv_stmt const* stmt, SQLINTEGER sql_type, SQLUINTEGER size, bool prefer_string ) +sqlsrv_phptype determine_sqlsrv_php_type( _In_ ss_sqlsrv_stmt const* stmt, _In_ SQLINTEGER sql_type, _In_ SQLUINTEGER size, _In_ bool prefer_string ) { sqlsrv_phptype sqlsrv_phptype; sqlsrv_phptype.typeinfo.type = PHPTYPE_INVALID; @@ -1700,7 +1702,7 @@ sqlsrv_phptype determine_sqlsrv_php_type( ss_sqlsrv_stmt const* stmt, SQLINTEGER // The return value simply states whether or not if an error occurred during the determination. // (All errors are posted here before returning.) -void determine_stmt_has_rows( ss_sqlsrv_stmt* stmt TSRMLS_DC ) +void determine_stmt_has_rows( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC ) { SQLRETURN r = SQL_SUCCESS; @@ -1749,7 +1751,7 @@ void determine_stmt_has_rows( ss_sqlsrv_stmt* stmt TSRMLS_DC ) } } -void fetch_fields_common( _Inout_ ss_sqlsrv_stmt* stmt, zend_long fetch_type, _Out_ zval& fields, bool allow_empty_field_names +void fetch_fields_common( _Inout_ ss_sqlsrv_stmt* stmt, _In_ zend_long fetch_type, _Out_ zval& fields, _In_ bool allow_empty_field_names TSRMLS_DC ) { void* field_value = NULL; @@ -1849,7 +1851,7 @@ void fetch_fields_common( _Inout_ ss_sqlsrv_stmt* stmt, zend_long fetch_type, _O } -void parse_param_array( ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array, zend_ulong index, _Out_ SQLSMALLINT& direction, +void parse_param_array( _Inout_ ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array, zend_ulong index, _Out_ SQLSMALLINT& direction, _Out_ SQLSRV_PHPTYPE& php_out_type, _Out_ SQLSRV_ENCODING& encoding, _Out_ SQLSMALLINT& sql_type, _Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits TSRMLS_DC ) @@ -2022,7 +2024,7 @@ void parse_param_array( ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array, zend_ul } } -bool is_valid_sqlsrv_phptype( sqlsrv_phptype type ) +bool is_valid_sqlsrv_phptype( _In_ sqlsrv_phptype type ) { switch( type.typeinfo.type ) { @@ -2047,7 +2049,7 @@ bool is_valid_sqlsrv_phptype( sqlsrv_phptype type ) // return if the type is a valid sql server type not including // size, precision or scale. Use determine_precision_and_scale for that. -bool is_valid_sqlsrv_sqltype( sqlsrv_sqltype sql_type ) +bool is_valid_sqlsrv_sqltype( _In_ sqlsrv_sqltype sql_type ) { switch( sql_type.typeinfo.type ) { case SQL_BIGINT: @@ -2084,21 +2086,23 @@ bool is_valid_sqlsrv_sqltype( sqlsrv_sqltype sql_type ) // verify an encoding given to type_and_encoding by looking through the list // of standard encodings created at module initialization time -bool verify_and_set_encoding( const char* encoding_string, _Out_ sqlsrv_phptype& phptype_encoding TSRMLS_DC ) +bool verify_and_set_encoding( _In_ const char* encoding_string, _Inout_ sqlsrv_phptype& phptype_encoding TSRMLS_DC ) { void* encoding_temp = NULL; zend_ulong index = -1; zend_string* key = NULL; ZEND_HASH_FOREACH_KEY_PTR( g_ss_encodings_ht, index, key, encoding_temp ) { - if ( !encoding_temp ) { - DIE( "Fatal: Error retrieving encoding from encoding hash table." ); - } - sqlsrv_encoding* encoding = reinterpret_cast( encoding_temp ); - encoding_temp = NULL; - if( !stricmp( encoding_string, encoding->iana )) { - phptype_encoding.typeinfo.encoding = encoding->code_page; - return true; - } + if (encoding_temp) { + sqlsrv_encoding* encoding = reinterpret_cast(encoding_temp); + encoding_temp = NULL; + if (!stricmp(encoding_string, encoding->iana)) { + phptype_encoding.typeinfo.encoding = encoding->code_page; + return true; + } + } + else { + DIE("Fatal: Error retrieving encoding from encoding hash table."); + } } ZEND_HASH_FOREACH_END(); return false; @@ -2106,7 +2110,7 @@ bool verify_and_set_encoding( const char* encoding_string, _Out_ sqlsrv_phptype& // called when one of the SQLSRV_SQLTYPE type functions is called. Encodes the type and size // into a sqlsrv_sqltype bit fields (see php_sqlsrv.h). -void type_and_size_calc( INTERNAL_FUNCTION_PARAMETERS, int type ) +void type_and_size_calc( INTERNAL_FUNCTION_PARAMETERS, _In_ int type ) { char* size_p = NULL; size_t size_len = 0; @@ -2116,20 +2120,24 @@ void type_and_size_calc( INTERNAL_FUNCTION_PARAMETERS, int type ) return; } - - if( !strnicmp( "max", size_p, sizeof( "max" ) / sizeof(char)) ) { - size = SQLSRV_SIZE_MAX_TYPE; + if (size_p) { + if (!strnicmp("max", size_p, sizeof("max") / sizeof(char))) { + size = SQLSRV_SIZE_MAX_TYPE; + } + else { +#ifndef _WIN32 + errno = 0; +#else + _set_errno(0); // reset errno for atol +#endif // !_WIN32 + size = atol(size_p); + if (errno != 0) { + size = SQLSRV_INVALID_SIZE; + } + } } else { -#ifndef _WIN32 - errno = 0; -#else - _set_errno(0); // reset errno for atol -#endif // !_WIN32 - size = atol( size_p ); - if( errno != 0 ) { - size = SQLSRV_INVALID_SIZE; - } + DIE("type_and_size_calc: size_p is null."); } int max_size = SQL_SERVER_MAX_FIELD_SIZE; @@ -2154,7 +2162,7 @@ void type_and_size_calc( INTERNAL_FUNCTION_PARAMETERS, int type ) // called when the user gives SQLSRV_SQLTYPE_DECIMAL or SQLSRV_SQLTYPE_NUMERIC sql types as the type of the // field. encodes these into a sqlsrv_sqltype structure (see php_sqlsrv.h) -void type_and_precision_calc( INTERNAL_FUNCTION_PARAMETERS, int type ) +void type_and_precision_calc( INTERNAL_FUNCTION_PARAMETERS, _In_ int type ) { zend_long prec = SQLSRV_INVALID_PRECISION; zend_long scale = SQLSRV_INVALID_SCALE; @@ -2189,7 +2197,7 @@ void type_and_precision_calc( INTERNAL_FUNCTION_PARAMETERS, int type ) // common code for SQLSRV_PHPTYPE_STREAM and SQLSRV_PHPTYPE_STRING php types given as parameters. // encodes the type and encoding into a sqlsrv_phptype structure (see php_sqlsrv.h) -void type_and_encoding( INTERNAL_FUNCTION_PARAMETERS, int type ) +void type_and_encoding( INTERNAL_FUNCTION_PARAMETERS, _In_ int type ) { SQLSRV_ASSERT(( type == SQLSRV_PHPTYPE_STREAM || type == SQLSRV_PHPTYPE_STRING ), "type_and_encoding: Invalid type passed." ); diff --git a/source/sqlsrv/util.cpp b/source/sqlsrv/util.cpp index 352e5c24..cc03d78d 100644 --- a/source/sqlsrv/util.cpp +++ b/source/sqlsrv/util.cpp @@ -34,15 +34,15 @@ char log_msg[ LOG_MSG_SIZE ]; SQLCHAR INTERNAL_FORMAT_ERROR[] = "An internal error occurred. FormatMessage failed writing an error message."; // *** internal functions *** -sqlsrv_error_const* get_error_message( unsigned int sqlsrv_error_code ); +sqlsrv_error_const* get_error_message( _In_ unsigned int sqlsrv_error_code ); -void copy_error_to_zval( zval* error_z, sqlsrv_error_const* error, zval* reported_chain, zval* ignored_chain, - bool warning TSRMLS_DC ); -bool ignore_warning( char* sql_state, int native_code TSRMLS_DC ); -bool handle_errors_and_warnings( sqlsrv_context& ctx, zval* reported_chain, zval* ignored_chain, logging_severity log_severity, - unsigned int sqlsrv_error_code, bool warning, va_list* print_args TSRMLS_DC ); +void copy_error_to_zval( _Inout_ zval* error_z, _In_ sqlsrv_error_const* error, _Inout_ zval* reported_chain, _Inout_ zval* ignored_chain, + _In_ bool warning TSRMLS_DC ); +bool ignore_warning( _In_ char* sql_state, _In_ int native_code TSRMLS_DC ); +bool handle_errors_and_warnings( _Inout_ sqlsrv_context& ctx, _Inout_ zval* reported_chain, _Inout_ zval* ignored_chain, _In_ logging_severity log_severity, + _In_ unsigned int sqlsrv_error_code, _In_ bool warning, _In_opt_ va_list* print_args TSRMLS_DC ); -int sqlsrv_merge_zend_hash_dtor( zval* dest TSRMLS_DC ); +int sqlsrv_merge_zend_hash_dtor( _Inout_ zval* dest TSRMLS_DC ); bool sqlsrv_merge_zend_hash( _Inout_ zval* dest_z, zval const* src_z TSRMLS_DC ); } @@ -382,7 +382,7 @@ ss_error SS_ERRORS[] = { }; // Formats an error message and finally writes it to the php log. -void ss_sqlsrv_log( unsigned int severity TSRMLS_DC, const char* msg, va_list* print_args ) +void ss_sqlsrv_log( _In_ unsigned int severity TSRMLS_DC, _In_opt_ const char* msg, _In_opt_ va_list* print_args ) { if(( severity & SQLSRV_G( log_severity )) && ( SQLSRV_G( current_subsystem ) & SQLSRV_G( log_subsystems ))) { @@ -398,7 +398,7 @@ void ss_sqlsrv_log( unsigned int severity TSRMLS_DC, const char* msg, va_list* p } } -bool ss_error_handler(sqlsrv_context& ctx, unsigned int sqlsrv_error_code, bool warning TSRMLS_DC, va_list* print_args ) +bool ss_error_handler( _Inout_ sqlsrv_context& ctx, _In_ unsigned int sqlsrv_error_code, _In_ bool warning TSRMLS_DC, _In_opt_ va_list* print_args ) { logging_severity severity = SEV_ERROR; if( warning && !SQLSRV_G( warnings_return_as_errors )) { @@ -528,6 +528,7 @@ PHP_FUNCTION( sqlsrv_configure ) } // WarningsReturnAsErrors + SQLSRV_ASSERT( option[option_len] == '\0', "sqlsrv_configure: option was not null terminated." ); if( !stricmp( option, INI_WARNINGS_RETURN_AS_ERRORS )) { SQLSRV_G( warnings_return_as_errors ) = zend_is_true( value_z ) ? true : false; @@ -645,7 +646,7 @@ PHP_FUNCTION( sqlsrv_get_config ) throw ss::SSException(); } - + SQLSRV_ASSERT( option != NULL, "sqlsrv_get_config: option was null." ); if( !stricmp( option, INI_WARNINGS_RETURN_AS_ERRORS )) { ZVAL_BOOL( return_value, SQLSRV_G( warnings_return_as_errors )); @@ -698,8 +699,8 @@ sqlsrv_error_const* get_error_message( unsigned int sqlsrv_error_code ) { return error_message; } -void copy_error_to_zval( zval* error_z, sqlsrv_error_const* error, zval* reported_chain, zval* ignored_chain, - bool warning TSRMLS_DC ) +void copy_error_to_zval( _Inout_ zval* error_z, _In_ sqlsrv_error_const* error, _Inout_ zval* reported_chain, _Inout_ zval* ignored_chain, + _In_ bool warning TSRMLS_DC ) { if( array_init( error_z ) == FAILURE ) { @@ -775,8 +776,8 @@ void copy_error_to_zval( zval* error_z, sqlsrv_error_const* error, zval* reporte } } -bool handle_errors_and_warnings( sqlsrv_context& ctx, zval* reported_chain, zval* ignored_chain, logging_severity log_severity, - unsigned int sqlsrv_error_code, bool warning, va_list* print_args TSRMLS_DC ) +bool handle_errors_and_warnings( _Inout_ sqlsrv_context& ctx, _Inout_ zval* reported_chain, _Inout_ zval* ignored_chain, _In_ logging_severity log_severity, + _In_ unsigned int sqlsrv_error_code, _In_ bool warning, _In_opt_ va_list* print_args TSRMLS_DC ) { bool result = true; bool errors_ignored = false; @@ -863,7 +864,7 @@ bool handle_errors_and_warnings( sqlsrv_context& ctx, zval* reported_chain, zval // return whether or not a warning should be ignored or returned as an error if WarningsReturnAsErrors is true // see RINIT in init.cpp for information about which errors are ignored. -bool ignore_warning( char* sql_state, int native_code TSRMLS_DC ) +bool ignore_warning( _In_ char* sql_state, _In_ int native_code TSRMLS_DC ) { zend_ulong index = -1; zend_string* key = NULL; @@ -884,7 +885,7 @@ bool ignore_warning( char* sql_state, int native_code TSRMLS_DC ) return false; } -int sqlsrv_merge_zend_hash_dtor( zval* dest TSRMLS_DC ) +int sqlsrv_merge_zend_hash_dtor( _Inout_ zval* dest TSRMLS_DC ) { zval_ptr_dtor( dest ); return ZEND_HASH_APPLY_REMOVE;