]> granicus.if.org Git - php/commitdiff
Correct oci8 hash destructors to prevent segfaults, and a few other fixes.
authorCameron Porter <camporter1@gmail.com>
Sat, 27 Jun 2015 06:09:05 +0000 (01:09 -0500)
committerAnatol Belski <ab@php.net>
Sun, 28 Jun 2015 11:05:25 +0000 (13:05 +0200)
ext/oci8/oci8.c
ext/oci8/oci8_interface.c
ext/oci8/oci8_statement.c
ext/oci8/php_oci8_int.h

index 01c9b6d18927845711c5cd765bff44b0f5237788..0492cdb238987dbc3be456d78066ac4eba29a74a 100644 (file)
@@ -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;
 
index e1452dca018251c011b8c70525156ea637cbc18c..4deaec608087d15d302295cceb10545d61da2bae 100644 (file)
@@ -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);
                        }
                }
 
index 2583e1a386c76d8f96b1618fc9c3dcf90f11a0c4..ef68f1ce38fe11e835924d21e1a6b685d06c5fb4 100644 (file)
@@ -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);
                }
        }
index c4b1f1bd1470ec81a42ea17cf9a419db456865a6..9f1da48cd101a329aa106bc2b7908c7ac4403514 100644 (file)
@@ -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);