Skip to content

Commit 3eae7aa

Browse files
committed
Don't separate array parameter
Closes GH-6243.
1 parent a9e96a3 commit 3eae7aa

File tree

1 file changed

+65
-91
lines changed

1 file changed

+65
-91
lines changed

ext/odbc/php_odbc.c

Lines changed: 65 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -960,24 +960,34 @@ PHP_FUNCTION(odbc_prepare)
960960
* Execute prepared SQL statement. Supports only input parameters.
961961
*/
962962

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+
963978
/* {{{ Execute a prepared statement */
964979
PHP_FUNCTION(odbc_execute)
965980
{
966981
zval *pv_res, *tmp;
967982
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;
973984
char *filename;
974-
unsigned char otype;
975985
SQLSMALLINT ctype;
976-
odbc_result *result;
986+
odbc_result *result;
977987
int i, ne;
978988
RETCODE rc;
979989

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) {
981991
RETURN_THROWS();
982992
}
983993

@@ -991,38 +1001,21 @@ PHP_FUNCTION(odbc_execute)
9911001
RETURN_FALSE;
9921002
}
9931003

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);
9961005
for(i = 0; i < result->numparams; i++) {
9971006
params[i].fp = -1;
9981007
}
9991008

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);
10221015
RETURN_THROWS();
10231016
}
10241017

1025-
params[i-1].vallen = Z_STRLEN_P(tmp);
1018+
params[i-1].vallen = ZSTR_LEN(tmpstr);
10261019
params[i-1].fp = -1;
10271020

10281021
if (IS_SQL_BINARY(result->param_info[i-1].sqltype)) {
@@ -1031,38 +1024,30 @@ PHP_FUNCTION(odbc_execute)
10311024
ctype = SQL_C_CHAR;
10321025
}
10331026

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] == '\'') {
10371030

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);
10391034
RETURN_FALSE;
10401035
}
1041-
filename = estrndup(&Z_STRVAL_P(tmp)[1], Z_STRLEN_P(tmp) - 2);
1036+
filename = estrndup(&ZSTR_VAL(tmpstr)[1], ZSTR_LEN(tmpstr) - 2);
10421037
filename[strlen(filename)] = '\0';
10431038

10441039
/* Check the basedir */
10451040
if (php_check_open_basedir(filename)) {
10461041
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);
10541044
RETURN_FALSE;
10551045
}
10561046

10571047
if ((params[i-1].fp = open(filename,O_RDONLY)) == -1) {
10581048
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);
10661051
efree(filename);
10671052
RETURN_FALSE;
10681053
}
@@ -1085,22 +1070,18 @@ PHP_FUNCTION(odbc_execute)
10851070

10861071
rc = SQLBindParameter(result->stmt, (SQLUSMALLINT)i, SQL_PARAM_INPUT,
10871072
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,
10891074
&params[i-1].vallen);
10901075
}
10911076
if (rc == SQL_ERROR) {
10921077
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);
11001080
RETURN_FALSE;
11011081
}
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();
11041085
}
11051086
/* Close cursor, needed for doing multiple selects */
11061087
rc = SQLFreeStmt(result->stmt, SQL_CLOSE);
@@ -1109,42 +1090,35 @@ PHP_FUNCTION(odbc_execute)
11091090
odbc_sql_error(result->conn_ptr, result->stmt, "SQLFreeStmt");
11101091
}
11111092

1112-
rc = SQLExecute(result->stmt);
1113-
11141093
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+
}
11231105
}
11241106
}
1107+
break;
11251108
}
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;
11381118
}
11391119

11401120
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);
11481122
}
11491123

11501124
if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO || rc == SQL_NO_DATA_FOUND) {

0 commit comments

Comments
 (0)