From: Cameron Porter Date: Sat, 27 Jun 2015 06:09:05 +0000 (-0500) Subject: Correct oci8 hash destructors to prevent segfaults, and a few other fixes. X-Git-Tag: php-7.1.0alpha3~25^2~150^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=621698d3f9ccf1941d05ff553d4e2214b0734118;p=php Correct oci8 hash destructors to prevent segfaults, and a few other fixes. --- diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c index 01c9b6d189..0492cdb238 100644 --- a/ext/oci8/oci8.c +++ b/ext/oci8/oci8.c @@ -128,7 +128,7 @@ static void php_oci_descriptor_list_dtor (zend_resource *); static void php_oci_spool_list_dtor(zend_resource *entry); static void php_oci_collection_list_dtor (zend_resource *); -static int php_oci_persistent_helper(zend_resource *le); +static int php_oci_persistent_helper(zval *zv); static int php_oci_connection_ping(php_oci_connection *); static int php_oci_connection_status(php_oci_connection *); static int php_oci_connection_close(php_oci_connection *); @@ -1321,7 +1321,7 @@ PHP_RSHUTDOWN_FUNCTION(oci) * unable to process a pconnection because of a refcount, the processing would happen from * np-destructor which is called when refcount goes to zero - php_oci_pconnection_list_np_dtor */ - zend_hash_apply(&EG(persistent_list), (apply_func_t) php_oci_persistent_helper); + zend_hash_apply(&EG(persistent_list), php_oci_persistent_helper); if (OCI_G(edition)) { efree(OCI_G(edition)); @@ -1530,9 +1530,9 @@ static void php_oci_collection_list_dtor(zend_resource *entry) * * Define hash destructor */ -void php_oci_define_hash_dtor(void *data) +void php_oci_define_hash_dtor(zval *data) { - php_oci_define *define = (php_oci_define *) data; + php_oci_define *define = (php_oci_define *) Z_PTR_P(data); zval_ptr_dtor(&define->zval); @@ -1547,9 +1547,9 @@ void php_oci_define_hash_dtor(void *data) * * Bind hash destructor */ -void php_oci_bind_hash_dtor(void *data) +void php_oci_bind_hash_dtor(zval *data) { - php_oci_bind *bind = (php_oci_bind *) data; + php_oci_bind *bind = (php_oci_bind *) Z_PTR_P(data); if (bind->array.elements) { efree(bind->array.elements); @@ -1571,17 +1571,17 @@ void php_oci_bind_hash_dtor(void *data) * * Column hash destructor */ -void php_oci_column_hash_dtor(void *data) +void php_oci_column_hash_dtor(zval *data) { - php_oci_out_column *column = (php_oci_out_column *) data; + php_oci_out_column *column = (php_oci_out_column *) Z_PTR_P(data); - /* if (column->stmtid) { */ /* PHPNG TODO */ + if (column->stmtid) { zend_list_close(column->stmtid); - /* } */ + } - /* if (column->is_descr) { */ /* PHPNG TODO */ + if (column->is_descr) { zend_list_close(column->descid); - /* } */ + } if (column->data) { efree(column->data); @@ -1597,9 +1597,9 @@ void php_oci_column_hash_dtor(void *data) * * Flush descriptors on commit */ -void php_oci_descriptor_flush_hash_dtor(void *data) +void php_oci_descriptor_flush_hash_dtor(zval *data) { - php_oci_descriptor *descriptor = *(php_oci_descriptor **)data; + php_oci_descriptor *descriptor = (php_oci_descriptor *) Z_PTR_P(data); if (descriptor && descriptor->buffering == PHP_OCI_LOB_BUFFER_USED && (descriptor->type == OCI_DTYPE_LOB || descriptor->type == OCI_DTYPE_FILE)) { php_oci_lob_flush(descriptor, OCI_LOB_BUFFER_FREE); @@ -2076,7 +2076,7 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char if (OCI_G(max_persistent) != -1 && OCI_G(num_persistent) >= OCI_G(max_persistent)) { /* try to find an idle connection and kill it */ - zend_hash_apply(&EG(persistent_list), (apply_func_t) php_oci_persistent_helper); + zend_hash_apply(&EG(persistent_list), php_oci_persistent_helper); if (OCI_G(max_persistent) != -1 && OCI_G(num_persistent) >= OCI_G(max_persistent)) { /* all persistent connactions are in use, fallback to non-persistent connection creation */ @@ -2561,7 +2561,7 @@ int php_oci_column_to_zval(php_oci_out_column *column, zval *value, int mode) } if (column->is_cursor) { /* REFCURSOR -> simply return the statement id */ - ZVAL_RES(value, zend_register_resource(column->stmtid, 0)); /* XXX type correct? */ + ZVAL_RES(value, column->stmtid); ++GC_REFCOUNT(column->stmtid); } else if (column->is_descr) { @@ -2797,8 +2797,9 @@ void php_oci_fetch_row (INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_arg * Helper function to close/rollback persistent connections at the end of request. A return value of * 1 indicates that the connection is to be destroyed */ -static int php_oci_persistent_helper(zend_resource *le) +static int php_oci_persistent_helper(zval *zv) { + zend_resource *le = Z_RES_P(zv); time_t timestamp; php_oci_connection *connection; diff --git a/ext/oci8/oci8_interface.c b/ext/oci8/oci8_interface.c index e1452dca01..4deaec6080 100644 --- a/ext/oci8/oci8_interface.c +++ b/ext/oci8/oci8_interface.c @@ -1429,7 +1429,7 @@ PHP_FUNCTION(oci_fetch_all) if (flags & PHP_OCI_NUM) { zend_hash_next_index_insert(Z_ARRVAL(row), &element); } else { /* default to ASSOC */ - zend_symtable_update(Z_ARRVAL(row), zend_string_init(columns[ i ]->name, columns[ i ]->name_len+1, 0), &element); + zend_symtable_update(Z_ARRVAL(row), zend_string_init(columns[ i ]->name, columns[ i ]->name_len, 0), &element); } } @@ -1459,7 +1459,7 @@ PHP_FUNCTION(oci_fetch_all) columns[ i ] = php_oci_statement_get_column(statement, i + 1, NULL, 0); array_init(&tmp); - outarrs[ i ] = zend_symtable_update(Z_ARRVAL_P(array), zend_string_init(columns[ i ]->name, columns[ i ]->name_len+1, 0), &tmp); + outarrs[ i ] = zend_symtable_update(Z_ARRVAL_P(array), zend_string_init(columns[ i ]->name, columns[ i ]->name_len, 0), &tmp); } } diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c index 2583e1a386..ef68f1ce38 100644 --- a/ext/oci8/oci8_statement.c +++ b/ext/oci8/oci8_statement.c @@ -207,9 +207,9 @@ int php_oci_statement_set_prefetch(php_oci_statement *statement, ub4 prefetch ) /* {{{ php_oci_cleanup_pre_fetch() Helper function to cleanup ref-cursors and descriptors from the previous row */ -int php_oci_cleanup_pre_fetch(void *data) +int php_oci_cleanup_pre_fetch(zval *data) { - php_oci_out_column *outcol = data; + php_oci_out_column *outcol = (php_oci_out_column*) Z_PTR_P(data); if (!outcol->is_descr && !outcol->is_cursor) return ZEND_HASH_APPLY_KEEP; @@ -254,7 +254,7 @@ int php_oci_statement_fetch(php_oci_statement *statement, ub4 nrows) statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */ if (statement->has_descr && statement->columns) { - zend_hash_apply(statement->columns, (apply_func_t) php_oci_cleanup_pre_fetch); + zend_hash_apply(statement->columns, php_oci_cleanup_pre_fetch); } PHP_OCI_CALL_RETURN(errstatus, OCIStmtFetch, (statement->stmt, statement->err, nrows, OCI_FETCH_NEXT, OCI_DEFAULT)); @@ -479,7 +479,6 @@ sb4 php_oci_define_callback(dvoid *ctx, OCIDefine *define, ub4 iter, dvoid **buf int php_oci_statement_execute(php_oci_statement *statement, ub4 mode) { php_oci_out_column *outcol; - php_oci_out_column column; OCIParam *param = NULL; text *colname; ub4 counter; @@ -530,7 +529,7 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode) if (statement->binds) { int result = 0; - zend_hash_apply_with_argument(statement->binds, (apply_func_arg_t) php_oci_bind_pre_exec, (void *)&result); + zend_hash_apply_with_argument(statement->binds, php_oci_bind_pre_exec, (void *)&result); if (result) { return 1; } @@ -546,7 +545,7 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode) } if (statement->binds) { - zend_hash_apply(statement->binds, (apply_func_t) php_oci_bind_post_exec); + zend_hash_apply(statement->binds, php_oci_bind_post_exec); } if (mode & OCI_COMMIT_ON_SUCCESS) { @@ -587,9 +586,9 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode) statement->ncolumns = colcount; for (counter = 1; counter <= colcount; counter++) { - memset(&column,0,sizeof(php_oci_out_column)); + outcol = (php_oci_out_column *) ecalloc(1, sizeof(php_oci_out_column)); - if ((outcol = zend_hash_index_update_ptr(statement->columns, counter, &column)) == NULL) { + if ((outcol = zend_hash_index_update_ptr(statement->columns, counter, outcol)) == NULL) { efree(statement->columns); /* out of memory */ return 1; @@ -902,9 +901,9 @@ void php_oci_statement_free(php_oci_statement *statement) /* {{{ php_oci_bind_pre_exec() Helper function */ -int php_oci_bind_pre_exec(void *data, void *result) +int php_oci_bind_pre_exec(zval *data, void *result) { - php_oci_bind *bind = (php_oci_bind *) data; + php_oci_bind *bind = (php_oci_bind *) Z_PTR_P(data); *(int *)result = 0; @@ -961,9 +960,9 @@ int php_oci_bind_pre_exec(void *data, void *result) /* {{{ php_oci_bind_post_exec() Helper function */ -int php_oci_bind_post_exec(void *data) +int php_oci_bind_post_exec(zval *data) { - php_oci_bind *bind = (php_oci_bind *) data; + php_oci_bind *bind = (php_oci_bind *) Z_PTR_P(data); php_oci_connection *connection = bind->parent_statement->connection; sword errstatus; @@ -1317,7 +1316,7 @@ sb4 php_oci_bind_in_callback( return OCI_ERROR; } - if (ZVAL_IS_NULL(val)) { + if (Z_ISNULL_P(val)) { /* we're going to insert a NULL column */ phpbind->indicator = -1; *bufpp = 0; @@ -1597,10 +1596,10 @@ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int nam (text *)name, name_len, (dvoid *) bindp->array.elements, - (sb4) bind->array.max_length, + (sb4) bindp->array.max_length, (ub2)type, (dvoid *)bindp->array.indicators, - (ub2 *)bind->array.element_lengths, + (ub2 *)bindp->array.element_lengths, (ub2 *)0, /* bindp->array.retcodes, */ (ub4) max_table_length, (ub4 *) &(bindp->array.current_length), @@ -1610,13 +1609,11 @@ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int nam if (errstatus != OCI_SUCCESS) { - efree(bind); statement->errcode = php_oci_error(statement->err, errstatus); PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode); return 1; } statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */ - efree(bind); return 0; } /* }}} */ @@ -1636,9 +1633,11 @@ php_oci_bind *php_oci_bind_array_helper_string(zval *var, zend_long max_table_le zend_hash_internal_pointer_reset(hash); while ((entry = zend_hash_get_current_data(hash)) != NULL) { convert_to_string_ex(entry); - if (Z_STRLEN_P(entry) > maxlength) { + + if (maxlength == -1 || Z_STRLEN_P(entry) > maxlength) { maxlength = Z_STRLEN_P(entry) + 1; } + zend_hash_move_forward(hash); } } diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h index c4b1f1bd14..9f1da48cd1 100644 --- a/ext/oci8/php_oci8_int.h +++ b/ext/oci8/php_oci8_int.h @@ -406,10 +406,10 @@ typedef struct { /* {{{ main prototypes */ -void php_oci_column_hash_dtor(void *data); -void php_oci_define_hash_dtor(void *data); -void php_oci_bind_hash_dtor(void *data); -void php_oci_descriptor_flush_hash_dtor(void *data); +void php_oci_column_hash_dtor(zval *data); +void php_oci_define_hash_dtor(zval *data); +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); @@ -483,13 +483,13 @@ php_oci_out_column *php_oci_statement_get_column(php_oci_statement *statement, z int php_oci_statement_execute(php_oci_statement *statement, ub4 mode); int php_oci_statement_cancel(php_oci_statement *statement); void php_oci_statement_free(php_oci_statement *statement); -int php_oci_bind_pre_exec(void *data, void *result); -int php_oci_bind_post_exec(void *data); +int php_oci_bind_pre_exec(zval *data, void *result); +int php_oci_bind_post_exec(zval *data); int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, zval *var, zend_long maxlength, ub2 type); sb4 php_oci_bind_in_callback(dvoid *ictxp, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 *alenp, ub1 *piecep, dvoid **indpp); sb4 php_oci_bind_out_callback(dvoid *octxp, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcodepp); php_oci_out_column *php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAMETERS, int need_data); -int php_oci_cleanup_pre_fetch(void *data); +int php_oci_cleanup_pre_fetch(zval *data); int php_oci_statement_get_type(php_oci_statement *statement, ub2 *type); int php_oci_statement_get_numrows(php_oci_statement *statement, ub4 *numrows); int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int name_len, zval *var, zend_long max_table_length, zend_long maxlength, zend_long type);