diff options
Diffstat (limited to 'ext/odbc/php_odbc.c')
-rw-r--r-- | ext/odbc/php_odbc.c | 70 |
1 files changed, 41 insertions, 29 deletions
diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c index 11fecbd617..f432dcd551 100644 --- a/ext/odbc/php_odbc.c +++ b/ext/odbc/php_odbc.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 7 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2015 The PHP Group | + | Copyright (c) 1997-2016 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -387,7 +387,7 @@ const zend_function_entry odbc_functions[] = { }; /* }}} */ -ZEND_DECLARE_MODULE_GLOBALS(odbc) +PHP_ODBC_API ZEND_DECLARE_MODULE_GLOBALS(odbc) static PHP_GINIT_FUNCTION(odbc); /* {{{ odbc_module_entry @@ -412,7 +412,7 @@ zend_module_entry odbc_module_entry = { #ifdef COMPILE_DL_ODBC #ifdef ZTS -ZEND_TSRMLS_CACHE_DEFINE(); +ZEND_TSRMLS_CACHE_DEFINE() #endif ZEND_GET_MODULE(odbc) #endif @@ -434,7 +434,8 @@ static void _free_odbc_result(zend_resource *rsrc) efree(res->values); res->values = NULL; } - if (res->stmt) { + /* If aborted via timer expiration, don't try to call any unixODBC function */ + if (res->stmt && !(PG(connection_status) & PHP_CONNECTION_TIMEOUT)) { #if defined(HAVE_SOLID) || defined(HAVE_SOLID_30) || defined(HAVE_SOLID_35) SQLTransact(res->conn_ptr->henv, res->conn_ptr->hdbc, (SQLUSMALLINT) SQL_COMMIT); @@ -445,6 +446,9 @@ static void _free_odbc_result(zend_resource *rsrc) * zend_list_delete(res->conn_ptr->id); */ } + if (res->param_info) { + efree(res->param_info); + } efree(res); } } @@ -484,9 +488,12 @@ static void _close_odbc_conn(zend_resource *rsrc) } } ZEND_HASH_FOREACH_END(); - safe_odbc_disconnect(conn->hdbc); - SQLFreeConnect(conn->hdbc); - SQLFreeEnv(conn->henv); + /* If aborted via timer expiration, don't try to call any unixODBC function */ + if (!(PG(connection_status) & PHP_CONNECTION_TIMEOUT)) { + safe_odbc_disconnect(conn->hdbc); + SQLFreeConnect(conn->hdbc); + SQLFreeEnv(conn->henv); + } efree(conn); ODBCG(num_links)--; } @@ -509,9 +516,12 @@ static void _close_odbc_pconn(zend_resource *rsrc) } } ZEND_HASH_FOREACH_END(); - safe_odbc_disconnect(conn->hdbc); - SQLFreeConnect(conn->hdbc); - SQLFreeEnv(conn->henv); + /* If aborted via timer expiration, don't try to call any unixODBC function */ + if (!(PG(connection_status) & PHP_CONNECTION_TIMEOUT)) { + safe_odbc_disconnect(conn->hdbc); + SQLFreeConnect(conn->hdbc); + SQLFreeEnv(conn->henv); + } free(conn); ODBCG(num_links)--; @@ -1184,6 +1194,7 @@ PHP_FUNCTION(odbc_prepare) odbc_result *result = NULL; odbc_connection *conn; RETCODE rc; + int i; #ifdef HAVE_SQL_EXTENDED_FETCH SQLUINTEGER scrollopts; #endif @@ -1199,6 +1210,7 @@ PHP_FUNCTION(odbc_prepare) result = (odbc_result *)ecalloc(1, sizeof(odbc_result)); result->numparams = 0; + result->param_info = NULL; rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt)); if (rc == SQL_INVALID_HANDLE) { @@ -1255,6 +1267,20 @@ PHP_FUNCTION(odbc_prepare) Z_ADDREF_P(pv_conn); result->conn_ptr = conn; result->fetched = 0; + + result->param_info = (odbc_param_info *) safe_emalloc(sizeof(odbc_param_info), result->numparams, 0); + for (i=0;i<result->numparams;i++) { + rc = SQLDescribeParam(result->stmt, (SQLUSMALLINT)(i+1), &result->param_info[i].sqltype, &result->param_info[i].precision, + &result->param_info[i].scale, &result->param_info[i].nullable); + if (rc == SQL_ERROR) { + odbc_sql_error(result->conn_ptr, result->stmt, "SQLDescribeParameter"); + SQLFreeStmt(result->stmt, SQL_RESET_PARAMS); + efree(result->param_info); + efree(result); + RETURN_FALSE; + } + } + RETURN_RES(zend_register_resource(result, le_result)); } /* }}} */ @@ -1275,9 +1301,7 @@ PHP_FUNCTION(odbc_execute) params_t *params = NULL; char *filename; unsigned char otype; - SQLSMALLINT sqltype, ctype, scale; - SQLSMALLINT nullable; - SQLULEN precision; + SQLSMALLINT ctype; odbc_result *result; int numArgs, i, ne; RETCODE rc; @@ -1337,22 +1361,10 @@ PHP_FUNCTION(odbc_execute) RETURN_FALSE; } - rc = SQLDescribeParam(result->stmt, (SQLUSMALLINT)i, &sqltype, &precision, &scale, &nullable); params[i-1].vallen = Z_STRLEN_P(tmp); params[i-1].fp = -1; - if (rc == SQL_ERROR) { - odbc_sql_error(result->conn_ptr, result->stmt, "SQLDescribeParam"); - SQLFreeStmt(result->stmt, SQL_RESET_PARAMS); - for (i = 0; i < result->numparams; i++) { - if (params[i].fp != -1) { - close(params[i].fp); - } - } - efree(params); - RETURN_FALSE; - } - if (IS_SQL_BINARY(sqltype)) { + if (IS_SQL_BINARY(result->param_info[i-1].sqltype)) { ctype = SQL_C_BINARY; } else { ctype = SQL_C_CHAR; @@ -1399,7 +1411,7 @@ PHP_FUNCTION(odbc_execute) params[i-1].vallen = SQL_LEN_DATA_AT_EXEC(0); rc = SQLBindParameter(result->stmt, (SQLUSMALLINT)i, SQL_PARAM_INPUT, - ctype, sqltype, precision, scale, + ctype, result->param_info[i-1].sqltype, result->param_info[i-1].precision, result->param_info[i-1].scale, (void *)(intptr_t)params[i-1].fp, 0, ¶ms[i-1].vallen); } else { @@ -1411,7 +1423,7 @@ PHP_FUNCTION(odbc_execute) } rc = SQLBindParameter(result->stmt, (SQLUSMALLINT)i, SQL_PARAM_INPUT, - ctype, sqltype, precision, scale, + ctype, result->param_info[i-1].sqltype, result->param_info[i-1].precision, result->param_info[i-1].scale, Z_STRVAL_P(tmp), 0, ¶ms[i-1].vallen); } @@ -1530,7 +1542,7 @@ PHP_FUNCTION(odbc_cursor) result->stmt, state, &error, errormsg, sizeof(errormsg)-1, &errormsgsize); if (!strncmp(state,"S1015",5)) { - snprintf(cursorname, max_len+1, "php_curs_%d", (int)result->stmt); + snprintf(cursorname, max_len+1, "php_curs_" ZEND_ULONG_FMT, (zend_ulong)result->stmt); if (SQLSetCursorName(result->stmt,cursorname,SQL_NTS) != SQL_SUCCESS) { odbc_sql_error(result->conn_ptr, result->stmt, "SQLSetCursorName"); RETVAL_FALSE; |