Skip to content

Commit a570077

Browse files
committed
Correct oci8 hash destructors to prevent segfaults, and a few other fixes.
1 parent 692d283 commit a570077

File tree

4 files changed

+44
-44
lines changed

4 files changed

+44
-44
lines changed

ext/oci8/oci8.c

+18-17
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ static void php_oci_descriptor_list_dtor (zend_resource *);
128128
static void php_oci_spool_list_dtor(zend_resource *entry);
129129
static void php_oci_collection_list_dtor (zend_resource *);
130130

131-
static int php_oci_persistent_helper(zend_resource *le);
131+
static int php_oci_persistent_helper(zval *zv);
132132
static int php_oci_connection_ping(php_oci_connection *);
133133
static int php_oci_connection_status(php_oci_connection *);
134134
static int php_oci_connection_close(php_oci_connection *);
@@ -1321,7 +1321,7 @@ PHP_RSHUTDOWN_FUNCTION(oci)
13211321
* unable to process a pconnection because of a refcount, the processing would happen from
13221322
* np-destructor which is called when refcount goes to zero - php_oci_pconnection_list_np_dtor
13231323
*/
1324-
zend_hash_apply(&EG(persistent_list), (apply_func_t) php_oci_persistent_helper);
1324+
zend_hash_apply(&EG(persistent_list), php_oci_persistent_helper);
13251325

