Fixes suggested by Semmle (#1068)

* Fixes suggested by Semmle

* Updated azure-pipelines
This commit is contained in:
David Puglielli 2019-12-17 16:25:57 -08:00 committed by GitHub
parent afa217f002
commit eeec2f838d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 286 additions and 293 deletions

View file

@ -2,7 +2,7 @@
# https://aka.ms/yaml
variables:
phpVersion: 7.3
phpVersion: 7.4
server: 'localhost,1433'
host: 'sql1'
sqlsrv_db: 'sqlsrv_testdb'
@ -70,7 +70,7 @@ jobs:
inputs:
versionSpec: '3.6'
architecture: 'x64'
- script: |
sudo update-alternatives --set php /usr/bin/php$(phpVersion)
sudo update-alternatives --set phar /usr/bin/phar$(phpVersion)
@ -109,13 +109,13 @@ jobs:
sudo sed -i 's/# en_US ISO-8859-1/en_US ISO-8859-1/g' /etc/locale.gen
sudo locale-gen en_US
sudo locale-gen en_US.UTF-8
export LANG='en_US.UTF-8'
export LANGUAGE='en_US:en'
export LANG='en_US.UTF-8'
export LANGUAGE='en_US:en'
export LC_ALL='en_US.UTF-8'
displayName: 'Generate locales for testing'
- script: |
echo setting env variables
echo setting env variables
export TEST_PHP_SQL_SERVER='$(server)'
export TEST_PHP_SQL_UID='$(uid)'
export TEST_PHP_SQL_PWD='$(pwd)'
@ -132,7 +132,7 @@ jobs:
./packagize.sh
dest=`php --ini | grep "Scan for additional .ini files" | sudo sed -e "s|.*:\s*||"`/
cd $(Build.SourcesDirectory)/source/sqlsrv
ls -al
phpize && ./configure && make && sudo make install
@ -141,7 +141,7 @@ jobs:
echo copying sqlsrv to $dest
sudo cp 20-sqlsrv.ini $dest
cd $(Build.SourcesDirectory)/source/pdo_sqlsrv
ls -al
phpize && ./configure && make && sudo make install
@ -160,7 +160,7 @@ jobs:
sed -i -e 's/TARGET_SERVER/'"$(server)"'/g' MsSetup.inc
sed -i -e 's/TARGET_DATABASE/'"$(sqlsrv_db)"'/g' MsSetup.inc
sed -i -e 's/TARGET_USERNAME/'"$(uid)"'/g' MsSetup.inc
sed -i -e 's/TARGET_PASSWORD/'"$(pwd)"'/g' MsSetup.inc
sed -i -e 's/TARGET_PASSWORD/'"$(pwd)"'/g' MsSetup.inc
php run-tests.php -P ./*.phpt 2>&1 | tee ../sqlsrv.log
displayName: 'Run sqlsrv functional tests'
@ -170,7 +170,7 @@ jobs:
sed -i -e 's/TARGET_SERVER/'"$(server)"'/g' MsSetup.inc
sed -i -e 's/TARGET_DATABASE/'"$(pdo_sqlsrv_db)"'/g' MsSetup.inc
sed -i -e 's/TARGET_USERNAME/'"$(uid)"'/g' MsSetup.inc
sed -i -e 's/TARGET_PASSWORD/'"$(pwd)"'/g' MsSetup.inc
sed -i -e 's/TARGET_PASSWORD/'"$(pwd)"'/g' MsSetup.inc
php run-tests.php -P ./*.phpt 2>&1 | tee ../pdo_sqlsrv.log
displayName: 'Run pdo_sqlsrv functional tests'
@ -194,7 +194,7 @@ jobs:
docker stop $(host)
docker rm $(host)
displayName: 'Stop SQL Server for Linux'
condition: always()
condition: always()
- job: Windows
pool:
@ -249,7 +249,7 @@ jobs:
- script: msiexec /i "msodbcsql_13.1.msi" /q IACCEPTMSODBCSQLLICENSETERMS=YES ADDLOCAL=ALL
condition: false
# FOR SOME REASON the set up did not set the PATH
# FOR SOME REASON the set up did not set the PATH
- script: |
msiexec /i "MsSqlCmdLnUtils.msi" /qn IACCEPTMSSQLCMDLNUTILSLICENSETERMS=YES
displayName: 'Install SQL command line utilities version 15'
@ -260,7 +260,7 @@ jobs:
$client.Headers.Add("user-agent", "azure pipeline build")
$client.DownloadFile("https://windows.php.net/downloads/releases/sha256sum.txt", "sha256sum.txt")
$env:VERSION=type sha256sum.txt | where { $_ -match "php-($(phpVersion)\.\d+)-src" } | foreach { $matches[1] }
Write-Host "Latest PHP $(phpVersion) is ${env:VERSION}"
Write-Host "Latest PHP $(phpVersion) is ${env:VERSION}"
cd $(Build.SourcesDirectory)/buildscripts/
python builddrivers.py --PHPVER=${env:VERSION} --DRIVER=sqlsrv --ARCH=x64 --THREAD=nts --SOURCE=$(Build.SourcesDirectory)/source --TESTING --NO_RENAME
dir *sqlsrv*.dll
@ -270,7 +270,7 @@ jobs:
dir *sqlsrv*.dll
cp *sqlsrv*.dll C:\tools\php\ext\
displayName: 'Build drivers (separately) for the latest version of PHP $(phpVersion)'
- script: |
echo extension=php_sqlsrv.dll >> C:\tools\php\php.ini
echo extension=php_pdo_sqlsrv.dll >> C:\tools\php\php.ini
@ -285,7 +285,7 @@ jobs:
displayName: 'Run SQL Server for Windows Server'
condition: false
- script: |
- script: |
set path=C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\;%path%
sqlcmd -S $(host) -U $(uid) -P $(pwd) -Q "SELECT @@Version"
set TEST_PHP_SQL_SERVER=$(host)
@ -309,4 +309,4 @@ jobs:
docker stop sqlcontainer
docker rm sqlcontainer
displayName: 'Stop SQL Server for Windows Server'
condition: false
condition: false

View file

@ -10,13 +10,13 @@
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//---------------------------------------------------------------------------------------------------------------------------------
@ -28,7 +28,7 @@
#undef SQL_WCHART_CONVERT
#endif
#ifndef _WCHART_DEFINED
#define _WCHART_DEFINED
#define _WCHART_DEFINED
#endif
#include "php.h"
@ -54,8 +54,6 @@
#define PHP_SQLSRV_API
#endif
// #define MultiByteToWideChar SystemLocale::ToUtf16
#define stricmp strcasecmp
#define strnicmp strncasecmp
#define strnlen_s(s) strnlen_s(s, INT_MAX)
@ -103,10 +101,10 @@ extern "C" {
#endif
#if _MSC_VER >= 1400
// typedef and macro to prevent a conflict between php.h and ws2tcpip.h.
// php.h defines this constant as unsigned int which causes a compile error
// typedef and macro to prevent a conflict between php.h and ws2tcpip.h.
// php.h defines this constant as unsigned int which causes a compile error
// in ws2tcpip.h. Fortunately php.h allows an override by defining
// HAVE_SOCKLEN_T. Since ws2tcpip.h isn't included until later, we define
// HAVE_SOCKLEN_T. Since ws2tcpip.h isn't included until later, we define
// socklen_t here and override the php.h version.
typedef int socklen_t;
#define HAVE_SOCKLEN_T
@ -142,7 +140,7 @@ OACR_WARNING_POP
#define WC_ERR_INVALID_CHARS 0x00000080 // error for invalid chars
#endif
// PHP defines inline as __forceinline, which in debug mode causes a warning to be emitted when
// PHP defines inline as __forceinline, which in debug mode causes a warning to be emitted when
// we use std::copy, which causes compilation to fail since we compile with warnings as errors.
#if defined(ZEND_DEBUG) && defined(inline)
#undef inline
@ -190,7 +188,7 @@ const long ACTIVE_NUM_ROWS_INVALID = -99;
const int SQL_SERVER_2005_DEFAULT_DATETIME_PRECISION = 23;
const int SQL_SERVER_2005_DEFAULT_DATETIME_SCALE = 3;
const int SQL_SERVER_2008_DEFAULT_DATETIME_PRECISION = 34;
const int SQL_SERVER_2008_DEFAULT_DATETIME_SCALE = 7;
const int SQL_SERVER_2008_DEFAULT_DATETIME_SCALE = 7;
namespace AzureADOptions {
const char AZURE_AUTH_SQL_PASSWORD[] = "SqlPassword";
@ -215,7 +213,7 @@ enum SQLSRV_PHPTYPE {
};
// encodings supported by this extension. These basically translate into the use of SQL_C_CHAR or SQL_C_BINARY when getting
// information as a string or a stream.
// information as a string or a stream.
enum SQLSRV_ENCODING {
SQLSRV_ENCODING_INVALID, // unknown or invalid encoding. Used to initialize variables.
SQLSRV_ENCODING_DEFAULT, // use what is the connection's default for a statement, use system if a connection
@ -263,7 +261,7 @@ union sqlsrv_sqltype {
// SQLSRV PHP types (as opposed to the Zend PHP type constants). Contains the type (see SQLSRV_PHPTYPE)
// and the encoding for strings and streams (see SQLSRV_ENCODING)
// and the encoding for strings and streams (see SQLSRV_ENCODING)
union sqlsrv_phptype {
@ -325,8 +323,8 @@ void die( _In_opt_ const char* msg, ... );
#pragma push_macro( "max" )
#undef max
// new memory allocation/free debugging facilities to help us verify that all allocations are being
// released in a timely manner and not just at the end of the script.
// new memory allocation/free debugging facilities to help us verify that all allocations are being
// released in a timely manner and not just at the end of the script.
// Zend has memory logging and checking, but it can generate a lot of noise for just one extension.
// It's meant for internal use but might be useful for people adding features to our extension.
// To use it, uncomment the #define below and compile in Debug NTS. All allocations and releases
@ -435,7 +433,7 @@ struct remove_const<const T*> {
// this allows us to use STL classes that still work with Zend objects
template<typename T>
struct sqlsrv_allocator {
// typedefs used by the STL classes
typedef T value_type;
typedef value_type* pointer;
@ -459,8 +457,8 @@ struct sqlsrv_allocator {
// address (doesn't work if the class defines operator&)
inline pointer address( _In_ reference r )
{
return &r;
{
return &r;
}
inline const_pointer address( _In_ const_reference r )
@ -469,20 +467,20 @@ struct sqlsrv_allocator {
}
// memory allocation/deallocation
inline pointer allocate( _In_ size_type cnt,
inline pointer allocate( _In_ size_type cnt,
typename std::allocator<void>::const_pointer = 0 )
{
return reinterpret_cast<pointer>( sqlsrv_malloc(cnt, sizeof (T), 0));
return reinterpret_cast<pointer>( sqlsrv_malloc(cnt, sizeof (T), 0));
}
inline void deallocate( _Inout_ pointer p, size_type )
{
sqlsrv_free(p);
inline void deallocate( _Inout_ pointer p, size_type )
{
sqlsrv_free(p);
}
// size
inline size_type max_size( void ) const
{
inline size_type max_size( void ) const
{
return std::numeric_limits<size_type>::max() / sizeof(T);
}
@ -507,11 +505,11 @@ struct sqlsrv_allocator {
{
return !operator==(a);
}
};
};
// base class for auto_ptrs that we define below. It provides common operators and functions
// used by all the classes.
// base class for auto_ptrs that we define below. It provides common operators and functions
// used by all the classes.
template <typename T, typename Subclass>
class sqlsrv_auto_ptr {
@ -576,8 +574,8 @@ public:
return _ptr[index];
}
#ifdef __WIN64
#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[]( _In_ std::size_t index ) const
@ -616,7 +614,7 @@ public:
protected:
sqlsrv_auto_ptr( _In_opt_ T* ptr ) :
_ptr( ptr )
_ptr( ptr )
{
}
@ -637,7 +635,7 @@ protected:
return ptr;
}
T* _ptr;
T* _ptr;
};
// an auto_ptr for sqlsrv_malloc/sqlsrv_free. When allocating a chunk of memory using sqlsrv_malloc, wrap that pointer
@ -684,13 +682,13 @@ 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( _In_ size_t new_size )
{
{
sqlsrv_auto_ptr<T,sqlsrv_malloc_auto_ptr<T> >::_ptr = reinterpret_cast<T*>( sqlsrv_realloc( sqlsrv_auto_ptr<T,sqlsrv_malloc_auto_ptr<T> >::_ptr, new_size ));
}
};
// auto ptr for Zend hash tables. Used to clean up a hash table allocated when
// auto ptr for Zend hash tables. Used to clean up a hash table allocated when
// something caused an early exit from the function. This is used when the hash_table is
// allocated in a zval that itself can't be released. Otherwise, use the zval_auto_ptr.
@ -726,8 +724,8 @@ private:
};
// an auto_ptr for zvals. When allocating a zval, wrap that pointer in a variable of zval_auto_ptr.
// zval_auto_ptr will "own" that zval and assure that it is freed when the variable is destroyed
// an auto_ptr for zvals. When allocating a zval, wrap that pointer in a variable of zval_auto_ptr.
// zval_auto_ptr will "own" that zval and assure that it is freed when the variable is destroyed
// (out of scope) or ownership is transferred using the function "transferred".
class zval_auto_ptr : public sqlsrv_auto_ptr<zval, zval_auto_ptr> {
@ -798,7 +796,7 @@ struct sqlsrv_error : public sqlsrv_error_const {
native_code = code;
format = printf_format;
}
sqlsrv_error( _In_ sqlsrv_error_const const& prototype )
{
sqlsrv_error( prototype.sqlstate, prototype.native_message, prototype.native_code, prototype.format );
@ -865,8 +863,8 @@ class sqlsrv_context;
struct sqlsrv_conn;
// error_callback
// a driver specific callback for processing errors.
// ctx - the context holding the handles
// 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)( _Inout_ sqlsrv_context& ctx, _In_ unsigned int sqlsrv_error_code, _In_ bool error TSRMLS_DC, _In_opt_ va_list* print_args );
@ -910,7 +908,7 @@ class sqlsrv_context {
}
virtual ~sqlsrv_context()
{
{
}
void set_func( _In_z_ const char* f )
@ -927,7 +925,7 @@ class sqlsrv_context {
{
return last_error_;
}
// since the primary responsibility of a context is to hold an ODBC handle, we
// provide these convenience operators for using them interchangeably
operator SQLHANDLE ( void ) const
@ -997,7 +995,7 @@ class sqlsrv_context {
error_callback err_; // driver error callback if error occurs in core layer
void* driver_; // points back to the driver for PDO
sqlsrv_error_auto_ptr last_error_; // last error that happened on this object
SQLSRV_ENCODING encoding_; // encoding of the context
SQLSRV_ENCODING encoding_; // encoding of the context
};
// maps an IANA encoding to a code page
@ -1064,7 +1062,7 @@ enum DRIVER_VERSION {
struct sqlsrv_stmt;
struct stmt_option;
// This holds the various details of column encryption.
// This holds the various details of column encryption.
struct col_encryption_option {
bool enabled; // column encryption enabled, false by default
SQLINTEGER akv_mode;
@ -1105,13 +1103,13 @@ struct sqlsrv_conn : public sqlsrv_context {
driver_version = ODBC_DRIVER_UNKNOWN;
}
// sqlsrv_conn has no destructor since its allocated using placement new, which requires that the destructor be
// sqlsrv_conn has no destructor since its allocated using placement new, which requires that the destructor be
// called manually. Instead, we leave it to the allocator to invalidate the handle when an error occurs allocating
// the sqlsrv_conn with a connection.
};
enum SQLSRV_STMT_OPTIONS {
SQLSRV_STMT_OPTION_INVALID,
SQLSRV_STMT_OPTION_QUERY_TIMEOUT,
SQLSRV_STMT_OPTION_SEND_STREAMS_AT_EXEC,
@ -1164,7 +1162,7 @@ const char SERVER[] = "Server";
}
enum SQLSRV_CONN_OPTIONS {
SQLSRV_CONN_OPTION_INVALID,
SQLSRV_CONN_OPTION_APP,
SQLSRV_CONN_OPTION_ACCESS_TOKEN,
@ -1200,7 +1198,7 @@ enum SQLSRV_CONN_OPTIONS {
// Driver specific connection options
SQLSRV_CONN_OPTION_DRIVER_SPECIFIC = 1000,
};
@ -1220,7 +1218,7 @@ struct connection_option {
// the name of the option as passed in by the user
const char * sqlsrv_name;
unsigned int sqlsrv_len;
unsigned int conn_option_key;
// the name of the option in the ODBC connection string
const char * odbc_name;
@ -1247,7 +1245,7 @@ struct column_encryption_set_func {
static void func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str TSRMLS_DC );
};
struct driver_set_func {
struct driver_set_func {
static void func( _In_ connection_option const* option, _In_ zval* value, _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str TSRMLS_DC );
};
@ -1265,8 +1263,8 @@ typedef sqlsrv_conn* (*driver_conn_factory)( _In_ SQLHANDLE h, _In_ error_callba
// *** connection functions ***
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[],
_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 core_odbc_connect( _Inout_ sqlsrv_conn* conn, _Inout_ std::string& conn_str, _In_ bool is_pooled );
void core_sqlsrv_close( _Inout_opt_ sqlsrv_conn* conn TSRMLS_DC );
@ -1332,9 +1330,9 @@ struct stmt_option {
const char * name; // name of the statement option
unsigned int name_len; // name length
unsigned int key;
unsigned int key;
std::unique_ptr<stmt_option_functor> func; // callback that actually handles the work of the option
};
// holds the stream param and the encoding that it was assigned
@ -1368,9 +1366,9 @@ extern php_stream_wrapper g_sqlsrv_stream_wrapper;
// *** parameter metadata struct ***
struct param_meta_data
{
SQLSMALLINT sql_type;
SQLSMALLINT sql_type;
SQLSMALLINT decimal_digits;
SQLSMALLINT nullable;
SQLSMALLINT nullable;
SQLULEN column_size;
param_meta_data() : sql_type(0), decimal_digits(0), column_size(0), nullable(0)
@ -1416,16 +1414,16 @@ struct sqlsrv_output_param {
{
}
void saveMetaData(SQLSMALLINT sql_type, SQLSMALLINT column_size, SQLSMALLINT decimal_digits, SQLSMALLINT nullable = SQL_NULLABLE)
{
void saveMetaData(SQLSMALLINT sql_type, SQLSMALLINT column_size, SQLSMALLINT decimal_digits, SQLSMALLINT nullable = SQL_NULLABLE)
{
meta_data.sql_type = sql_type;
meta_data.column_size = column_size;
meta_data.decimal_digits = decimal_digits;
meta_data.nullable = nullable;
}
param_meta_data& getMetaData()
{
param_meta_data& getMetaData()
{
return meta_data;
}
};
@ -1472,13 +1470,13 @@ namespace data_classification {
{
}
~column_sensitivity()
~column_sensitivity()
{
label_info_pairs.clear();
}
};
struct sensitivity_metadata {
struct sensitivity_metadata {
USHORT num_labels;
std::vector<name_id_pair*, sqlsrv_allocator<name_id_pair*>> labels;
USHORT num_infotypes;
@ -1491,7 +1489,7 @@ namespace data_classification {
}
~sensitivity_metadata()
{
{
reset();
}
@ -1503,7 +1501,7 @@ namespace data_classification {
struct sqlsrv_result_set;
struct field_meta_data;
// *** Statement resource structure ***
// *** Statement resource structure ***
struct sqlsrv_stmt : public sqlsrv_context {
void free_param_data( TSRMLS_D );
@ -1513,13 +1511,13 @@ struct sqlsrv_stmt : public sqlsrv_context {
void clean_up_sensitivity_metadata();
sqlsrv_conn* conn; // Connection that created this statement
bool executed; // Whether the statement has been executed yet (used for error messages)
bool past_fetch_end; // Core_sqlsrv_fetch sets this field when the statement goes beyond the last row
sqlsrv_result_set* current_results; // Current result set
SQLULEN cursor_type; // Type of cursor for the current result set
bool has_rows; // Has_rows is set if there are actual rows in the row set
bool fetch_called; // Used by core_sqlsrv_get_field to return an informative error if fetch not yet called
bool fetch_called; // Used by core_sqlsrv_get_field to return an informative error if fetch not yet called
int last_field_index; // last field retrieved by core_sqlsrv_get_field
bool past_next_result_end; // core_sqlsrv_next_result sets this to true when the statement goes beyond the last results
short column_count; // Number of columns in the current result set obtained from SQLNumResultCols
@ -1529,7 +1527,7 @@ struct sqlsrv_stmt : public sqlsrv_context {
bool date_as_string; // false by default but the user can set this to true to retrieve datetime values as strings
bool format_decimals; // false by default but the user can set this to true to add the missing leading zeroes and/or control number of decimal digits to show
short decimal_places; // indicates number of decimals shown in fetched results (-1 by default, which means no change to number of decimal digits)
bool data_classification; // false by default but the user can set this to true to retrieve data classification sensitivity metadata
bool data_classification; // false by default but the user can set this to true to retrieve data classification sensitivity metadata
// holds output pointers for SQLBindParameter
// We use a deque because it 1) provides the at/[] access in constant time, and 2) grows dynamically without moving
@ -1541,10 +1539,10 @@ struct sqlsrv_stmt : public sqlsrv_context {
zval param_datetime_buffers; // datetime strings to be converted back to DateTime objects
bool send_streams_at_exec; // send all stream data right after execution before returning
sqlsrv_stream current_stream; // current stream sending data to the server as an input parameter
unsigned int current_stream_read; // # of bytes read so far. (if we read an empty PHP stream, we send an empty string
unsigned int current_stream_read; // # of bytes read so far. (if we read an empty PHP stream, we send an empty string
// to the server)
zval field_cache; // cache for a single row of fields, to allow multiple and out of order retrievals
zval col_cache; // Used by get_field_as_string not to call SQLColAttribute() after every fetch.
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
std::vector<param_meta_data> param_descriptions;
@ -1573,7 +1571,7 @@ struct field_meta_data {
SQLSMALLINT field_type;
SQLULEN field_size;
SQLULEN field_precision;
SQLSMALLINT field_scale;
SQLSMALLINT field_scale;
SQLSMALLINT field_is_nullable;
bool field_is_money_type;
sqlsrv_phptype sqlsrv_php_type;
@ -1584,7 +1582,7 @@ struct field_meta_data {
reset_php_type();
}
~field_meta_data()
~field_meta_data()
{
}
@ -1614,7 +1612,7 @@ 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( _Inout_ sqlsrv_conn* conn, _In_ driver_stmt_factory stmt_factory, _In_opt_ HashTable* options_ht,
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, _Inout_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size,
@ -1660,7 +1658,7 @@ struct sqlsrv_result_set {
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( _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier,
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;
@ -1677,7 +1675,7 @@ struct sqlsrv_odbc_result_set : public sqlsrv_result_set {
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,
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 );
@ -1715,13 +1713,13 @@ struct sqlsrv_buffered_result_set : public sqlsrv_result_set {
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( _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier,
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
// buffered result set specific
SQLSMALLINT column_count( void )
{
return col_count;
@ -1758,7 +1756,7 @@ struct sqlsrv_buffered_result_set : public sqlsrv_result_set {
// string conversion functions
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,
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 );
@ -1839,7 +1837,7 @@ enum SQLSRV_ERROR_CODES {
SQLSRV_ERROR_INPUT_PARAM_ENCODING_TRANSLATE,
SQLSRV_ERROR_OUTPUT_PARAM_ENCODING_TRANSLATE,
SQLSRV_ERROR_CONNECT_STRING_ENCODING_TRANSLATE,
SQLSRV_ERROR_ZEND_STREAM,
SQLSRV_ERROR_ZEND_STREAM,
SQLSRV_ERROR_INPUT_STREAM_ENCODING_TRANSLATE,
SQLSRV_ERROR_UNKNOWN_SERVER_VERSION,
SQLSRV_ERROR_FETCH_PAST_END,
@ -1910,11 +1908,11 @@ 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( _Inout_ sqlsrv_context& ctx, _In_ int record_number, _Inout_ sqlsrv_error_auto_ptr& error,
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( _In_ sqlsrv_context& ctx, _In_ sqlsrv_error_const const* custom_error,
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 );
@ -1949,19 +1947,19 @@ inline bool call_error_handler( _Inout_ sqlsrv_context* ctx, _In_ unsigned long
// we don't want on a web server
#define SQLSRV_ASSERT( condition, msg, ...) if( !(condition)) DIE( msg, ## __VA_ARGS__ );
#if defined( PHP_DEBUG )
#if defined( PHP_DEBUG )
#define DEBUG_SQLSRV_ASSERT( condition, msg, ... ) \
if( !(condition)) { \
DIE (msg, ## __VA_ARGS__ ); \
}
}
#else
#define DEBUG_SQLSRV_ASSERT( condition, msg, ... ) ((void)0)
#endif
#endif
// check to see if the sqlstate is 01004, truncated field retrieved. Used for retrieving large fields.
inline bool is_truncated_warning( _In_ SQLCHAR* state )
@ -1984,7 +1982,7 @@ inline bool is_truncated_warning( _In_ SQLCHAR* state )
ignored##unique = call_error_handler( context, ssphp TSRMLS_CC, /*warning*/false, ## __VA_ARGS__ ); \
} \
if( !ignored##unique )
#define CHECK_ERROR_UNIQUE( unique, condition, context, ssphp, ...) \
CHECK_ERROR_EX( unique, condition, context, ssphp, ## __VA_ARGS__ )
@ -2003,11 +2001,11 @@ inline bool is_truncated_warning( _In_ SQLCHAR* state )
if( condition ) { \
ignored##unique = call_error_handler( context, ssphp TSRMLS_CC, /*warning*/true, ## __VA_ARGS__ ); \
} \
if( !ignored##unique )
if( !ignored##unique )
#define CHECK_SQL_WARNING_AS_ERROR( result, context, ... ) \
CHECK_WARNING_AS_ERROR_UNIQUE( __COUNTER__,( result == SQL_SUCCESS_WITH_INFO ), context, SQLSRV_ERROR_ODBC, ## __VA_ARGS__ )
#define CHECK_SQL_WARNING( result, context, ... ) \
if( result == SQL_SUCCESS_WITH_INFO ) { \
(void)call_error_handler( context, 0 TSRMLS_CC, /*warning*/ true, ## __VA_ARGS__ ); \
@ -2015,7 +2013,7 @@ inline bool is_truncated_warning( _In_ SQLCHAR* state )
#define CHECK_CUSTOM_WARNING_AS_ERROR( condition, context, ssphp, ... ) \
CHECK_WARNING_AS_ERROR_UNIQUE( __COUNTER__, condition, context, ssphp, ## __VA_ARGS__ )
#define CHECK_ZEND_ERROR( zr, ctx, error, ... ) \
CHECK_ERROR_UNIQUE( __COUNTER__, ( zr == FAILURE ), ctx, error, ## __VA_ARGS__ ) \
@ -2029,7 +2027,7 @@ inline bool is_truncated_warning( _In_ SQLCHAR* state )
ignored = call_error_handler( context, SQLSRV_ERROR_ODBC TSRMLS_CC, true TSRMLS_CC, ##__VA_ARGS__ ); \
} \
if( !ignored )
// throw an exception after it has been hooked into the custom error handler
#define THROW_CORE_ERROR( ctx, custom, ... ) \
(void)call_error_handler( ctx, custom TSRMLS_CC, /*warning*/ false, ## __VA_ARGS__ ); \
@ -2051,25 +2049,25 @@ namespace core {
inline void check_for_mars_error( _Inout_ sqlsrv_stmt* stmt, _In_ SQLRETURN r TSRMLS_DC )
{
// Skip this if not SQL_ERROR -
// Skip this if not SQL_ERROR -
// 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
if (r == SQL_ERROR) {
SQLCHAR err_msg[SQL_MAX_MESSAGE_LENGTH + 1] = {'\0'};
SQLSMALLINT len = 0;
SQLRETURN rtemp = ::SQLGetDiagField( stmt->handle_type(), stmt->handle(), 1, SQL_DIAG_MESSAGE_TEXT,
SQLRETURN rtemp = ::SQLGetDiagField( stmt->handle_type(), stmt->handle(), 1, SQL_DIAG_MESSAGE_TEXT,
err_msg, SQL_MAX_MESSAGE_LENGTH, &len );
if (rtemp == SQL_SUCCESS_WITH_INFO && len > SQL_MAX_MESSAGE_LENGTH) {
// if the error message is this long, then it must not be the mars message
// defined as ODBC_CONNECTION_BUSY_ERROR -- so return here and continue the
// if the error message is this long, then it must not be the mars message
// defined as ODBC_CONNECTION_BUSY_ERROR -- so return here and continue the
// regular error handling
return;
}
CHECK_SQL_ERROR_OR_WARNING( rtemp, stmt ) {
throw CoreException();
}
@ -2078,7 +2076,7 @@ namespace core {
const std::string returned_error( reinterpret_cast<char*>( err_msg ));
if(( returned_error.find( connection_busy_error ) != std::string::npos )) {
THROW_CORE_ERROR( stmt, SQLSRV_ERROR_MARS_OFF );
}
}
@ -2092,11 +2090,11 @@ 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( _Inout_ sqlsrv_context* ctx, _In_ SQLSMALLINT record_number, _In_ SQLSMALLINT diag_identifier,
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,
SQLRETURN r = ::SQLGetDiagField( ctx->handle_type(), ctx->handle(), record_number, diag_identifier,
diag_info_buffer, buffer_length, out_buffer_length );
CHECK_SQL_ERROR_OR_WARNING( r, ctx ) {
@ -2106,7 +2104,7 @@ namespace core {
return r;
}
inline void SQLAllocHandle( _In_ SQLSMALLINT HandleType, _Inout_ sqlsrv_context& InputHandle,
inline void SQLAllocHandle( _In_ SQLSMALLINT HandleType, _Inout_ sqlsrv_context& InputHandle,
_Out_ SQLHANDLE* OutputHandlePtr TSRMLS_DC )
{
SQLRETURN r;
@ -2116,7 +2114,7 @@ namespace core {
}
}
inline void SQLBindParameter( _Inout_ sqlsrv_stmt* stmt,
inline void SQLBindParameter( _Inout_ sqlsrv_stmt* stmt,
_In_ SQLUSMALLINT ParameterNumber,
_In_ SQLSMALLINT InputOutputType,
_In_ SQLSMALLINT ValueType,
@ -2129,9 +2127,9 @@ namespace core {
TSRMLS_DC )
{
SQLRETURN r;
r = ::SQLBindParameter( stmt->handle(), ParameterNumber, InputOutputType, ValueType, ParameterType, ColumnSize,
r = ::SQLBindParameter( stmt->handle(), ParameterNumber, InputOutputType, ValueType, ParameterType, ColumnSize,
DecimalDigits, ParameterValuePtr, BufferLength, StrLen_Or_IndPtr );
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
throw CoreException();
}
@ -2146,7 +2144,7 @@ namespace core {
}
}
inline void SQLColAttribute( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_index, _In_ SQLUSMALLINT field_identifier,
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 )
{
@ -2175,9 +2173,9 @@ namespace core {
_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,
r = ::SQLDescribeCol( stmt->handle(), colno, col_name, col_name_length, col_name_length_out,
data_type, col_size, decimal_digits, nullable);
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
throw CoreException();
}
@ -2220,17 +2218,17 @@ namespace core {
inline void SQLEndTran( _In_ SQLSMALLINT handleType, _Inout_ sqlsrv_conn* conn, _In_ SQLSMALLINT completionType TSRMLS_DC )
{
SQLRETURN r = ::SQLEndTran( handleType, conn->handle(), completionType );
CHECK_SQL_ERROR_OR_WARNING( r, conn ) {
throw CoreException();
}
}
// SQLExecDirect returns the status code since it returns either SQL_NEED_DATA or SQL_NO_DATA besides just errors/success
// SQLExecDirect returns the status code since it returns either SQL_NEED_DATA or SQL_NO_DATA besides just errors/success
inline SQLRETURN SQLExecDirect( _Inout_ sqlsrv_stmt* stmt, _In_ char* sql TSRMLS_DC )
{
SQLRETURN r = ::SQLExecDirect( stmt->handle(), reinterpret_cast<SQLCHAR*>( sql ), SQL_NTS );
check_for_mars_error( stmt, r TSRMLS_CC );
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
@ -2258,7 +2256,7 @@ namespace core {
{
SQLRETURN r;
r = ::SQLExecute( stmt->handle() );
check_for_mars_error( stmt, r TSRMLS_CC );
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
@ -2271,7 +2269,7 @@ namespace core {
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 );
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
throw CoreException();
}
@ -2304,7 +2302,7 @@ namespace core {
if( r == SQL_NO_DATA )
return r;
CHECK_SQL_ERROR( r, stmt ) {
throw CoreException();
}
@ -2318,13 +2316,13 @@ namespace core {
return r;
}
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 );
CHECK_SQL_ERROR_OR_WARNING( r, conn ) {
throw CoreException();
}
@ -2335,7 +2333,7 @@ namespace core {
{
SQLRETURN r;
r = ::SQLGetTypeInfo( stmt->handle(), data_type );
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
throw CoreException();
}
@ -2363,7 +2361,7 @@ namespace core {
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
throw CoreException();
}
return num_cols;
}
@ -2405,14 +2403,14 @@ namespace core {
SQLLEN rows_affected;
r = ::SQLRowCount( stmt->handle(), &rows_affected );
// On Linux platform
// DriverName: libmsodbcsql-13.0.so.0.0
// DriverODBCVer: 03.52
// DriverVer: 13.00.0000
// unixODBC: 2.3.1
// r = ::SQLRowCount( stmt->handle(), &rows_affected );
// returns r=-1 for an empty result set.
// r = ::SQLRowCount( stmt->handle(), &rows_affected );
// returns r=-1 for an empty result set.
#ifndef _WIN32
if( r == -1 && rows_affected == -1 )
return 0;
@ -2430,7 +2428,7 @@ namespace core {
{
SQLRETURN r;
r = ::SQLSetConnectAttr( ctx.handle(), attr, value_ptr, str_len );
CHECK_SQL_ERROR_OR_WARNING( r, ctx ) {
throw CoreException();
}
@ -2460,13 +2458,13 @@ namespace core {
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 );
SQLRETURN r = ::SQLSetConnectAttr( conn->handle(), attribute, value_ptr, value_len );
CHECK_SQL_ERROR_OR_WARNING( r, conn ) {
throw CoreException();
}
}
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;
@ -2505,7 +2503,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( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array, _In_ zend_ulong index, _In_ 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 ) {
@ -2513,7 +2511,7 @@ namespace core {
}
}
inline void sqlsrv_add_next_index_zval( _Inout_ sqlsrv_context& ctx, _Inout_ zval* array, _In_ 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 ) {
@ -2556,7 +2554,7 @@ namespace core {
}
}
inline void sqlsrv_array_init( _Inout_ sqlsrv_context& ctx, _Out_ zval* new_array TSRMLS_DC)
inline void sqlsrv_array_init( _Inout_ sqlsrv_context& ctx, _Out_ zval* new_array TSRMLS_DC)
{
#if PHP_VERSION_ID < 70300
CHECK_ZEND_ERROR(::array_init(new_array), ctx, SQLSRV_ERROR_ZEND_HASH) {
@ -2599,7 +2597,7 @@ namespace core {
throw CoreException();
}
}
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;
@ -2624,7 +2622,7 @@ namespace core {
throw CoreException();
}
}
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;
@ -2648,7 +2646,7 @@ namespace core {
throw CoreException();
}
}
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 )
{

View file

@ -329,7 +329,7 @@ sqlsrv_stmt* core_sqlsrv_create_stmt( _Inout_ sqlsrv_conn* conn, _In_ driver_stm
}
// The query timeout setting is inherited from the corresponding connection attribute, but
// the user may override that the query timeout setting using the statement option.
// the user may override that the query timeout setting using the statement option.
// In any case, set query timeout using the latest value
stmt->set_query_timeout();
@ -850,7 +850,7 @@ bool core_sqlsrv_fetch( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT fetch_orient
CHECK_CUSTOM_ERROR( stmt->past_fetch_end, stmt, SQLSRV_ERROR_FETCH_PAST_END ) {
throw core::CoreException();
}
// First time only
if ( !stmt->fetch_called ) {
SQLSMALLINT has_fields;
@ -860,7 +860,7 @@ bool core_sqlsrv_fetch( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT fetch_orient
has_fields = core::SQLNumResultCols( stmt TSRMLS_CC );
stmt->column_count = has_fields;
}
CHECK_CUSTOM_ERROR( has_fields == 0, stmt, SQLSRV_ERROR_NO_FIELDS ) {
throw core::CoreException();
}
@ -1009,7 +1009,7 @@ void core_sqlsrv_sensitivity_metadata( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
}
// Reference: https://docs.microsoft.com/sql/connect/odbc/data-classification
// To retrieve sensitivity classfication data, the first step is to retrieve the IRD(Implementation Row Descriptor) handle by
// To retrieve sensitivity classfication data, the first step is to retrieve the IRD(Implementation Row Descriptor) handle by
// calling SQLGetStmtAttr with SQL_ATTR_IMP_ROW_DESC statement attribute
r = ::SQLGetStmtAttr(stmt->handle(), SQL_ATTR_IMP_ROW_DESC, (SQLPOINTER)&ird, SQL_IS_POINTER, 0);
CHECK_SQL_ERROR_OR_WARNING(r, stmt) {
@ -1074,7 +1074,7 @@ void core_sqlsrv_sensitivity_metadata( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
CHECK_CUSTOM_ERROR(dcptr != dcend, stmt, SQLSRV_ERROR_DATA_CLASSIFICATION_FAILED, "Metadata parsing ends unexpectedly") {
throw core::CoreException();
}
stmt->current_sensitivity_metadata = sensitivity_meta;
sensitivity_meta.transferred();
} catch (core::CoreException& e) {
@ -1172,7 +1172,7 @@ void core_sqlsrv_get_field( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_i
// use the previously saved php type
sqlsrv_php_type = stmt->current_meta_data[field_index]->sqlsrv_php_type;
}
}
}
// Verify that we have an acceptable type to convert.
CHECK_CUSTOM_ERROR(!is_valid_sqlsrv_phptype(sqlsrv_php_type), stmt, SQLSRV_ERROR_INVALID_TYPE) {
@ -1209,7 +1209,7 @@ bool core_sqlsrv_has_any_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
{
SQLSMALLINT num_cols;
SQLLEN rows_affected;
if (stmt->column_count != ACTIVE_NUM_COLS_INVALID) {
num_cols = stmt->column_count;
}
@ -1218,7 +1218,7 @@ bool core_sqlsrv_has_any_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
num_cols = core::SQLNumResultCols( stmt TSRMLS_CC );
stmt->column_count = num_cols;
}
if (stmt->row_count != ACTIVE_NUM_ROWS_INVALID) {
rows_affected = stmt->row_count;
}
@ -1227,7 +1227,7 @@ bool core_sqlsrv_has_any_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
rows_affected = core::SQLRowCount( stmt TSRMLS_CC );
stmt->row_count = rows_affected;
}
return (num_cols != 0) || (rows_affected > 0);
}
@ -1266,7 +1266,7 @@ void core_sqlsrv_next_result( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_ bool fin
if( r == SQL_NO_DATA ) {
if( &(stmt->output_params) && finalize_output_params ) {
if( finalize_output_params ) {
// if we're finished processing result sets, handle the output parameters
finalize_output_parameters( stmt TSRMLS_CC );
}
@ -1416,7 +1416,7 @@ void core_sqlsrv_set_decimal_places(_Inout_ sqlsrv_stmt* stmt, _In_ zval* value_
}
stmt->decimal_places = static_cast<short>(decimal_places);
}
}
catch( core::CoreException& ) {
throw;
}
@ -1858,7 +1858,7 @@ void core_get_field_common( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_i
// Reference: https://docs.microsoft.com/sql/odbc/reference/appendixes/sql-to-c-timestamp
// Retrieve the datetime data as a string, which may be cached for later use.
// The string is converted to a DateTime object only when it is required to
// The string is converted to a DateTime object only when it is required to
// be returned as a zval.
case SQLSRV_PHPTYPE_DATETIME:
{
@ -1885,7 +1885,7 @@ void core_get_field_common( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_i
break;
}
// create a stream wrapper around the field and return that object to the PHP script. calls to fread
// on the stream will result in calls to SQLGetData. This is handled in stream.cpp. See that file
// for how these fields are used.
@ -2012,7 +2012,7 @@ bool convert_input_param_to_utf16( _In_ zval* input_param_z, _Inout_ zval* conve
// conversion, to avoid the performance penalty of calling ToUtf16
wchar_size = buffer_len;
#else
// Calculate the size of the necessary buffer from the length of the string -
// Calculate the size of the necessary buffer from the length of the string -
// no performance penalty because MultiByteToWidechar is highly optimised
wchar_size = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, reinterpret_cast<LPCSTR>( buffer ), static_cast<int>( buffer_len ), NULL, 0 );
#endif // !_WIN32
@ -2275,7 +2275,7 @@ void format_decimal_numbers(_In_ SQLSMALLINT decimals_places, _In_ SQLSMALLINT f
// number of decimals adheres to the column field scale. If smaller, the output value may be rounded up.
//
// Note: it's possible that the decimal data does not contain a decimal dot because the field scale is 0.
// Thus, first check if the decimal dot exists. If not, no formatting necessary, regardless of
// Thus, first check if the decimal dot exists. If not, no formatting necessary, regardless of
// format_decimals and decimals_places
//
std::string str = field_value;
@ -2292,8 +2292,8 @@ void format_decimal_numbers(_In_ SQLSMALLINT decimals_places, _In_ SQLSMALLINT f
}
// We want the rounding to be consistent with php number_format(), http://php.net/manual/en/function.number-format.php
// as well as SQL Server Management studio, such that the least significant digit will be rounded up if it is
// followed by 5 or above.
// as well as SQL Server Management studio, such that the least significant digit will be rounded up if it is
// followed by 5 or above.
bool isNegative = false;
@ -2313,16 +2313,16 @@ void format_decimal_numbers(_In_ SQLSMALLINT decimals_places, _In_ SQLSMALLINT f
str = oss.str();
pos++;
}
if (num_decimals == NO_CHANGE_DECIMAL_PLACES) {
// Add the minus sign back if negative
if (isNegative) {
std::ostringstream oss;
oss << '-' << str.substr(0);
str = oss.str();
}
}
} else {
// Start formatting
// Start formatting
size_t last = 0;
if (num_decimals == 0) {
// Chop all decimal digits, including the decimal dot
@ -2532,7 +2532,7 @@ void finalize_output_parameters( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
throw core::CoreException();
}
}
// if the output param is a boolean, still convert to
// if the output param is a boolean, still convert to
// a long integer first to take care of rounding
convert_to_long(value_z);
if (output_param->is_bool) {
@ -2911,9 +2911,9 @@ void resize_output_buffer_if_necessary( _Inout_ sqlsrv_stmt* stmt, _Inout_ zval*
// account for the NULL terminator returned by ODBC and needed by Zend to avoid a "String not null terminated" debug warning
SQLULEN field_size = column_size;
// with AE on, when column_size is retrieved from SQLDescribeParam, column_size
// with AE on, when column_size is retrieved from SQLDescribeParam, column_size
// does not include the negative sign or decimal place for numeric values
// VSO Bug 2913: without AE, the same can happen as well, in particular to decimals
// VSO Bug 2913: without AE, the same can happen as well, in particular to decimals
// and numerics with precision/scale specified
if (sql_type == SQL_DECIMAL || sql_type == SQL_NUMERIC || sql_type == SQL_BIGINT || sql_type == SQL_INTEGER || sql_type == SQL_SMALLINT) {
// include the possible negative sign
@ -2948,8 +2948,8 @@ void resize_output_buffer_if_necessary( _Inout_ sqlsrv_stmt* stmt, _Inout_ zval*
// A zval string len doesn't include the null. This calculates the length it should be
// regardless of whether the ODBC type contains the NULL or not.
// initialize the newly allocated space
char *p = ZSTR_VAL(param_z_string);
// initialize the newly allocated space
char *p = ZSTR_VAL(param_z_string);
p = p + original_len;
memset(p, '\0', expected_len - original_len);
ZVAL_NEW_STR(param_z, param_z_string);

View file

@ -7,13 +7,13 @@
// Copyright(c) Microsoft Corporation
// All rights reserved.
// MIT License
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//---------------------------------------------------------------------------------------------------------------------------------
@ -85,11 +85,6 @@ const char* NULLABLE = "Nullable";
}
// warning message printed when a parameter variable is not passed by reference
const char SS_SQLSRV_WARNING_PARAM_VAR_NOT_REF[] = "Variable parameter %d not passed by reference (prefaced with an &). "
"Variable parameters passed to sqlsrv_prepare or sqlsrv_query should be passed by reference, not by value. "
"For more information, see sqlsrv_prepare or sqlsrv_query in the API Reference section of the product documentation.";
/* internal functions */
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 );
@ -103,7 +98,7 @@ 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_ 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, _In_ int type );
void type_and_size_calc( INTERNAL_FUNCTION_PARAMETERS, _In_ int type );
@ -156,7 +151,7 @@ ss_sqlsrv_stmt::~ss_sqlsrv_stmt( void )
if( fetch_field_names != NULL ) {
for( int i=0; i < fetch_fields_count; ++i ) {
sqlsrv_free( fetch_field_names[i].name );
}
sqlsrv_free( fetch_field_names );
@ -165,16 +160,16 @@ ss_sqlsrv_stmt::~ss_sqlsrv_stmt( void )
zval_ptr_dtor( params_z );
sqlsrv_free(params_z);
}
}
}
// to be called whenever a new result set is created, such as after an
// execute or next_result. Resets the state variables and calls the subclass.
void ss_sqlsrv_stmt::new_result_set( TSRMLS_D )
void ss_sqlsrv_stmt::new_result_set( TSRMLS_D )
{
if( fetch_field_names != NULL ) {
for( int i=0; i < fetch_fields_count; ++i ) {
sqlsrv_free( fetch_field_names[i].name );
}
sqlsrv_free( fetch_field_names );
@ -185,7 +180,7 @@ void ss_sqlsrv_stmt::new_result_set( TSRMLS_D )
sqlsrv_stmt::new_result_set( TSRMLS_C );
}
// Returns a php type for a given sql type. Also sets the encoding wherever applicable.
// 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( _In_ SQLINTEGER sql_type, _In_ SQLUINTEGER size, _In_ bool prefer_string_to_stream )
{
sqlsrv_phptype ss_phptype;
@ -299,13 +294,13 @@ void ss_sqlsrv_stmt::set_query_timeout()
}
// sqlsrv_execute( resource $stmt )
//
//
// Executes a previously prepared statement. See sqlsrv_prepare for information
// on preparing a statement for execution.
//
//
// This function is ideal for executing a prepared statement multiple times with
// different parameter values. See the MSDN documentation
//
//
// Parameters
// $stmt: A resource specifying the statement to be executed. For more
// information about how to create a statement resource, see sqlsrv_prepare.
@ -316,12 +311,12 @@ void ss_sqlsrv_stmt::set_query_timeout()
PHP_FUNCTION( sqlsrv_execute )
{
LOG_FUNCTION( "sqlsrv_execute" );
ss_sqlsrv_stmt* stmt = NULL;
try {
PROCESS_PARAMS( stmt, "r", _FN_, 0 );
PROCESS_PARAMS( stmt, "r", _FN_, 0 );
CHECK_CUSTOM_ERROR(( !stmt->prepared ), stmt, SS_SQLSRV_ERROR_STATEMENT_NOT_PREPARED ) {
throw ss::SSException();
}
@ -340,11 +335,11 @@ PHP_FUNCTION( sqlsrv_execute )
bind_params( stmt TSRMLS_CC );
core_sqlsrv_execute( stmt TSRMLS_CC );
RETURN_TRUE;
}
catch( core::CoreException& ) {
RETURN_FALSE;
}
catch( ... ) {
@ -382,8 +377,8 @@ PHP_FUNCTION( sqlsrv_fetch )
PROCESS_PARAMS( stmt, "r|ll", _FN_, 2, &fetch_style, &fetch_offset );
try {
CHECK_CUSTOM_ERROR(( fetch_style < SQL_FETCH_NEXT || fetch_style > SQL_FETCH_RELATIVE ), stmt,
CHECK_CUSTOM_ERROR(( fetch_style < SQL_FETCH_NEXT || fetch_style > SQL_FETCH_RELATIVE ), stmt,
SS_SQLSRV_ERROR_INVALID_FETCH_STYLE ) {
throw ss::SSException();
}
@ -406,7 +401,7 @@ PHP_FUNCTION( sqlsrv_fetch )
}
// sqlsrv_fetch_array( resource $stmt [, int $fetchType] )
//
//
// Retrieves the next row of data as an array.
//
// Parameters
@ -425,7 +420,7 @@ PHP_FUNCTION( sqlsrv_fetch )
PHP_FUNCTION( sqlsrv_fetch_array )
{
LOG_FUNCTION( "sqlsrv_fetch_array" );
ss_sqlsrv_stmt* stmt = NULL;
zend_long fetch_type = SQLSRV_FETCH_BOTH; // default value for parameter if one isn't supplied
zend_long fetch_style = SQL_FETCH_NEXT; // default value for parameter if one isn't supplied
@ -436,13 +431,13 @@ PHP_FUNCTION( sqlsrv_fetch_array )
PROCESS_PARAMS( stmt, "r|lll", _FN_, 3, &fetch_type, &fetch_style, &fetch_offset );
try {
CHECK_CUSTOM_ERROR(( fetch_type < MIN_SQLSRV_FETCH || fetch_type > MAX_SQLSRV_FETCH ), stmt,
CHECK_CUSTOM_ERROR(( fetch_type < MIN_SQLSRV_FETCH || fetch_type > MAX_SQLSRV_FETCH ), stmt,
SS_SQLSRV_ERROR_INVALID_FETCH_TYPE ) {
throw ss::SSException();
}
CHECK_CUSTOM_ERROR(( fetch_style < SQL_FETCH_NEXT || fetch_style > SQL_FETCH_RELATIVE ), stmt,
CHECK_CUSTOM_ERROR(( fetch_style < SQL_FETCH_NEXT || fetch_style > SQL_FETCH_RELATIVE ), stmt,
SS_SQLSRV_ERROR_INVALID_FETCH_STYLE ) {
throw ss::SSException();
}
@ -467,7 +462,7 @@ PHP_FUNCTION( sqlsrv_fetch_array )
}
// sqlsrv_field_metadata( resource $stmt )
//
//
// Retrieves metadata for the fields of a prepared statement. For information
// about preparing a statement, see sqlsrv_query or sqlsrv_prepare. Note that
// sqlsrv_field_metadata can be called on any prepared statement, pre- or
@ -477,7 +472,7 @@ PHP_FUNCTION( sqlsrv_fetch_array )
// $stmt: A statement resource for which field metadata is sought.
//
// Return Value
// retrieve an array of metadata for the current result set on a statement. Each element of the
// retrieve an array of metadata for the current result set on a statement. Each element of the
// array is a sub-array containing 5 elements accessed by key:
// name - name of the field.
// type - integer of the type. Can be compared against the SQLSRV_SQLTYPE constants.
@ -507,10 +502,10 @@ PHP_FUNCTION( sqlsrv_field_metadata )
zval result_meta_data;
ZVAL_UNDEF( &result_meta_data );
core::sqlsrv_array_init( *stmt, &result_meta_data TSRMLS_CC );
for( SQLSMALLINT f = 0; f < num_cols; ++f ) {
field_meta_data* core_meta_data = stmt->current_meta_data[f];
// initialize the array
zval field_array;
ZVAL_UNDEF( &field_array );
@ -555,7 +550,7 @@ PHP_FUNCTION( sqlsrv_field_metadata )
// add the nullability to the array
core::sqlsrv_add_assoc_long( *stmt, &field_array, FieldMetaData::NULLABLE, core_meta_data->field_is_nullable
TSRMLS_CC );
if (stmt->data_classification) {
data_classification::fill_column_sensitivity_array(stmt, f, &field_array TSRMLS_CC);
}
@ -580,7 +575,7 @@ PHP_FUNCTION( sqlsrv_field_metadata )
// sqlsrv_next_result( resource $stmt )
//
//
// Makes the next result (result set, row count, or output parameter) of the
// specified statement active. The first (or only) result returned by a batch
// query or stored procedure is active without a call to sqlsrv_next_result.
@ -619,7 +614,7 @@ PHP_FUNCTION( sqlsrv_next_result )
RETURN_TRUE;
}
catch( core::CoreException& ) {
RETURN_FALSE;
}
catch( ... ) {
@ -708,7 +703,7 @@ PHP_FUNCTION( sqlsrv_num_rows )
// make sure that the statement is scrollable and the cursor is not dynamic.
// if the cursor is dynamic, then the number of rows returned is always -1.
CHECK_CUSTOM_ERROR( stmt->cursor_type == SQL_CURSOR_FORWARD_ONLY || stmt->cursor_type == SQL_CURSOR_DYNAMIC, stmt,
CHECK_CUSTOM_ERROR( stmt->cursor_type == SQL_CURSOR_FORWARD_ONLY || stmt->cursor_type == SQL_CURSOR_DYNAMIC, stmt,
SS_SQLSRV_ERROR_STATEMENT_NOT_SCROLLABLE ) {
throw ss::SSException();
}
@ -750,10 +745,10 @@ PHP_FUNCTION( sqlsrv_num_fields )
PROCESS_PARAMS( stmt, "r", _FN_, 0 );
try {
// retrieve the number of columns from ODBC
fields = core::SQLNumResultCols( stmt TSRMLS_CC );
RETURN_LONG( fields );
}
@ -768,7 +763,7 @@ PHP_FUNCTION( sqlsrv_num_fields )
}
// sqlsrv_fetch_object( resource $stmt [, string $className [, array $ctorParams]])
//
//
// Retrieves the next row of data as a PHP object.
//
// Parameters
@ -801,7 +796,7 @@ PHP_FUNCTION( sqlsrv_num_fields )
// object and the result set value is applied to the property. For more
// information about calling sqlsrv_fetch_object with the $className parameter,
// see How to: Retrieve Data as an Object (Microsoft Drivers for PHP for SQL Server).
//
//
// If a field with no name is returned, sqlsrv_fetch_object will discard the
// field value and issue a warning.
@ -824,19 +819,19 @@ PHP_FUNCTION( sqlsrv_fetch_object )
// retrieve the statement resource and optional fetch type (see enum SQLSRV_FETCH_TYPE),
// fetch style (see SQLSRV_SCROLL_* constants) and fetch offset
// we also use z! instead of s and a so that null may be passed in as valid values for
// we also use z! instead of s and a so that null may be passed in as valid values for
// the class name and ctor params
PROCESS_PARAMS( stmt, "r|z!z!ll", _FN_, 4, &class_name_z, &ctor_params_z, &fetch_style, &fetch_offset );
try {
CHECK_CUSTOM_ERROR(( fetch_style < SQL_FETCH_NEXT || fetch_style > SQL_FETCH_RELATIVE ), stmt,
CHECK_CUSTOM_ERROR(( fetch_style < SQL_FETCH_NEXT || fetch_style > SQL_FETCH_RELATIVE ), stmt,
SS_SQLSRV_ERROR_INVALID_FETCH_STYLE ) {
throw ss::SSException();
}
if( class_name_z ) {
CHECK_CUSTOM_ERROR(( Z_TYPE_P( class_name_z ) != IS_STRING ), stmt, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ ) {
throw ss::SSException();
}
@ -847,7 +842,7 @@ PHP_FUNCTION( sqlsrv_fetch_object )
if( ctor_params_z && Z_TYPE_P( ctor_params_z ) != IS_ARRAY ) {
THROW_SS_ERROR( stmt, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ );
}
// fetch the data
bool result = core_sqlsrv_fetch( stmt, static_cast<SQLSMALLINT>(fetch_style), fetch_offset TSRMLS_CC );
if( !result ) {
@ -855,8 +850,8 @@ PHP_FUNCTION( sqlsrv_fetch_object )
}
fetch_fields_common( stmt, SQLSRV_FETCH_ASSOC, retval_z, false /*allow_empty_field_names*/ TSRMLS_CC );
properties_ht = Z_ARRVAL( retval_z );
properties_ht = Z_ARRVAL( retval_z );
// find the zend_class_entry of the class the user requested (stdClass by default) for use below
zend_class_entry* class_entry = NULL;
zend_string* class_name_str_z = zend_string_init( class_name, class_name_len, 0 );
@ -885,13 +880,13 @@ PHP_FUNCTION( sqlsrv_fetch_object )
// find and call the object's constructor
// The header files (zend.h and zend_API.h) declare
// these functions and structures, so by working with those, we were able to
// these functions and structures, so by working with those, we were able to
// develop this as a suitable snippet for calling constructors. Some observations:
// params must be an array of zval**, not a zval** to an array as we originally
// thought. Also, a constructor doesn't show up in the function table, but
// is put into the "magic methods" section of the class entry.
//
// The default values of the fci and fcic structures were determined by
//
// The default values of the fci and fcic structures were determined by
// calling zend_fcall_info_init with a test callable.
// if there is a constructor (e.g., stdClass doesn't have one)
@ -919,7 +914,7 @@ PHP_FUNCTION( sqlsrv_fetch_object )
i++;
} ZEND_HASH_FOREACH_END();
} //if( !Z_ISUNDEF( ctor_params_z ))
// call the constructor function itself.
zend_fcall_info fci;
zend_fcall_info_cache fcic;
@ -933,7 +928,7 @@ PHP_FUNCTION( sqlsrv_fetch_object )
fci.retval = &ctor_retval_z;
fci.param_count = num_params;
fci.params = params_m; // purposefully not transferred since ownership isn't actually transferred.
fci.object = Z_OBJ_P( &retval_z );
memset( &fcic, 0, sizeof( fcic ));
@ -950,7 +945,7 @@ PHP_FUNCTION( sqlsrv_fetch_object )
throw ss::SSException();
}
} //if( class_entry->constructor )
} //if( class_entry->constructor )
RETURN_ZVAL( &retval_z, 1, 1 );
}
@ -985,7 +980,7 @@ PHP_FUNCTION( sqlsrv_fetch_object )
// for using a function like this:
// 1) To know if there are any actual rows, not just a result set (empty or not). Use sqlsrv_has_rows to determine this.
// The guarantee is that if sqlsrv_has_rows returns true immediately after a query, that sqlsrv_fetch_* will return at least
// one row of data.
// one row of data.
// 2) To know if there is any sort of result set, empty or not, that has to be bypassed to get to something else, such as
// output parameters being returned. Use sqlsrv_num_fields > 0 to check if there is any result set that must be bypassed
// until sqlsrv_fetch returns NULL.
@ -1048,8 +1043,8 @@ PHP_FUNCTION( sqlsrv_has_rows )
PHP_FUNCTION( sqlsrv_send_stream_data )
{
sqlsrv_stmt* stmt = NULL;
LOG_FUNCTION( "sqlsrv_send_stream_data" );
LOG_FUNCTION( "sqlsrv_send_stream_data" );
// get the statement resource that we've bound streams to
PROCESS_PARAMS( stmt, "r", _FN_, 0 );
@ -1079,14 +1074,14 @@ PHP_FUNCTION( sqlsrv_send_stream_data )
RETURN_FALSE;
}
catch( ... ) {
DIE( "sqlsrv_send_stream_data: Unknown exception caught." );
}
}
// sqlsrv_get_field( resource $stmt, int $fieldIndex [, int $getAsType] )
//
//
// Retrieves data from the specified field of the current row. Field data must
// be accessed in order. For example, data from the first field cannot be
// accessed after data from the second field has been accessed.
@ -1111,7 +1106,7 @@ PHP_FUNCTION( sqlsrv_send_stream_data )
PHP_FUNCTION( sqlsrv_get_field )
{
LOG_FUNCTION( "sqlsrv_get_field" );
ss_sqlsrv_stmt* stmt = NULL;
sqlsrv_phptype sqlsrv_php_type;
sqlsrv_php_type.typeinfo.type = SQLSRV_PHPTYPE_INVALID;
@ -1121,7 +1116,7 @@ PHP_FUNCTION( sqlsrv_get_field )
SQLLEN field_len = -1;
zval retval_z;
ZVAL_UNDEF(&retval_z);
// get the statement, the field index and the optional type
PROCESS_PARAMS( stmt, "rl|l", _FN_, 2, &field_index, &sqlsrv_php_type );
@ -1136,7 +1131,7 @@ PHP_FUNCTION( sqlsrv_get_field )
core_sqlsrv_get_field( stmt, static_cast<SQLUSMALLINT>( field_index ), sqlsrv_php_type, false, field_value, &field_len, false/*cache_field*/,
&sqlsrv_php_type_out TSRMLS_CC );
convert_to_zval( stmt, sqlsrv_php_type_out, field_value, field_len, retval_z );
convert_to_zval( stmt, sqlsrv_php_type_out, field_value, field_len, retval_z );
sqlsrv_free( field_value );
RETURN_ZVAL( &retval_z, 1, 1 );
}
@ -1232,9 +1227,9 @@ void bind_params( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC )
stmt->executed = false;
zval* params_z = stmt->params_z;
HashTable* params_ht = Z_ARRVAL_P( params_z );
zend_ulong index = -1;
zend_string *key = NULL;
zval* param_z = NULL;
@ -1256,7 +1251,7 @@ void bind_params( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC )
CHECK_CUSTOM_ERROR( type != HASH_KEY_IS_LONG, stmt, SS_SQLSRV_ERROR_PARAM_INVALID_INDEX ) {
throw ss::SSException();
}
// if it's a parameter array
if( Z_TYPE_P( param_z ) == IS_ARRAY ) {
@ -1279,7 +1274,7 @@ void bind_params( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC )
}
// bind the parameter
SQLSRV_ASSERT( value_z != NULL, "bind_params: value_z is null." );
core_sqlsrv_bind_param( stmt, static_cast<SQLUSMALLINT>( index ), direction, value_z, php_out_type, encoding, sql_type, column_size,
core_sqlsrv_bind_param( stmt, static_cast<SQLUSMALLINT>( index ), direction, value_z, php_out_type, encoding, sql_type, column_size,
decimal_digits TSRMLS_CC );
} ZEND_HASH_FOREACH_END();
@ -1294,7 +1289,7 @@ void bind_params( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC )
}
// sqlsrv_cancel( resource $stmt )
//
//
// Cancels a statement. This means that any pending results for the statement
// are discarded. After this function is called, the statement can be
// re-executed if it was prepared with sqlsrv_prepare. Calling this function is
@ -1313,12 +1308,12 @@ PHP_FUNCTION( sqlsrv_cancel )
LOG_FUNCTION( "sqlsrv_cancel" );
ss_sqlsrv_stmt* stmt = NULL;
PROCESS_PARAMS( stmt, "r", _FN_, 0 );
try {
// close the stream to release the resource
close_active_stream( stmt TSRMLS_CC );
SQLRETURN r = SQLCancel( stmt->handle() );
CHECK_SQL_ERROR_OR_WARNING( r, stmt ) {
throw ss::SSException();
@ -1360,7 +1355,7 @@ void __cdecl sqlsrv_stmt_dtor( _Inout_ zend_resource *rsrc TSRMLS_DC )
// cannot be used again after this function has been called.
//
// Parameters
// $stmt: The statement to be closed.
// $stmt: The statement to be closed.
//
// Return Value
// The Boolean value true unless the function is called with an invalid
@ -1384,7 +1379,7 @@ PHP_FUNCTION( sqlsrv_free_stmt )
sqlsrv_context_auto_ptr error_ctx;
reset_errors( TSRMLS_C );
try {
// dummy context to pass to the error handler
@ -1393,14 +1388,14 @@ PHP_FUNCTION( sqlsrv_free_stmt )
// take only the statement resource
if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "r", &stmt_r ) == FAILURE ) {
// Check if it was a zval
int zr = zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "z", &stmt_r );
CHECK_CUSTOM_ERROR(( zr == FAILURE ), error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ ) {
throw ss::SSException();
}
}
if( Z_TYPE_P( stmt_r ) == IS_NULL ) {
RETURN_TRUE;
@ -1413,19 +1408,19 @@ PHP_FUNCTION( sqlsrv_free_stmt )
// verify the resource so we know we're deleting a statement
stmt = static_cast<ss_sqlsrv_stmt*>(zend_fetch_resource_ex(stmt_r TSRMLS_CC, ss_sqlsrv_stmt::resource_name, ss_sqlsrv_stmt::descriptor));
// 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;
}
if( stmt == NULL ) {
THROW_CORE_ERROR( error_ctx, SS_SQLSRV_ERROR_INVALID_FUNCTION_PARAMETER, _FN_ );
}
// delete the resource from Zend's master list, which will trigger the statement's destructor
if( zend_list_close( Z_RES_P(stmt_r) ) == FAILURE ) {
LOG( SEV_ERROR, "Failed to remove stmt resource %1!d!", Z_RES_P( stmt_r )->handle);
@ -1436,17 +1431,17 @@ PHP_FUNCTION( sqlsrv_free_stmt )
// zend_list_close only destroy the resource pointed to by Z_RES_P( stmt_r ), not the zend_resource itself
Z_TRY_DELREF_P(stmt_r);
ZVAL_NULL( stmt_r );
RETURN_TRUE;
}
catch( core::CoreException& ) {
RETURN_FALSE;
}
catch( ... ) {
DIE( "sqlsrv_free_stmt: Unknown exception caught." );
}
}
@ -1456,16 +1451,16 @@ void stmt_option_ss_scrollable:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_opt
CHECK_CUSTOM_ERROR(( Z_TYPE_P( value_z ) != IS_STRING ), stmt, SQLSRV_ERROR_INVALID_OPTION_SCROLLABLE ) {
throw ss::SSException();
}
const char* scroll_type = Z_STRVAL_P( value_z );
unsigned long cursor_type = -1;
// find which cursor type they would like and set the ODBC statement attribute as such
if( !stricmp( scroll_type, SSCursorTypes::QUERY_OPTION_SCROLLABLE_STATIC )) {
if( !stricmp( scroll_type, SSCursorTypes::QUERY_OPTION_SCROLLABLE_STATIC )) {
cursor_type = SQL_CURSOR_STATIC;
}
else if( !stricmp( scroll_type, SSCursorTypes::QUERY_OPTION_SCROLLABLE_DYNAMIC )) {
cursor_type = SQL_CURSOR_DYNAMIC;
@ -1477,12 +1472,12 @@ void stmt_option_ss_scrollable:: operator()( _Inout_ sqlsrv_stmt* stmt, stmt_opt
}
else if( !stricmp( scroll_type, SSCursorTypes::QUERY_OPTION_SCROLLABLE_FORWARD )) {
cursor_type = SQL_CURSOR_FORWARD_ONLY;
}
else if( !stricmp( scroll_type, SSCursorTypes::QUERY_OPTION_SCROLLABLE_BUFFERED )) {
cursor_type = SQLSRV_CURSOR_BUFFERED;
}
@ -1553,7 +1548,7 @@ void convert_to_zval( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSRV_PHPTYPE sqlsrv_php_
// 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, _In_ sqlsrv_sqltype sqlsrv_type, _Inout_ 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;
@ -1608,7 +1603,7 @@ bool determine_column_size_or_precision( sqlsrv_stmt const* stmt, _In_ sqlsrv_sq
}
break;
case SQL_WCHAR:
case SQL_WVARCHAR:
case SQL_WVARCHAR:
*column_size = sqlsrv_type.typeinfo.size;
if( *column_size == SQLSRV_SIZE_MAX_TYPE ) {
*column_size = SQL_SS_LENGTH_UNLIMITED;
@ -1731,7 +1726,7 @@ sqlsrv_phptype determine_sqlsrv_php_type( _In_ ss_sqlsrv_stmt const* stmt, _In_
case SQL_SS_TIME2:
case SQL_TYPE_TIMESTAMP:
{
if (stmt->date_as_string) {
if (stmt->date_as_string) {
sqlsrv_phptype.typeinfo.type = SQLSRV_PHPTYPE_STRING;
sqlsrv_phptype.typeinfo.encoding = stmt->encoding();
}
@ -1749,7 +1744,7 @@ sqlsrv_phptype determine_sqlsrv_php_type( _In_ ss_sqlsrv_stmt const* stmt, _In_
if( sqlsrv_phptype.typeinfo.encoding == SQLSRV_ENCODING_DEFAULT ) {
sqlsrv_phptype.typeinfo.encoding = stmt->conn->encoding();
}
return sqlsrv_phptype;
}
@ -1793,9 +1788,9 @@ void determine_stmt_has_rows( _Inout_ ss_sqlsrv_stmt* stmt TSRMLS_DC )
}
}
else {
// otherwise, we fetch the first row, but record that we did. sqlsrv_fetch checks this
// flag and simply skips the first fetch, knowing it was already done. It records its own
// flag and simply skips the first fetch, knowing it was already done. It records its own
// flags to know if it should fetch on subsequent calls.
r = core::SQLFetchScroll( stmt, SQL_FETCH_NEXT, 0 TSRMLS_CC );
@ -1812,7 +1807,7 @@ SQLSMALLINT get_resultset_meta_data(_Inout_ sqlsrv_stmt * stmt)
{
// get the numer of columns in the result set
SQLSMALLINT num_cols = -1;
num_cols = stmt->current_meta_data.size();
bool getMetaData = false;
@ -1887,8 +1882,8 @@ void fetch_fields_common( _Inout_ ss_sqlsrv_stmt* stmt, _In_ zend_long fetch_typ
throw ss::SSException();
}
#else
array_init(&fields);
#endif
array_init(&fields);
#endif
for( int i = 0; i < num_cols; ++i ) {
SQLLEN field_len = -1;
@ -1924,7 +1919,7 @@ void fetch_fields_common( _Inout_ ss_sqlsrv_stmt* stmt, _In_ zend_long fetch_typ
}
}
//only addref when the fetch_type is BOTH because this is the only case when fields(hashtable)
//has 2 elements pointing to field. Do not addref if the type is NUMERIC or ASSOC because
//has 2 elements pointing to field. Do not addref if the type is NUMERIC or ASSOC because
//fields now only has 1 element pointing to field and we want the ref count to be only 1
if (fetch_type == SQLSRV_FETCH_BOTH) {
Z_TRY_ADDREF(field);
@ -1934,7 +1929,7 @@ void fetch_fields_common( _Inout_ ss_sqlsrv_stmt* stmt, _In_ zend_long fetch_typ
}
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_ SQLSRV_PHPTYPE& php_out_type, _Out_ SQLSRV_ENCODING& encoding, _Out_ SQLSMALLINT& sql_type,
_Out_ SQLULEN& column_size, _Out_ SQLSMALLINT& decimal_digits TSRMLS_DC )
{
@ -1954,7 +1949,7 @@ void parse_param_array( _Inout_ ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array,
// handle the array parameters that contain the value/var, direction, php_type, sql_type
zend_hash_internal_pointer_reset_ex( param_ht, &pos );
if( zend_hash_has_more_elements_ex( param_ht, &pos ) == FAILURE ||
if( zend_hash_has_more_elements_ex( param_ht, &pos ) == FAILURE ||
(var_or_val = zend_hash_get_current_data_ex(param_ht, &pos)) == NULL) {
THROW_SS_ERROR( stmt, SS_SQLSRV_ERROR_VAR_REQUIRED, index + 1 );
@ -1977,7 +1972,7 @@ void parse_param_array( _Inout_ ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array,
CHECK_CUSTOM_ERROR( !Z_ISREF_P( var_or_val ) && ( direction == SQL_PARAM_OUTPUT || direction == SQL_PARAM_INPUT_OUTPUT ), stmt, SS_SQLSRV_ERROR_PARAM_VAR_NOT_REF, index + 1 ) {
throw ss::SSException();
}
}
else {
direction = SQL_PARAM_INPUT;
@ -1986,7 +1981,7 @@ void parse_param_array( _Inout_ ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array,
// extract the php type and encoding from the 3rd parameter
if ( zend_hash_move_forward_ex( param_ht, &pos ) == SUCCESS && ( temp = zend_hash_get_current_data_ex( param_ht, &pos )) != NULL &&
Z_TYPE_P( temp ) != IS_NULL ) {
php_type_param_was_null = false;
sqlsrv_phptype sqlsrv_phptype;
@ -1997,7 +1992,7 @@ void parse_param_array( _Inout_ ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array,
sqlsrv_phptype.value = Z_LVAL_P( temp );
CHECK_CUSTOM_ERROR( !is_valid_sqlsrv_phptype( sqlsrv_phptype ), stmt, SQLSRV_ERROR_INVALID_PARAMETER_PHPTYPE,
CHECK_CUSTOM_ERROR( !is_valid_sqlsrv_phptype( sqlsrv_phptype ), stmt, SQLSRV_ERROR_INVALID_PARAMETER_PHPTYPE,
index + 1 ) {
throw ss::SSException();
@ -2005,7 +2000,7 @@ void parse_param_array( _Inout_ ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array,
php_out_type = static_cast<SQLSRV_PHPTYPE>( sqlsrv_phptype.typeinfo.type );
encoding = ( SQLSRV_ENCODING ) sqlsrv_phptype.typeinfo.encoding;
// if the call has a SQLSRV_PHPTYPE_STRING/STREAM('default'), then the stream is in the encoding established
// if the call has a SQLSRV_PHPTYPE_STRING/STREAM('default'), then the stream is in the encoding established
// by the connection
if( encoding == SQLSRV_ENCODING_DEFAULT ) {
encoding = stmt->conn->encoding();
@ -2013,7 +2008,7 @@ void parse_param_array( _Inout_ ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array,
}
// set default for php type and encoding if not supplied
else {
php_type_param_was_null = true;
if ( Z_ISREF_P( var_or_val )){
@ -2025,7 +2020,7 @@ void parse_param_array( _Inout_ ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array,
encoding = stmt->encoding();
if( encoding == SQLSRV_ENCODING_DEFAULT ) {
encoding = stmt->conn->encoding();
}
}
}
// get the server type, column size/precision and the decimal digits if provided
@ -2042,12 +2037,12 @@ void parse_param_array( _Inout_ ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array,
sqlsrv_sql_type.value = Z_LVAL_P( temp );
// since the user supplied this type, make sure it's valid
CHECK_CUSTOM_ERROR( !is_valid_sqlsrv_sqltype( sqlsrv_sql_type ), stmt, SQLSRV_ERROR_INVALID_PARAMETER_SQLTYPE,
CHECK_CUSTOM_ERROR( !is_valid_sqlsrv_sqltype( sqlsrv_sql_type ), stmt, SQLSRV_ERROR_INVALID_PARAMETER_SQLTYPE,
index + 1 ) {
throw ss::SSException();
}
}
bool size_okay = determine_column_size_or_precision( stmt, sqlsrv_sql_type, &column_size, &decimal_digits );
CHECK_CUSTOM_ERROR( !size_okay, stmt, SS_SQLSRV_ERROR_INVALID_PARAMETER_PRECISION, index + 1 ) {
@ -2076,7 +2071,7 @@ void parse_param_array( _Inout_ ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array,
sqlsrv_phptype sqlsrv_phptype;
sqlsrv_phptype = determine_sqlsrv_php_type( stmt, sql_type, (SQLUINTEGER)column_size, true );
// we DIE here since everything should have been validated already and to return the user an error
// for our own logic error would be confusing/misleading.
SQLSRV_ASSERT( sqlsrv_phptype.typeinfo.type != PHPTYPE_INVALID, "An invalid php type was returned with (supposed) "
@ -2121,7 +2116,7 @@ bool is_valid_sqlsrv_phptype( _In_ sqlsrv_phptype type )
case SQLSRV_PHPTYPE_STRING:
case SQLSRV_PHPTYPE_STREAM:
{
if( type.typeinfo.encoding == SQLSRV_ENCODING_BINARY || type.typeinfo.encoding == SQLSRV_ENCODING_CHAR
if( type.typeinfo.encoding == SQLSRV_ENCODING_BINARY || type.typeinfo.encoding == SQLSRV_ENCODING_CHAR
|| type.typeinfo.encoding == CP_UTF8 || type.typeinfo.encoding == SQLSRV_ENCODING_DEFAULT ) {
return true;
}
@ -2152,7 +2147,7 @@ bool is_valid_sqlsrv_sqltype( _In_ sqlsrv_sqltype sql_type )
case SQL_BINARY:
case SQL_CHAR:
case SQL_WCHAR:
case SQL_WVARCHAR:
case SQL_WVARCHAR:
case SQL_VARBINARY:
case SQL_VARCHAR:
case SQL_DECIMAL:
@ -2202,7 +2197,7 @@ void type_and_size_calc( INTERNAL_FUNCTION_PARAMETERS, _In_ int type )
int size = 0;
if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s", &size_p, &size_len ) == FAILURE ) {
return;
}
if (size_p) {
@ -2226,7 +2221,7 @@ void type_and_size_calc( INTERNAL_FUNCTION_PARAMETERS, _In_ int type )
}
int max_size = SQL_SERVER_MAX_FIELD_SIZE;
// size is actually the number of characters, not the number of bytes, so if they ask for a
// size is actually the number of characters, not the number of bytes, so if they ask for a
// 2 byte per character type, then we half the maximum size allowed.
if( type == SQL_WVARCHAR || type == SQL_WCHAR ) {
max_size >>= 1;
@ -2236,7 +2231,7 @@ void type_and_size_calc( INTERNAL_FUNCTION_PARAMETERS, _In_ int type )
LOG( SEV_ERROR, "invalid size. size must be > 0 and <= %1!d! characters or 'max'", max_size );
size = SQLSRV_INVALID_SIZE;
}
sqlsrv_sqltype sql_type;
sql_type.typeinfo.type = type;
sql_type.typeinfo.size = size;
@ -2253,15 +2248,15 @@ void type_and_precision_calc( INTERNAL_FUNCTION_PARAMETERS, _In_ int type )
zend_long scale = SQLSRV_INVALID_SCALE;
if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &prec, &scale ) == FAILURE ) {
return;
}
if( prec > SQL_SERVER_MAX_PRECISION ) {
LOG( SEV_ERROR, "Invalid precision. Precision can't be > 38" );
prec = SQLSRV_INVALID_PRECISION;
}
if( prec < 0 ) {
LOG( SEV_ERROR, "Invalid precision. Precision can't be negative" );
prec = SQLSRV_INVALID_PRECISION;
@ -2285,11 +2280,11 @@ void type_and_precision_calc( INTERNAL_FUNCTION_PARAMETERS, _In_ 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." );
SQLSRV_ASSERT(( type == SQLSRV_PHPTYPE_STREAM || type == SQLSRV_PHPTYPE_STRING ), "type_and_encoding: Invalid type passed." );
char* encoding_param;
size_t encoding_param_len = 0;
// set the default encoding values to invalid so that
// if the encoding isn't validated, it will return the invalid setting.
sqlsrv_phptype sqlsrv_php_type;
@ -2297,7 +2292,7 @@ void type_and_encoding( INTERNAL_FUNCTION_PARAMETERS, _In_ int type )
sqlsrv_php_type.typeinfo.encoding = SQLSRV_ENCODING_INVALID;
if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s", &encoding_param, &encoding_param_len ) == FAILURE ) {
ZVAL_LONG( return_value, sqlsrv_php_type.value );
}