@@ -960,24 +960,34 @@ PHP_FUNCTION(odbc_prepare)
960
960
* Execute prepared SQL statement. Supports only input parameters.
961
961
*/
962
962
963
+ typedef struct odbc_params_t {
964
+ SQLLEN vallen ;
965
+ int fp ;
966
+ } odbc_params_t ;
967
+
968
+ static void odbc_release_params (odbc_result * result , odbc_params_t * params ) {
969
+ SQLFreeStmt (result -> stmt , SQL_RESET_PARAMS );
970
+ for (int i = 0 ; i < result -> numparams ; i ++ ) {
971
+ if (params [i ].fp != -1 ) {
972
+ close (params [i ].fp );
973
+ }
974
+ }
975
+ efree (params );
976
+ }
977
+
963
978
/* {{{ Execute a prepared statement */
964
979
PHP_FUNCTION (odbc_execute )
965
980
{
966
981
zval * pv_res , * tmp ;
967
982
HashTable * pv_param_ht = (HashTable * ) & zend_empty_array ;
968
- typedef struct params_t {
969
- SQLLEN vallen ;
970
- int fp ;
971
- } params_t ;
972
- params_t * params = NULL ;
983
+ odbc_params_t * params = NULL ;
973
984
char * filename ;
974
- unsigned char otype ;
975
985
SQLSMALLINT ctype ;
976
- odbc_result * result ;
986
+ odbc_result * result ;
977
987
int i , ne ;
978
988
RETCODE rc ;
979
989
980
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "r|h/ " , & pv_res , & pv_param_ht ) == FAILURE ) {
990
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "r|h" , & pv_res , & pv_param_ht ) == FAILURE ) {
981
991
RETURN_THROWS ();
982
992
}
983
993
@@ -991,38 +1001,21 @@ PHP_FUNCTION(odbc_execute)
991
1001
RETURN_FALSE ;
992
1002
}
993
1003
994
- zend_hash_internal_pointer_reset (pv_param_ht );
995
- params = (params_t * )safe_emalloc (sizeof (params_t ), result -> numparams , 0 );
1004
+ params = (odbc_params_t * )safe_emalloc (sizeof (odbc_params_t ), result -> numparams , 0 );
996
1005
for (i = 0 ; i < result -> numparams ; i ++ ) {
997
1006
params [i ].fp = -1 ;
998
1007
}
999
1008
1000
- for (i = 1 ; i <= result -> numparams ; i ++ ) {
1001
- if ((tmp = zend_hash_get_current_data (pv_param_ht )) == NULL ) {
1002
- php_error_docref (NULL , E_WARNING ,"Error getting parameter" );
1003
- SQLFreeStmt (result -> stmt ,SQL_RESET_PARAMS );
1004
- for (i = 0 ; i < result -> numparams ; i ++ ) {
1005
- if (params [i ].fp != -1 ) {
1006
- close (params [i ].fp );
1007
- }
1008
- }
1009
- efree (params );
1010
- RETURN_FALSE ;
1011
- }
1012
-
1013
- otype = Z_TYPE_P (tmp );
1014
- if (!try_convert_to_string (tmp )) {
1015
- SQLFreeStmt (result -> stmt , SQL_RESET_PARAMS );
1016
- for (i = 0 ; i < result -> numparams ; i ++ ) {
1017
- if (params [i ].fp != -1 ) {
1018
- close (params [i ].fp );
1019
- }
1020
- }
1021
- efree (params );
1009
+ i = 1 ;
1010
+ ZEND_HASH_FOREACH_VAL (pv_param_ht , tmp ) {
1011
+ unsigned char otype = Z_TYPE_P (tmp );
1012
+ zend_string * tmpstr = zval_try_get_string (tmp );
1013
+ if (!tmpstr ) {
1014
+ odbc_release_params (result , params );
1022
1015
RETURN_THROWS ();
1023
1016
}
1024
1017
1025
- params [i - 1 ].vallen = Z_STRLEN_P ( tmp );
1018
+ params [i - 1 ].vallen = ZSTR_LEN ( tmpstr );
1026
1019
params [i - 1 ].fp = -1 ;
1027
1020
1028
1021
if (IS_SQL_BINARY (result -> param_info [i - 1 ].sqltype )) {
@@ -1031,38 +1024,30 @@ PHP_FUNCTION(odbc_execute)
1031
1024
ctype = SQL_C_CHAR ;
1032
1025
}
1033
1026
1034
- if (Z_STRLEN_P ( tmp ) > 2 &&
1035
- Z_STRVAL_P ( tmp )[0 ] == '\'' &&
1036
- Z_STRVAL_P ( tmp )[ Z_STRLEN_P ( tmp ) - 1 ] == '\'' ) {
1027
+ if (ZSTR_LEN ( tmpstr ) > 2 &&
1028
+ ZSTR_VAL ( tmpstr )[0 ] == '\'' &&
1029
+ ZSTR_VAL ( tmpstr )[ ZSTR_LEN ( tmpstr ) - 1 ] == '\'' ) {
1037
1030
1038
- if (CHECK_ZVAL_NULL_PATH (tmp )) {
1031
+ if (ZSTR_LEN (tmpstr ) != strlen (ZSTR_VAL (tmpstr ))) {
1032
+ odbc_release_params (result , params );
1033
+ zend_string_release (tmpstr );
1039
1034
RETURN_FALSE ;
1040
1035
}
1041
- filename = estrndup (& Z_STRVAL_P ( tmp )[1 ], Z_STRLEN_P ( tmp ) - 2 );
1036
+ filename = estrndup (& ZSTR_VAL ( tmpstr )[1 ], ZSTR_LEN ( tmpstr ) - 2 );
1042
1037
filename [strlen (filename )] = '\0' ;
1043
1038
1044
1039
/* Check the basedir */
1045
1040
if (php_check_open_basedir (filename )) {
1046
1041
efree (filename );
1047
- SQLFreeStmt (result -> stmt , SQL_RESET_PARAMS );
1048
- for (i = 0 ; i < result -> numparams ; i ++ ) {
1049
- if (params [i ].fp != -1 ) {
1050
- close (params [i ].fp );
1051
- }
1052
- }
1053
- efree (params );
1042
+ odbc_release_params (result , params );
1043
+ zend_string_release (tmpstr );
1054
1044
RETURN_FALSE ;
1055
1045
}
1056
1046
1057
1047
if ((params [i - 1 ].fp = open (filename ,O_RDONLY )) == -1 ) {
1058
1048
php_error_docref (NULL , E_WARNING ,"Can't open file %s" , filename );
1059
- SQLFreeStmt (result -> stmt , SQL_RESET_PARAMS );
1060
- for (i = 0 ; i < result -> numparams ; i ++ ) {
1061
- if (params [i ].fp != -1 ) {
1062
- close (params [i ].fp );
1063
- }
1064
- }
1065
- efree (params );
1049
+ odbc_release_params (result , params );
1050
+ zend_string_release (tmpstr );
1066
1051
efree (filename );
1067
1052
RETURN_FALSE ;
1068
1053
}
@@ -1085,22 +1070,18 @@ PHP_FUNCTION(odbc_execute)
1085
1070
1086
1071
rc = SQLBindParameter (result -> stmt , (SQLUSMALLINT )i , SQL_PARAM_INPUT ,
1087
1072
ctype , result -> param_info [i - 1 ].sqltype , result -> param_info [i - 1 ].precision , result -> param_info [i - 1 ].scale ,
1088
- Z_STRVAL_P ( tmp ), 0 ,
1073
+ ZSTR_VAL ( tmpstr ), 0 ,
1089
1074
& params [i - 1 ].vallen );
1090
1075
}
1091
1076
if (rc == SQL_ERROR ) {
1092
1077
odbc_sql_error (result -> conn_ptr , result -> stmt , "SQLBindParameter" );
1093
- SQLFreeStmt (result -> stmt , SQL_RESET_PARAMS );
1094
- for (i = 0 ; i < result -> numparams ; i ++ ) {
1095
- if (params [i ].fp != -1 ) {
1096
- close (params [i ].fp );
1097
- }
1098
- }
1099
- efree (params );
1078
+ odbc_release_params (result , params );
1079
+ zend_string_release (tmpstr );
1100
1080
RETURN_FALSE ;
1101
1081
}
1102
- zend_hash_move_forward (pv_param_ht );
1103
- }
1082
+ zend_string_release (tmpstr );
1083
+ if (++ i > result -> numparams ) break ;
1084
+ } ZEND_HASH_FOREACH_END ();
1104
1085
}
1105
1086
/* Close cursor, needed for doing multiple selects */
1106
1087
rc = SQLFreeStmt (result -> stmt , SQL_CLOSE );
@@ -1109,42 +1090,35 @@ PHP_FUNCTION(odbc_execute)
1109
1090
odbc_sql_error (result -> conn_ptr , result -> stmt , "SQLFreeStmt" );
1110
1091
}
1111
1092
1112
- rc = SQLExecute (result -> stmt );
1113
-
1114
1093
result -> fetched = 0 ;
1115
- if (rc == SQL_NEED_DATA ) {
1116
- char buf [4096 ];
1117
- int fp , nbytes ;
1118
- while (rc == SQL_NEED_DATA ) {
1119
- rc = SQLParamData (result -> stmt , (void * )& fp );
1120
- if (rc == SQL_NEED_DATA ) {
1121
- while ((nbytes = read (fp , & buf , 4096 )) > 0 ) {
1122
- SQLPutData (result -> stmt , (void * )& buf , nbytes );
1094
+ rc = SQLExecute (result -> stmt );
1095
+ switch (rc ) {
1096
+ case SQL_NEED_DATA : {
1097
+ char buf [4096 ];
1098
+ int fp , nbytes ;
1099
+ while (rc == SQL_NEED_DATA ) {
1100
+ rc = SQLParamData (result -> stmt , (void * )& fp );
1101
+ if (rc == SQL_NEED_DATA ) {
1102
+ while ((nbytes = read (fp , & buf , 4096 )) > 0 ) {
1103
+ SQLPutData (result -> stmt , (void * )& buf , nbytes );
1104
+ }
1123
1105
}
1124
1106
}
1107
+ break ;
1125
1108
}
1126
- } else {
1127
- switch (rc ) {
1128
- case SQL_SUCCESS :
1129
- break ;
1130
- case SQL_NO_DATA_FOUND :
1131
- case SQL_SUCCESS_WITH_INFO :
1132
- odbc_sql_error (result -> conn_ptr , result -> stmt , "SQLExecute" );
1133
- break ;
1134
- default :
1135
- odbc_sql_error (result -> conn_ptr , result -> stmt , "SQLExecute" );
1136
- RETVAL_FALSE ;
1137
- }
1109
+ case SQL_SUCCESS :
1110
+ break ;
1111
+ case SQL_NO_DATA_FOUND :
1112
+ case SQL_SUCCESS_WITH_INFO :
1113
+ odbc_sql_error (result -> conn_ptr , result -> stmt , "SQLExecute" );
1114
+ break ;
1115
+ default :
1116
+ odbc_sql_error (result -> conn_ptr , result -> stmt , "SQLExecute" );
1117
+ RETVAL_FALSE ;
1138
1118
}
1139
1119
1140
1120
if (result -> numparams > 0 ) {
1141
- SQLFreeStmt (result -> stmt , SQL_RESET_PARAMS );
1142
- for (i = 0 ; i < result -> numparams ; i ++ ) {
1143
- if (params [i ].fp != -1 ) {
1144
- close (params [i ].fp );
1145
- }
1146
- }
1147
- efree (params );
1121
+ odbc_release_params (result , params );
1148
1122
}
1149
1123
1150
1124
if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO || rc == SQL_NO_DATA_FOUND ) {
0 commit comments