13261326
if (OCI_G(edition)) {
13271327
efree(OCI_G(edition));
@@ -1530,9 +1530,9 @@ static void php_oci_collection_list_dtor(zend_resource *entry)
15301530
*
15311531
* Define hash destructor
15321532
*/
1533-
void php_oci_define_hash_dtor(void *data)
1533+
void php_oci_define_hash_dtor(zval *data)
15341534
{
1535-
php_oci_define *define = (php_oci_define *) data;
1535+
php_oci_define *define = (php_oci_define *) Z_PTR_P(data);
15361536

15371537
zval_ptr_dtor(&define->zval);
15381538

@@ -1547,9 +1547,9 @@ void php_oci_define_hash_dtor(void *data)
15471547
*
15481548
* Bind hash destructor
15491549
*/
1550-
void php_oci_bind_hash_dtor(void *data)
1550+
void php_oci_bind_hash_dtor(zval *data)
15511551
{
1552-
php_oci_bind *bind = (php_oci_bind *) data;
1552+
php_oci_bind *bind = (php_oci_bind *) Z_PTR_P(data);
15531553

15541554
if (bind->array.elements) {
15551555
efree(bind->array.elements);
@@ -1571,17 +1571,17 @@ void php_oci_bind_hash_dtor(void *data)
15711571
*
15721572
* Column hash destructor
15731573
*/
1574-
void php_oci_column_hash_dtor(void *data)
1574+
void php_oci_column_hash_dtor(zval *data)
15751575
{
1576-
php_oci_out_column *column = (php_oci_out_column *) data;
1576+
php_oci_out_column *column = (php_oci_out_column *) Z_PTR_P(data);
15771577

1578-
/* if (column->stmtid) { */ /* PHPNG TODO */
1578+
if (column->stmtid) {
15791579
zend_list_close(column->stmtid);
1580-
/* } */
1580+
}
15811581

1582-
/* if (column->is_descr) { */ /* PHPNG TODO */
1582+
if (column->is_descr) {
15831583
zend_list_close(column->descid);
1584-
/* } */
1584+
}
15851585

15861586
if (column->data) {
15871587
efree(column->data);
@@ -1597,9 +1597,9 @@ void php_oci_column_hash_dtor(void *data)
15971597
*
15981598
* Flush descriptors on commit
15991599
*/
1600-
void php_oci_descriptor_flush_hash_dtor(void *data)
1600+
void php_oci_descriptor_flush_hash_dtor(zval *data)
16011601
{
1602-
php_oci_descriptor *descriptor = *(php_oci_descriptor **)data;
1602+
php_oci_descriptor *descriptor = (php_oci_descriptor *) Z_PTR_P(data);
16031603

16041604
if (descriptor && descriptor->buffering == PHP_OCI_LOB_BUFFER_USED && (descriptor->type == OCI_DTYPE_LOB || descriptor->type == OCI_DTYPE_FILE)) {
16051605
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
20762076

20772077
if (OCI_G(max_persistent) != -1 && OCI_G(num_persistent) >= OCI_G(max_persistent)) {
20782078
/* try to find an idle connection and kill it */
2079-
zend_hash_apply(&EG(persistent_list), (apply_func_t) php_oci_persistent_helper);
2079+
zend_hash_apply(&EG(persistent_list), php_oci_persistent_helper);
20802080

20812081
if (OCI_G(max_persistent) != -1 && OCI_G(num_persistent) >= OCI_G(max_persistent)) {
20822082
/* 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)
25612561
}
25622562

25632563
if (column->is_cursor) { /* REFCURSOR -> simply return the statement id */
2564-
ZVAL_RES(value, zend_register_resource(column->stmtid, 0)); /* XXX type correct? */
2564+
ZVAL_RES(value, column->stmtid);
25652565
++GC_REFCOUNT(column->stmtid);
25662566
} else if (column->is_descr) {
25672567

@@ -2797,8 +2797,9 @@ void php_oci_fetch_row (INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_arg
27972797
* Helper function to close/rollback persistent connections at the end of request. A return value of
27982798
* 1 indicates that the connection is to be destroyed
27992799
*/
2800-
static int php_oci_persistent_helper(zend_resource *le)
2800+
static int php_oci_persistent_helper(zval *zv)
28012801
{
2802+
zend_resource *le = Z_RES_P(zv);
28022803
time_t timestamp;
28032804
php_oci_connection *connection;
28042805

ext/oci8/oci8_interface.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1429,7 +1429,7 @@ PHP_FUNCTION(oci_fetch_all)
14291429
if (flags & PHP_OCI_NUM) {
14301430
zend_hash_next_index_insert(Z_ARRVAL(row), &element);
14311431
} else { /* default to ASSOC */
1432-
zend_symtable_update(Z_ARRVAL(row), zend_string_init(columns[ i ]->name, columns[ i ]->name_len+1, 0), &element);
1432+
zend_symtable_update(Z_ARRVAL(row), zend_string_init(columns[ i ]->name, columns[ i ]->name_len, 0), &element);
14331433
}
14341434
}
14351435

@@ -1459,7 +1459,7 @@ PHP_FUNCTION(oci_fetch_all)
14591459
columns[ i ] = php_oci_statement_get_column(statement, i + 1, NULL, 0);
14601460

14611461
array_init(&tmp);
1462-
outarrs[ i ] = zend_symtable_update(Z_ARRVAL_P(array), zend_string_init(columns[ i ]->name, columns[ i ]->name_len+1, 0), &tmp);
1462+
outarrs[ i ] = zend_symtable_update(Z_ARRVAL_P(array), zend_string_init(columns[ i ]->name, columns[ i ]->name_len, 0), &tmp);
14631463
}
14641464
}
14651465

ext/oci8/oci8_statement.c

+17-18
Original file line numberDiff line numberDiff line change
@@ -207,9 +207,9 @@ int php_oci_statement_set_prefetch(php_oci_statement *statement, ub4 prefetch )
207207

208208
/* {{{ php_oci_cleanup_pre_fetch()
209209
Helper function to cleanup ref-cursors and descriptors from the previous row */
210-
int php_oci_cleanup_pre_fetch(void *data)
210+
int php_oci_cleanup_pre_fetch(zval *data)
211211
{
212-
php_oci_out_column *outcol = data;
212+
php_oci_out_column *outcol = (php_oci_out_column*) Z_PTR_P(data);
213213

214214
if (!outcol->is_descr && !outcol->is_cursor)
215215
return ZEND_HASH_APPLY_KEEP;
@@ -254,7 +254,7 @@ int php_oci_statement_fetch(php_oci_statement *statement, ub4 nrows)
254254
statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */
255255

256256
if (statement->has_descr && statement->columns) {
257-
zend_hash_apply(statement->columns, (apply_func_t) php_oci_cleanup_pre_fetch);
257+
zend_hash_apply(statement->columns, php_oci_cleanup_pre_fetch);
258258
}
259259

260260
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
479479
int php_oci_statement_execute(php_oci_statement *statement, ub4 mode)
480480
{
481481
php_oci_out_column *outcol;
482-
php_oci_out_column column;
483482
OCIParam *param = NULL;
484483
text *colname;
485484
ub4 counter;
@@ -530,7 +529,7 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode)
530529

531530
if (statement->binds) {
532531
int result = 0;
533-
zend_hash_apply_with_argument(statement->binds, (apply_func_arg_t) php_oci_bind_pre_exec, (void *)&result);
532+
zend_hash_apply_with_argument(statement->binds, php_oci_bind_pre_exec, (void *)&result);
534533
if (result) {
535534
return 1;
536535
}
@@ -546,7 +545,7 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode)
546545
}
547546

548547
if (statement->binds) {
549-
zend_hash_apply(statement->binds, (apply_func_t) php_oci_bind_post_exec);
548+
zend_hash_apply(statement->binds, php_oci_bind_post_exec);
550549
}
551550

552551
if (mode & OCI_COMMIT_ON_SUCCESS) {
@@ -587,9 +586,9 @@ int php_oci_statement_execute(php_oci_statement *statement, ub4 mode)
587586
statement->ncolumns = colcount;
588587

589588
for (counter = 1; counter <= colcount; counter++) {
590-
memset(&column,0,sizeof(php_oci_out_column));
589+
outcol = (php_oci_out_column *) ecalloc(1, sizeof(php_oci_out_column));
591590

592-
if ((outcol = zend_hash_index_update_ptr(statement->columns, counter, &column)) == NULL) {
591+
if ((outcol = zend_hash_index_update_ptr(statement->columns, counter, outcol)) == NULL) {
593592
efree(statement->columns);
594593
/* out of memory */
595594
return 1;
@@ -902,9 +901,9 @@ void php_oci_statement_free(php_oci_statement *statement)
902901

903902
/* {{{ php_oci_bind_pre_exec()
904903
Helper function */
905-
int php_oci_bind_pre_exec(void *data, void *result)
904+
int php_oci_bind_pre_exec(zval *data, void *result)
906905
{
907-
php_oci_bind *bind = (php_oci_bind *) data;
906+
php_oci_bind *bind = (php_oci_bind *) Z_PTR_P(data);
908907

909908
*(int *)result = 0;
910909

@@ -961,9 +960,9 @@ int php_oci_bind_pre_exec(void *data, void *result)
961960

962961
/* {{{ php_oci_bind_post_exec()
963962
Helper function */
964-
int php_oci_bind_post_exec(void *data)
963+
int php_oci_bind_post_exec(zval *data)
965964
{
966-
php_oci_bind *bind = (php_oci_bind *) data;
965+
php_oci_bind *bind = (php_oci_bind *) Z_PTR_P(data);
967966
php_oci_connection *connection = bind->parent_statement->connection;
968967
sword errstatus;
969968

@@ -1317,7 +1316,7 @@ sb4 php_oci_bind_in_callback(
13171316
return OCI_ERROR;
13181317
}
13191318

1320-
if (ZVAL_IS_NULL(val)) {
1319+
if (Z_ISNULL_P(val)) {
13211320
/* we're going to insert a NULL column */
13221321
phpbind->indicator = -1;
13231322
*bufpp = 0;
@@ -1597,10 +1596,10 @@ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int nam
15971596
(text *)name,
15981597
name_len,
15991598
(dvoid *) bindp->array.elements,
1600-
(sb4) bind->array.max_length,
1599+
(sb4) bindp->array.max_length,
16011600
(ub2)type,
16021601
(dvoid *)bindp->array.indicators,
1603-
(ub2 *)bind->array.element_lengths,
1602+
(ub2 *)bindp->array.element_lengths,
16041603
(ub2 *)0, /* bindp->array.retcodes, */
16051604
(ub4) max_table_length,
16061605
(ub4 *) &(bindp->array.current_length),
@@ -1610,13 +1609,11 @@ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, int nam
16101609

16111610

16121611
if (errstatus != OCI_SUCCESS) {
1613-
efree(bind);
16141612
statement->errcode = php_oci_error(statement->err, errstatus);
16151613
PHP_OCI_HANDLE_ERROR(statement->connection, statement->errcode);
16161614
return 1;
16171615
}
16181616
statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */
1619-
efree(bind);
16201617
return 0;
16211618
}
16221619
/* }}} */
@@ -1636,9 +1633,11 @@ php_oci_bind *php_oci_bind_array_helper_string(zval *var, zend_long max_table_le
16361633
zend_hash_internal_pointer_reset(hash);
16371634
while ((entry = zend_hash_get_current_data(hash)) != NULL) {
16381635
convert_to_string_ex(entry);
1639-
if (Z_STRLEN_P(entry) > maxlength) {
1636+
1637+
if (maxlength == -1 || Z_STRLEN_P(entry) > maxlength) {
16401638
maxlength = Z_STRLEN_P(entry) + 1;
16411639
}
1640+
16421641
zend_hash_move_forward(hash);
16431642
}
16441643
}

ext/oci8/php_oci8_int.h

+7-7
Original file line numberDiff line numberDiff line change
@@ -406,10 +406,10 @@ typedef struct {
406406

407407
/* {{{ main prototypes */
408408

409-
void php_oci_column_hash_dtor(void *data);
410-
void php_oci_define_hash_dtor(void *data);
411-
void php_oci_bind_hash_dtor(void *data);
412-
void php_oci_descriptor_flush_hash_dtor(void *data);
409+
void php_oci_column_hash_dtor(zval *data);
410+
void php_oci_define_hash_dtor(zval *data);
411+
void php_oci_bind_hash_dtor(zval *data);
412+
void php_oci_descriptor_flush_hash_dtor(zval *data);
413413
void php_oci_connection_descriptors_free(php_oci_connection *connection);
414414
sb4 php_oci_error(OCIError *err_p, sword status);
415415
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
483483
int php_oci_statement_execute(php_oci_statement *statement, ub4 mode);
484484
int php_oci_statement_cancel(php_oci_statement *statement);
485485
void php_oci_statement_free(php_oci_statement *statement);
486-
int php_oci_bind_pre_exec(void *data, void *result);
487-
int php_oci_bind_post_exec(void *data);
486+
int php_oci_bind_pre_exec(zval *data, void *result);
487+
int php_oci_bind_post_exec(zval *data);
488488
int php_oci_bind_by_name(php_oci_statement *statement, char *name, int name_len, zval *var, zend_long maxlength, ub2 type);
489489
sb4 php_oci_bind_in_callback(dvoid *ictxp, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 *alenp, ub1 *piecep, dvoid **indpp);
490490
sb4 php_oci_bind_out_callback(dvoid *octxp, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcodepp);
491491
php_oci_out_column *php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAMETERS, int need_data);
492-
int php_oci_cleanup_pre_fetch(void *data);
492+
int php_oci_cleanup_pre_fetch(zval *data);
493493
int php_oci_statement_get_type(php_oci_statement *statement, ub2 *type);
494494
int php_oci_statement_get_numrows(php_oci_statement *statement, ub4 *numrows);
495495
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);

0 commit comments

Comments
 (0)