From: Christopher Jones Date: Thu, 30 Jul 2015 10:25:40 +0000 (+1000) Subject: More PHP7 compat (Rajendra/Senthil) X-Git-Tag: php-7.0.0beta3~5^2~45 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=70a7221540567ed77dcc176b00e56bcbe1407d68;p=php More PHP7 compat (Rajendra/Senthil) --- diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c index 2c65ea94f9..9eae15e346 100644 --- a/ext/oci8/oci8.c +++ b/ext/oci8/oci8.c @@ -100,13 +100,6 @@ zend_class_entry *oci_coll_class_entry_ptr; #define SQLT_CFILEE 115 #endif -#ifdef OCI_ERROR_MAXMSG_SIZE2 -/* Bigger size is defined from 11.2.0.3 onwards */ -#define PHP_OCI_ERRBUF_LEN OCI_ERROR_MAXMSG_SIZE2 -#else -#define PHP_OCI_ERRBUF_LEN OCI_ERROR_MAXMSG_SIZE -#endif - #if ZEND_MODULE_API_NO > 20020429 #define ONUPDATELONGFUNC OnUpdateLong #else @@ -1084,7 +1077,7 @@ static void php_oci_init_global_handles(void) { sword errstatus; sb4 ora_error_code = 0; - text tmp_buf[OCI_ERROR_MAXMSG_SIZE]; /* Use traditional smaller size: non-PL/SQL errors should fit and it keeps the stack smaller */ + text tmp_buf[PHP_OCI_ERRBUF_LEN]; /* Use traditional smaller size: non-PL/SQL errors should fit and it keeps the stack smaller */ errstatus = OCIEnvNlsCreate(&OCI_G(env), PHP_OCI_INIT_MODE, 0, NULL, NULL, NULL, 0, NULL, 0, 0); @@ -1095,7 +1088,7 @@ static void php_oci_init_global_handles(void) php_error_docref(NULL, E_WARNING, "OCIEnvNlsCreate() failed. There is something wrong with your system - please check that ORACLE_HOME and " PHP_OCI8_LIB_PATH_MSG " are set and point to the right directories"); #endif if (OCI_G(env) - && OCIErrorGet(OCI_G(env), (ub4)1, NULL, &ora_error_code, tmp_buf, (ub4)OCI_ERROR_MAXMSG_SIZE, (ub4)OCI_HTYPE_ENV) == OCI_SUCCESS + && OCIErrorGet(OCI_G(env), (ub4)1, NULL, &ora_error_code, tmp_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ENV) == OCI_SUCCESS && *tmp_buf) { php_error_docref(NULL, E_WARNING, "%s", tmp_buf); } @@ -1124,7 +1117,7 @@ static void php_oci_init_global_handles(void) PHP_OCI_CALL(OCIHandleFree, (cpoolh, OCI_HTYPE_CPOOL)); #endif } else { - OCIErrorGet(OCI_G(env), (ub4)1, NULL, &ora_error_code, tmp_buf, (ub4)OCI_ERROR_MAXMSG_SIZE, (ub4)OCI_HTYPE_ERROR); + OCIErrorGet(OCI_G(env), (ub4)1, NULL, &ora_error_code, tmp_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR); if (ora_error_code) { int tmp_buf_len = strlen((char *)tmp_buf); @@ -1334,7 +1327,7 @@ PHP_MINFO_FUNCTION(oci) { char buf[32]; #if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2))) - char *ver; + char ver[256]; #endif php_info_print_table_start(); @@ -1348,9 +1341,8 @@ PHP_MINFO_FUNCTION(oci) php_info_print_table_row(2, "Revision", "$Id$"); #if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2))) - php_oci_client_get_version(&ver); + php_oci_client_get_version(ver, sizeof(ver)); php_info_print_table_row(2, "Oracle Run-time Client Library Version", ver); - efree(ver); #else php_info_print_table_row(2, "Oracle Run-time Client Library Version", "Unknown"); #endif @@ -1536,8 +1528,6 @@ void php_oci_define_hash_dtor(zval *data) { php_oci_define *define = (php_oci_define *) Z_PTR_P(data); - zval_ptr_dtor(define->zval); - if (define->name) { efree(define->name); define->name = NULL; @@ -1557,18 +1547,20 @@ void php_oci_bind_hash_dtor(zval *data) if (bind->array.elements) { efree(bind->array.elements); + bind->array.elements = NULL; } if (bind->array.element_lengths) { efree(bind->array.element_lengths); + bind->array.element_lengths = NULL; } if (bind->array.indicators) { efree(bind->array.indicators); + bind->array.indicators = NULL; } efree(bind); - zval_ptr_dtor(bind->zval); } /* }}} */ @@ -1585,7 +1577,10 @@ void php_oci_column_hash_dtor(zval *data) } if (column->descid) { - zend_list_close(column->descid); + if (GC_REFCOUNT(column->descid) == 1) + zend_list_close(column->descid); + else + GC_REFCOUNT(column->descid)--; } if (column->data) { @@ -1638,17 +1633,16 @@ void php_oci_connection_descriptors_free(php_oci_connection *connection) */ sb4 php_oci_error(OCIError *err_p, sword errstatus) { - text *errbuf = (text *)NULL; + text errbuf[PHP_OCI_ERRBUF_LEN]; sb4 errcode = 0; /* Oracle error number */ switch (errstatus) { case OCI_SUCCESS: break; case OCI_SUCCESS_WITH_INFO: - errcode = php_oci_fetch_errmsg(err_p, &errbuf); - if (errbuf) { + errcode = php_oci_fetch_errmsg(err_p, errbuf, sizeof(errbuf)); + if (errcode) { php_error_docref(NULL, E_WARNING, "OCI_SUCCESS_WITH_INFO: %s", errbuf); - efree(errbuf); } else { php_error_docref(NULL, E_WARNING, "OCI_SUCCESS_WITH_INFO: failed to fetch error message"); } @@ -1657,19 +1651,17 @@ sb4 php_oci_error(OCIError *err_p, sword errstatus) php_error_docref(NULL, E_WARNING, "OCI_NEED_DATA"); break; case OCI_NO_DATA: - errcode = php_oci_fetch_errmsg(err_p, &errbuf); - if (errbuf) { + errcode = php_oci_fetch_errmsg(err_p, errbuf, sizeof(errbuf)); + if (errcode) { php_error_docref(NULL, E_WARNING, "%s", errbuf); - efree(errbuf); } else { php_error_docref(NULL, E_WARNING, "OCI_NO_DATA: failed to fetch error message"); } break; case OCI_ERROR: - errcode = php_oci_fetch_errmsg(err_p, &errbuf); - if (errbuf) { - php_error_docref(NULL, E_WARNING, "%s", errbuf); - efree(errbuf); + errcode = php_oci_fetch_errmsg(err_p, errbuf, sizeof(errbuf)); + if (errcode) { + php_error_docref(NULL, E_WARNING, "%s", errbuf, sizeof(errbuf)); } else { php_error_docref(NULL, E_WARNING, "failed to fetch error message"); } @@ -1702,24 +1694,17 @@ sb4 php_oci_error(OCIError *err_p, sword errstatus) * * Fetch error message into the buffer from the error handle provided */ -sb4 php_oci_fetch_errmsg(OCIError *error_handle, text **error_buf) +sb4 php_oci_fetch_errmsg(OCIError *error_handle, text *error_buf, size_t error_buf_size) { sb4 error_code = 0; - text err_buf[PHP_OCI_ERRBUF_LEN]; - memset(err_buf, 0, sizeof(err_buf)); - *error_buf = (text *)0; - PHP_OCI_CALL(OCIErrorGet, (error_handle, (ub4)1, NULL, &error_code, err_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR)); + PHP_OCI_CALL(OCIErrorGet, (error_handle, (ub4)1, NULL, &error_code, error_buf, (ub4)error_buf_size, (ub4)OCI_HTYPE_ERROR)); if (error_code) { - int err_buf_len = strlen((char *)err_buf); + int err_buf_len = strlen((char *)error_buf); - if (err_buf_len && err_buf[err_buf_len - 1] == '\n') { - err_buf[err_buf_len - 1] = '\0'; - } - if (err_buf_len && error_buf) { - *error_buf = NULL; - *error_buf = (text *)estrndup((char *)err_buf, err_buf_len); + if (err_buf_len && error_buf[err_buf_len - 1] == '\n') { + error_buf[err_buf_len - 1] = '\0'; } } return error_code; @@ -2013,7 +1998,8 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char tmp = (php_oci_connection *)connection->id->ptr; if (tmp != NULL && tmp->hash_key->len == hashed_details.s->len && - memcmp(tmp->hash_key->val, hashed_details.s->val, tmp->hash_key->len) == 0 && ++GC_REFCOUNT(connection->id) == SUCCESS) { + memcmp(tmp->hash_key->val, hashed_details.s->val, tmp->hash_key->len) == 0) { + ++GC_REFCOUNT(connection->id); /* do nothing */ } else { PHP_OCI_REGISTER_RESOURCE(connection, le_pconnection); @@ -2238,10 +2224,10 @@ static int php_oci_connection_ping(php_oci_connection *connection) return 1; } else { sb4 error_code = 0; - text tmp_buf[OCI_ERROR_MAXMSG_SIZE]; + text tmp_buf[PHP_OCI_ERRBUF_LEN]; /* Treat ORA-1010 as a successful Ping */ - OCIErrorGet(OCI_G(err), (ub4)1, NULL, &error_code, tmp_buf, (ub4)OCI_ERROR_MAXMSG_SIZE, (ub4)OCI_HTYPE_ERROR); + OCIErrorGet(OCI_G(err), (ub4)1, NULL, &error_code, tmp_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR); if (error_code == 1010) { return 1; } @@ -2510,9 +2496,8 @@ int php_oci_password_change(php_oci_connection *connection, char *user, int user * * Get Oracle client library version */ -void php_oci_client_get_version(char **version) +void php_oci_client_get_version(char *version, size_t version_size) { - char version_buff[256]; #if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2))) /* OCIClientVersion only available 10.2 onwards */ sword major_version = 0; sword minor_version = 0; @@ -2521,11 +2506,10 @@ void php_oci_client_get_version(char **version) sword port_update_num = 0; PHP_OCI_CALL(OCIClientVersion, (&major_version, &minor_version, &update_num, &patch_num, &port_update_num)); - snprintf(version_buff, sizeof(version_buff), "%d.%d.%d.%d.%d", major_version, minor_version, update_num, patch_num, port_update_num); + snprintf(version, version_size, "%d.%d.%d.%d.%d", major_version, minor_version, update_num, patch_num, port_update_num); #else - memcpy(version_buff, "Unknown", sizeof("Unknown")); + memcpy(version, "Unknown", sizeof("Unknown")); #endif - *version = estrdup(version_buff); } /* }}} */ @@ -2533,12 +2517,11 @@ void php_oci_client_get_version(char **version) * * Get Oracle server version */ -int php_oci_server_get_version(php_oci_connection *connection, char **version) +int php_oci_server_get_version(php_oci_connection *connection, char *version, size_t version_size) { sword errstatus; - char version_buff[256]; - PHP_OCI_CALL_RETURN(errstatus, OCIServerVersion, (connection->svc, connection->err, (text *)version_buff, sizeof(version_buff), OCI_HTYPE_SVCCTX)); + PHP_OCI_CALL_RETURN(errstatus, OCIServerVersion, (connection->svc, connection->err, (text *)version, version_size, OCI_HTYPE_SVCCTX)); if (errstatus != OCI_SUCCESS) { connection->errcode = php_oci_error(connection->err, errstatus); @@ -2546,7 +2529,6 @@ int php_oci_server_get_version(php_oci_connection *connection, char **version) return 1; } - *version = estrdup(version_buff); return 0; } /* }}} */ @@ -2560,7 +2542,7 @@ int php_oci_column_to_zval(php_oci_out_column *column, zval *value, int mode) php_oci_descriptor *descriptor; ub4 lob_length; int column_size; - char *lob_buffer; + char *lob_buffer = (char *)0; int lob_fetch_status; if (column->indicator == -1) { /* column is NULL */ @@ -2606,6 +2588,8 @@ int php_oci_column_to_zval(php_oci_out_column *column, zval *value, int mode) } else { ZVAL_EMPTY_STRING(value); } + if (lob_buffer) + efree(lob_buffer); return 0; } } else { @@ -2752,7 +2736,53 @@ void php_oci_fetch_row (INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_arg } #endif /* OCI_MAJOR_VERSION */ - array_init(return_value); +#if 0 + if (expected_args > 2) + { + array_init(array); + + for (i = 0; i < statement->ncolumns; i++) { + + column = php_oci_statement_get_column(statement, i + 1, NULL, 0); + + if (column == NULL) { + continue; + } + if ((column->indicator == -1) && ((fetch_mode & PHP_OCI_RETURN_NULLS) == 0)) { + continue; + } + + if (!(column->indicator == -1)) { + zval element; + + php_oci_column_to_zval(column, &element, fetch_mode); + + if (fetch_mode & PHP_OCI_NUM || !(fetch_mode & PHP_OCI_ASSOC)) { + add_index_zval(array, i, &element); + } + if (fetch_mode & PHP_OCI_ASSOC) { + if (fetch_mode & PHP_OCI_NUM) { + Z_TRY_ADDREF_P(&element); + } + add_assoc_zval(array, column->name, &element); + } + + } else { + if (fetch_mode & PHP_OCI_NUM || !(fetch_mode & PHP_OCI_ASSOC)) { + add_index_null(array, i); + } + if (fetch_mode & PHP_OCI_ASSOC) { + add_assoc_null(array, column->name); + } + } + } + + /* RETURN_LONG(statement->ncolumns); */ + } + else +#endif + { + array_init(return_value); for (i = 0; i < statement->ncolumns; i++) { @@ -2792,10 +2822,11 @@ void php_oci_fetch_row (INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_arg if (expected_args > 2) { /* Only for ocifetchinto BC. In all other cases we return array, not long */ - ZVAL_COPY_VALUE(array, return_value); /* copy return_value to given reference */ - zval_dtor(return_value); + ZVAL_COPY(array, return_value); /* copy return_value to given reference */ + /* zval_dtor(return_value); */ RETURN_LONG(statement->ncolumns); } + } } /* }}} */ @@ -3061,7 +3092,7 @@ static OCIEnv *php_oci_create_env(ub2 charsetid) if (OCI_G(errcode) != OCI_SUCCESS) { sb4 ora_error_code = 0; - text ora_msg_buf[OCI_ERROR_MAXMSG_SIZE]; /* Use traditional smaller size: non-PL/SQL errors should fit and it keeps the stack smaller */ + text ora_msg_buf[PHP_OCI_ERRBUF_LEN]; /* Use traditional smaller size: non-PL/SQL errors should fit and it keeps the stack smaller */ #ifdef HAVE_OCI_INSTANT_CLIENT php_error_docref(NULL, E_WARNING, "OCIEnvNlsCreate() failed. There is something wrong with your system - please check that " PHP_OCI8_LIB_PATH_MSG " includes the directory with Oracle Instant Client libraries"); @@ -3069,7 +3100,7 @@ static OCIEnv *php_oci_create_env(ub2 charsetid) php_error_docref(NULL, E_WARNING, "OCIEnvNlsCreate() failed. There is something wrong with your system - please check that ORACLE_HOME and " PHP_OCI8_LIB_PATH_MSG " are set and point to the right directories"); #endif if (retenv - && OCIErrorGet(retenv, (ub4)1, NULL, &ora_error_code, ora_msg_buf, (ub4)OCI_ERROR_MAXMSG_SIZE, (ub4)OCI_HTYPE_ENV) == OCI_SUCCESS + && OCIErrorGet(retenv, (ub4)1, NULL, &ora_error_code, ora_msg_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ENV) == OCI_SUCCESS && *ora_msg_buf) { php_error_docref(NULL, E_WARNING, "%s", ora_msg_buf); } diff --git a/ext/oci8/oci8_interface.c b/ext/oci8/oci8_interface.c index 441dd448a5..5f414bd4ae 100644 --- a/ext/oci8/oci8_interface.c +++ b/ext/oci8/oci8_interface.c @@ -88,11 +88,12 @@ PHP_FUNCTION(oci_define_by_name) RETURN_FALSE; } - define->name = (text*) estrndup(name, name_len); + define->name = (text*) ecalloc(1, name_len+1); + memcpy(define->name, name, name_len); + define->name[name_len] = '\0'; define->name_len = name_len; define->type = type; define->zval = var; - Z_TRY_ADDREF_P(define->zval); RETURN_TRUE; } @@ -183,7 +184,7 @@ PHP_FUNCTION(oci_free_descriptor) PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor); - zend_list_delete(descriptor->id); + zend_list_close(descriptor->id); RETURN_TRUE; } /* }}} */ @@ -305,7 +306,10 @@ PHP_FUNCTION(oci_lob_load) RETURN_FALSE; } if (buffer_len > 0) { - RETURN_STRINGL(buffer, buffer_len); + zend_string *ret = zend_string_init(buffer, buffer_len, 0); + if (buffer) + efree(buffer); + RETURN_STR(ret); } else { RETURN_EMPTY_STRING(); @@ -350,7 +354,9 @@ PHP_FUNCTION(oci_lob_read) RETURN_FALSE; } if (buffer_len > 0) { - RETURN_STRINGL(buffer, buffer_len); + zend_string *ret = zend_string_init(buffer, buffer_len, 0); + efree(buffer); + RETURN_STR(ret); } else { RETURN_EMPTY_STRING(); @@ -951,7 +957,11 @@ PHP_FUNCTION(oci_lob_export) if (length == -1) { length = lob_length - descriptor->lob_current_position; } - + + if (lob_length == 0) { + length = 0; + } + if (length == 0) { /* nothing to write, fail silently */ RETURN_FALSE; @@ -987,7 +997,8 @@ PHP_FUNCTION(oci_lob_export) } if (tmp_bytes_read && !php_stream_write(stream, buffer, tmp_bytes_read)) { php_stream_close(stream); - efree(buffer); + if (buffer) + efree(buffer); RETURN_FALSE; } if (buffer) { @@ -1545,7 +1556,7 @@ PHP_FUNCTION(oci_free_statement) PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement); - zend_list_delete(statement->id); + zend_list_close(statement->id); RETURN_TRUE; } /* }}} */ @@ -1574,9 +1585,10 @@ PHP_FUNCTION(oci_close) } PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection); - zend_list_delete(connection->id); + if (GC_REFCOUNT(connection->id) == 1) + zend_list_close(connection->id); - ZVAL_NULL(z_connection); + /* ZVAL_NULL(z_connection); */ RETURN_TRUE; } @@ -1613,7 +1625,7 @@ PHP_FUNCTION(oci_error) zval *arg = NULL; php_oci_statement *statement; php_oci_connection *connection; - text *errbuf; + text errbuf[PHP_OCI_ERRBUF_LEN]; sb4 errcode = 0; dvoid *errh = NULL; ub2 error_offset = 0; @@ -1663,15 +1675,13 @@ go_out: RETURN_FALSE; } - errcode = php_oci_fetch_errmsg(errh, &errbuf); + errcode = php_oci_fetch_errmsg(errh, errbuf, sizeof(errbuf)); if (errcode) { array_init(return_value); add_assoc_long(return_value, "code", errcode); /* TODO: avoid reallocation ??? */ add_assoc_string(return_value, "message", (char*) errbuf); - if (errbuf) - efree(errbuf); add_assoc_long(return_value, "offset", error_offset); add_assoc_string(return_value, "sqltext", sqltext ? (char *) sqltext : ""); } else { @@ -2064,9 +2074,9 @@ PHP_FUNCTION(oci_result) Return a string containing runtime client library version information */ PHP_FUNCTION(oci_client_version) { - char *version = NULL; + char version[256]; - php_oci_client_get_version(&version); + php_oci_client_get_version(version, sizeof(version)); RETURN_STRING(version); } /* }}} */ @@ -2077,7 +2087,8 @@ PHP_FUNCTION(oci_server_version) { zval *z_connection; php_oci_connection *connection; - char *version = NULL; + char version[256]; + zend_string *ret; if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &z_connection) == FAILURE) { return; @@ -2085,11 +2096,12 @@ PHP_FUNCTION(oci_server_version) PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection); - if (php_oci_server_get_version(connection, &version)) { + if (php_oci_server_get_version(connection, version, sizeof(version))) { RETURN_FALSE; } - RETURN_STRING(version); + ret = zend_string_init(version, strlen(version), 0); + RETURN_STR(ret); } /* }}} */ @@ -2189,7 +2201,7 @@ PHP_FUNCTION(oci_free_collection) PHP_OCI_ZVAL_TO_COLLECTION(tmp, collection); - zend_list_delete(collection->id); + zend_list_close(collection->id); RETURN_TRUE; } /* }}} */ diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c index d27a728d3c..32ce365ea4 100644 --- a/ext/oci8/oci8_statement.c +++ b/ext/oci8/oci8_statement.c @@ -91,7 +91,8 @@ php_oci_statement *php_oci_statement_create(php_oci_connection *connection, char } if (query && query_len) { - statement->last_query = estrndup(query, query_len); + statement->last_query = ecalloc(1, query_len + 1); + memcpy(statement->last_query, query, query_len); statement->last_query_len = query_len; } else { @@ -677,7 +678,8 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode) } PHP_OCI_CALL(OCIDescriptorFree, (param, OCI_DTYPE_PARAM)); - outcol->name = estrndup((char*) colname, outcol->name_len); + outcol->name = ecalloc(1, outcol->name_len + 1); + memcpy(outcol->name, colname, outcol->name_len); /* find a user-set define */ if (statement->defines) { @@ -873,11 +875,6 @@ void php_oci_statement_free(php_oci_statement *statement) efree(statement->last_query); } - if (statement->columns) { - zend_hash_destroy(statement->columns); - efree(statement->columns); - } - if (statement->binds) { zend_hash_destroy(statement->binds); efree(statement->binds); @@ -888,6 +885,11 @@ void php_oci_statement_free(php_oci_statement *statement) efree(statement->defines); } + if (statement->columns) { + zend_hash_destroy(statement->columns); + efree(statement->columns); + } + if (statement->parent_stmtid) { zend_list_delete(statement->parent_stmtid); } @@ -1165,9 +1167,17 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, convert_to_string(var); } if (maxlength == -1) { - value_sz = (Z_TYPE_P(var) == IS_STRING) ? Z_STRLEN_P(var) : 0; + /* + value_sz = (Z_TYPE_P(var) == IS_STRING) ? Z_STRLEN_P(var) : PHP_OCI_PIECE_SIZE; + */ + /* We should use max length as dynamic bind is used */ + value_sz = PHP_OCI_PIECE_SIZE; } else { - value_sz = maxlength; + if (maxlength == 0) { + value_sz = PHP_OCI_PIECE_SIZE; + } else { + value_sz = maxlength; + } } break; @@ -1193,8 +1203,17 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, return 1; } convert_to_boolean(var); - bind_data = (int *)&Z_LVAL_P(var); - value_sz = sizeof(int); + bind_data = (zend_long *)&Z_LVAL_P(var); + if (Z_TYPE_P(var) == IS_TRUE) + *(zend_long *)bind_data = 1; + else if (Z_TYPE_P(var) == IS_FALSE) + *(zend_long *)bind_data = 0; + else { + php_error_docref(NULL, E_WARNING, "Invalid variable used for bind"); + return 1; + } + + value_sz = sizeof(zend_long); mode = OCI_DEFAULT; break; @@ -1205,11 +1224,11 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, return 1; break; } - + if (value_sz == 0) { value_sz = 1; } - + if (!statement->binds) { ALLOC_HASHTABLE(statement->binds); zend_hash_init(statement->binds, 13, NULL, php_oci_bind_hash_dtor, 0); @@ -1217,9 +1236,6 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, if ((old_bind = zend_hash_str_find_ptr(statement->binds, name, name_len)) != NULL) { bindp = old_bind; - if (bindp->zval) { - zval_ptr_dtor(bindp->zval); - } } else { zend_string *zvtmp; zvtmp = zend_string_init(name, name_len, 0); @@ -1233,7 +1249,6 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, bindp->parent_statement = statement; bindp->zval = var; bindp->type = type; - Z_TRY_ADDREF_P(bindp->zval); PHP_OCI_CALL_RETURN(errstatus, OCIBindByName, @@ -1587,53 +1602,65 @@ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int nam return 1; } - if (!statement->binds) { - ALLOC_HASHTABLE(statement->binds); - zend_hash_init(statement->binds, 13, NULL, php_oci_bind_hash_dtor, 0); - } - - zvtmp = zend_string_init(name, name_len, 0); - bindp = zend_hash_update_ptr(statement->binds, zvtmp, bind); - zend_string_release(zvtmp); - - bindp->descriptor = NULL; - bindp->statement = NULL; - bindp->parent_statement = statement; - bindp->bind = NULL; - bindp->zval = var; - bindp->array.type = type; - bindp->indicator = 0; /* not used for array binds */ - bindp->type = 0; /* not used for array binds */ - - Z_TRY_ADDREF_P(var); + bind->descriptor = NULL; + bind->statement = NULL; + bind->parent_statement = statement; + bind->bind = NULL; + bind->zval = var; + bind->array.type = type; + bind->indicator = 0; /* not used for array binds */ + bind->type = 0; /* not used for array binds */ PHP_OCI_CALL_RETURN(errstatus, OCIBindByName, ( statement->stmt, - (OCIBind **)&bindp->bind, + (OCIBind **)&bind->bind, statement->err, (text *)name, name_len, - (dvoid *) bindp->array.elements, - (sb4) bindp->array.max_length, + (dvoid *) bind->array.elements, + (sb4) bind->array.max_length, (ub2)type, - (dvoid *)bindp->array.indicators, - (ub2 *)bindp->array.element_lengths, + (dvoid *)bind->array.indicators, + (ub2 *)bind->array.element_lengths, (ub2 *)0, /* bindp->array.retcodes, */ (ub4) max_table_length, - (ub4 *) &(bindp->array.current_length), + (ub4 *) &(bind->array.current_length), (ub4) OCI_DEFAULT ) ); if (errstatus != OCI_SUCCESS) { - efree(bindp); + if (bind->array.elements) { + efree(bind->array.elements); + } + + if (bind->array.element_lengths) { + efree(bind->array.element_lengths); + } + + if (bind->array.indicators) { + efree(bind->array.indicators); + } + + efree(bind); + statement->errcode = php_oci_error(statement->err, errstatus); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; } + + if (!statement->binds) { + ALLOC_HASHTABLE(statement->binds); + zend_hash_init(statement->binds, 13, NULL, php_oci_bind_hash_dtor, 0); + } + + zvtmp = zend_string_init(name, name_len, 0); + bindp = zend_hash_update_ptr(statement->binds, zvtmp, bind); + zend_string_release(zvtmp); + statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */ return 0; } diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h index 4a23f06168..d113775bdc 100644 --- a/ext/oci8/php_oci8_int.h +++ b/ext/oci8/php_oci8_int.h @@ -95,6 +95,13 @@ extern zend_class_entry *oci_coll_class_entry_ptr; #define PHP_OCI_LOB_BUFFER_ENABLED 1 #define PHP_OCI_LOB_BUFFER_USED 2 +#ifdef OCI_ERROR_MAXMSG_SIZE2 +/* Bigger size is defined from 11.2.0.3 onwards */ +#define PHP_OCI_ERRBUF_LEN OCI_ERROR_MAXMSG_SIZE2 +#else +#define PHP_OCI_ERRBUF_LEN OCI_ERROR_MAXMSG_SIZE +#endif + /* The mode parameter for oci_connect() is overloaded and accepts both * privilege and external authentication flags OR'd together. * PHP_OCI_CRED_EXT must be distinct from the OCI_xxx privilege @@ -144,7 +151,7 @@ typedef struct { sb4 errcode; /* last ORA- error number */ HashTable *descriptors; /* descriptors hash, used to flush all the LOBs using this connection on commit */ - zend_ulong descriptor_count; /* used to index the descriptors hash table. Not an accurate count */ + zend_ulong descriptor_count; /* used to index the descriptors hash table. Not an accurate count */ unsigned is_open:1; /* hels to determine if the connection is dead or not */ unsigned is_attached:1; /* hels to determine if we should detach from the server when closing/freeing the connection */ unsigned is_persistent:1; /* self-descriptive */ @@ -221,7 +228,7 @@ typedef struct { OCIStmt *stmt; /* statement handle */ char *last_query; /* last query issued. also used to determine if this is a statement or a refcursor received from Oracle */ char impres_flag; /* PHP_OCI_IMPRES_*_ */ - zend_long last_query_len; /* last query length */ + zend_long last_query_len; /* last query length */ HashTable *columns; /* hash containing all the result columns */ HashTable *binds; /* binds hash */ HashTable *defines; /* defines hash */ @@ -412,7 +419,7 @@ void php_oci_bind_hash_dtor(zval *data); void php_oci_descriptor_flush_hash_dtor(zval *data); void php_oci_connection_descriptors_free(php_oci_connection *connection); sb4 php_oci_error(OCIError *err_p, sword status); -sb4 php_oci_fetch_errmsg(OCIError *error_handle, text **error_buf); +sb4 php_oci_fetch_errmsg(OCIError *error_handle, text *error_buf, size_t error_buf_size); int php_oci_fetch_sqltext_offset(php_oci_statement *statement, text **sqltext, ub2 *error_offset); void php_oci_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent, int exclusive); php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char *password, int password_len, char *new_password, int new_password_len, char *dbname, int dbname_len, char *charset, zend_long session_mode, int persistent, int exclusive); @@ -420,8 +427,8 @@ int php_oci_connection_rollback(php_oci_connection *connection); int php_oci_connection_commit(php_oci_connection *connection); int php_oci_connection_release(php_oci_connection *connection); int php_oci_password_change(php_oci_connection *connection, char *user, int user_len, char *pass_old, int pass_old_len, char *pass_new, int pass_new_len); -void php_oci_client_get_version(char **version); -int php_oci_server_get_version(php_oci_connection *connection, char **version); +void php_oci_client_get_version(char *version, size_t version_size); +int php_oci_server_get_version(php_oci_connection *connection, char *version, size_t version_size); void php_oci_fetch_row(INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_args); int php_oci_column_to_zval(php_oci_out_column *column, zval *value, int mode); void php_oci_dtrace_check_connection(php_oci_connection *connection, sb4 errcode, ub4 serverStatus);