From 9a01fe712a684dd0c6c6b36c48e7d16b78d9108d Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 20 Sep 2017 16:46:04 +0300 Subject: [PATCH 1/5] Fixed few ext/oci8 bugs --- ext/oci8/oci8.c | 10 +-- ext/oci8/oci8_failover.c | 8 +-- ext/oci8/oci8_interface.c | 9 +-- ext/oci8/oci8_statement.c | 145 +++++++++++++++++++++----------------- ext/oci8/php_oci8_int.h | 5 +- 5 files changed, 96 insertions(+), 81 deletions(-) diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c index 93e7bce2a38..8a26cf66ca0 100644 --- a/ext/oci8/oci8.c +++ b/ext/oci8/oci8.c @@ -1402,6 +1402,8 @@ void php_oci_define_hash_dtor(zval *data) define->name = NULL; } + zval_ptr_dtor(&define->val); + efree(define); } /* }}} */ @@ -1414,9 +1416,9 @@ void php_oci_bind_hash_dtor(zval *data) { php_oci_bind *bind = (php_oci_bind *) Z_PTR_P(data); - if (!Z_ISUNDEF(bind->parameter)) { - zval_ptr_dtor(&bind->parameter); - ZVAL_UNDEF(&bind->parameter); + if (!Z_ISUNDEF(bind->val)) { + zval_ptr_dtor(&bind->val); + ZVAL_UNDEF(&bind->val); } if (bind->array.elements) { @@ -2642,7 +2644,7 @@ void php_oci_fetch_row (INTERNAL_FUNCTION_PARAMETERS, int mode, int expected_arg if (placeholder == NULL) { placeholder = return_value; } else { - zval_dtor(placeholder); + zval_ptr_dtor(placeholder); } array_init(placeholder); diff --git a/ext/oci8/oci8_failover.c b/ext/oci8/oci8_failover.c index 4bc522b8650..82b0f0134f4 100644 --- a/ext/oci8/oci8_failover.c +++ b/ext/oci8/oci8_failover.c @@ -75,10 +75,10 @@ sb4 callback_fn(void *svchp, void *envhp, void *fo_ctx, ub4 fo_type, ub4 fo_even ZVAL_NULL(¶ms[0]); /* Cleanup */ - zval_dtor(&retval); - zval_dtor(¶ms[0]); - zval_dtor(¶ms[1]); - zval_dtor(¶ms[2]); + zval_ptr_dtor(&retval); + zval_ptr_dtor(¶ms[0]); + zval_ptr_dtor(¶ms[1]); + zval_ptr_dtor(¶ms[2]); return returnValue; } diff --git a/ext/oci8/oci8_interface.c b/ext/oci8/oci8_interface.c index 5da3084520e..5dabefcd2cf 100644 --- a/ext/oci8/oci8_interface.c +++ b/ext/oci8/oci8_interface.c @@ -117,7 +117,7 @@ PHP_FUNCTION(oci_define_by_name) php_oci_define *define; zend_string *zvtmp; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsz/|l", &stmt, &name, &name_len, &var, &type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsz|l", &stmt, &name, &name_len, &var, &type) == FAILURE) { return; } @@ -153,7 +153,8 @@ PHP_FUNCTION(oci_define_by_name) define->name[name_len] = '\0'; define->name_len = (ub4) name_len; define->type = (ub4) type; - define->zval = var; + ZEND_ASSERT(Z_ISREF_P(var)); + ZVAL_COPY(&define->val, var); RETURN_TRUE; } @@ -202,7 +203,7 @@ PHP_FUNCTION(oci_bind_array_by_name) zval *bind_var = NULL; php_oci_statement *statement; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsz/l|ll", &z_statement, &name, &name_len, &bind_var, &max_array_len, &max_item_len, &type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rszl|ll", &z_statement, &name, &name_len, &bind_var, &max_array_len, &max_item_len, &type) == FAILURE) { return; } @@ -1439,7 +1440,7 @@ PHP_FUNCTION(oci_fetch_all) PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement); - zval_dtor(array); + zval_ptr_dtor(array); while (skip--) { if (php_oci_statement_fetch(statement, nrows)) { diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c index 7639340c129..4c57dc91517 100644 --- a/ext/oci8/oci8_statement.c +++ b/ext/oci8/oci8_statement.c @@ -364,8 +364,10 @@ int php_oci_statement_fetch(php_oci_statement *statement, ub4 nrows) continue; } - zval_dtor(column->define->zval); - php_oci_column_to_zval(column, column->define->zval, 0); + ZEND_ASSERT(Z_ISREF(column->define->val)); + zval_ptr_dtor(Z_REFVAL(column->define->val)); + ZVAL_NULL(Z_REFVAL(column->define->val)); + php_oci_column_to_zval(column, Z_REFVAL(column->define->val), 0); } return 0; @@ -910,10 +912,12 @@ void php_oci_statement_free(php_oci_statement *statement) int php_oci_bind_pre_exec(zval *data, void *result) { php_oci_bind *bind = (php_oci_bind *) Z_PTR_P(data); + zval *zv = &bind->val; *(int *)result = 0; - if (Z_TYPE_P(bind->zval) == IS_ARRAY) { + ZVAL_DEREF(zv); + if (Z_TYPE_P(zv) == IS_ARRAY) { /* These checks are currently valid for oci_bind_by_name, not * oci_bind_array_by_name. Also bind->type and * bind->indicator are not used for oci_bind_array_by_name. @@ -927,7 +931,7 @@ int php_oci_bind_pre_exec(zval *data, void *result) case SQLT_CLOB: case SQLT_BLOB: case SQLT_RDD: - if (Z_TYPE_P(bind->zval) != IS_OBJECT) { + if (Z_TYPE_P(zv) != IS_OBJECT) { php_error_docref(NULL, E_WARNING, "Invalid variable used for bind"); *(int *)result = 1; } @@ -943,14 +947,14 @@ int php_oci_bind_pre_exec(zval *data, void *result) case SQLT_LBI: case SQLT_BIN: case SQLT_LNG: - if (Z_TYPE_P(bind->zval) == IS_RESOURCE || Z_TYPE_P(bind->zval) == IS_OBJECT) { + if (Z_TYPE_P(zv) == IS_RESOURCE || Z_TYPE_P(zv) == IS_OBJECT) { php_error_docref(NULL, E_WARNING, "Invalid variable used for bind"); *(int *)result = 1; } break; case SQLT_RSET: - if (Z_TYPE_P(bind->zval) != IS_RESOURCE) { + if (Z_TYPE_P(zv) != IS_RESOURCE) { php_error_docref(NULL, E_WARNING, "Invalid variable used for bind"); *(int *)result = 1; } @@ -971,30 +975,34 @@ int php_oci_bind_post_exec(zval *data) php_oci_bind *bind = (php_oci_bind *) Z_PTR_P(data); php_oci_connection *connection = bind->parent_statement->connection; sword errstatus; + zval *zv = &bind->val; + ZVAL_DEREF(zv); if (bind->indicator == -1) { /* NULL */ - zval *val = bind->zval; - if (Z_TYPE_P(val) == IS_STRING) { - *Z_STRVAL_P(val) = '\0'; /* XXX avoid warning in debug mode */ + if (Z_TYPE_P(zv) == IS_STRING) { + *Z_STRVAL_P(zv) = '\0'; /* XXX avoid warning in debug mode */ } - zval_dtor(val); - ZVAL_NULL(val); - } else if (Z_TYPE_P(bind->zval) == IS_STRING - && Z_STRLEN_P(bind->zval) > 0 - && Z_STRVAL_P(bind->zval)[ Z_STRLEN_P(bind->zval) ] != '\0') { + zval_ptr_dtor(zv); + ZVAL_NULL(zv); + } else if (Z_TYPE_P(zv) == IS_STRING + && Z_STRLEN_P(zv) > 0 + && Z_STRVAL_P(zv)[ Z_STRLEN_P(zv) ] != '\0') { /* The post- PHP 5.3 feature for "interned" strings disallows * their reallocation but (i) any IN binds either interned or * not should already be null terminated and (ii) for OUT * binds, php_oci_bind_out_callback() should have allocated a * new string that we can modify here. */ - Z_STR_P(bind->zval) = zend_string_extend(Z_STR_P(bind->zval), Z_STRLEN_P(bind->zval)+1, 0); - Z_STRVAL_P(bind->zval)[ Z_STRLEN_P(bind->zval) ] = '\0'; - } else if (Z_TYPE_P(bind->zval) == IS_ARRAY) { + SEPARATE_STRING(zv); + Z_STR_P(zv) = zend_string_extend(Z_STR_P(zv), Z_STRLEN_P(zv)+1, 0); + Z_STRVAL_P(zv)[ Z_STRLEN_P(zv) ] = '\0'; + } else if (Z_TYPE_P(zv) == IS_ARRAY) { int i; zval *entry = NULL; - HashTable *hash = HASH_OF(bind->zval); - + HashTable *hash; + + SEPARATE_ARRAY(zv); + hash = HASH_OF(zv); zend_hash_internal_pointer_reset(hash); switch (bind->array.type) { @@ -1003,22 +1011,22 @@ int php_oci_bind_post_exec(zval *data) case SQLT_LNG: for (i = 0; i < (int) bind->array.current_length; i++) { if ((i < (int) bind->array.old_length) && (entry = zend_hash_get_current_data(hash)) != NULL) { - zval_dtor(entry); + zval_ptr_dtor(entry); ZVAL_LONG(entry, ((oci_phpsized_int *)(bind->array.elements))[i]); zend_hash_move_forward(hash); } else { - add_next_index_long(bind->zval, ((oci_phpsized_int *)(bind->array.elements))[i]); + add_next_index_long(zv, ((oci_phpsized_int *)(bind->array.elements))[i]); } } break; case SQLT_FLT: for (i = 0; i < (int) bind->array.current_length; i++) { if ((i < (int) bind->array.old_length) && (entry = zend_hash_get_current_data(hash)) != NULL) { - zval_dtor(entry); + zval_ptr_dtor(entry); ZVAL_DOUBLE(entry, ((double *)(bind->array.elements))[i]); zend_hash_move_forward(hash); } else { - add_next_index_double(bind->zval, ((double *)(bind->array.elements))[i]); + add_next_index_double(zv, ((double *)(bind->array.elements))[i]); } } break; @@ -1031,7 +1039,7 @@ int php_oci_bind_post_exec(zval *data) if ((i < (int) bind->array.old_length) && (entry = zend_hash_get_current_data(hash)) != NULL) { PHP_OCI_CALL_RETURN(errstatus, OCIDateToText, (connection->err, &(((OCIDate *)(bind->array.elements))[i]), 0, 0, 0, 0, &buff_len, buff)); - zval_dtor(entry); + zval_ptr_dtor(entry); if (errstatus != OCI_SUCCESS) { connection->errcode = php_oci_error(connection->err, errstatus); @@ -1047,10 +1055,10 @@ int php_oci_bind_post_exec(zval *data) if (errstatus != OCI_SUCCESS) { connection->errcode = php_oci_error(connection->err, errstatus); PHP_OCI_HANDLE_ERROR(connection, connection->errcode); - add_next_index_null(bind->zval); + add_next_index_null(zv); } else { connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */ - add_next_index_stringl(bind->zval, (char *)buff, buff_len); + add_next_index_stringl(zv, (char *)buff, buff_len); } } } @@ -1066,20 +1074,15 @@ int php_oci_bind_post_exec(zval *data) /* int curr_element_length = strlen(((text *)bind->array.elements)+i*bind->array.max_length); */ int curr_element_length = bind->array.element_lengths[i]; if ((i < (int) bind->array.old_length) && (entry = zend_hash_get_current_data(hash)) != NULL) { - zval_dtor(entry); + zval_ptr_dtor(entry); ZVAL_STRINGL(entry, (char *)(((text *)bind->array.elements)+i*bind->array.max_length), curr_element_length); zend_hash_move_forward(hash); } else { - add_next_index_stringl(bind->zval, (char *)(((text *)bind->array.elements)+i*bind->array.max_length), curr_element_length); + add_next_index_stringl(zv, (char *)(((text *)bind->array.elements)+i*bind->array.max_length), curr_element_length); } } break; } - } else if ((Z_TYPE_P(bind->zval) == IS_TRUE) || (Z_TYPE_P(bind->zval) == IS_FALSE)) { - if (Z_LVAL_P(bind->zval) == 0) - ZVAL_BOOL(bind->zval, FALSE); - else if (Z_LVAL_P(bind->zval) == 1) - ZVAL_BOOL(bind->zval, TRUE); } return 0; @@ -1103,11 +1106,8 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, size_t name_l sword errstatus; zval *param = NULL; - if (!Z_ISREF_P(var)) { - param = var; - } else { - param = Z_REFVAL_P(var); - } + ZEND_ASSERT(Z_ISREF_P(var)); + param = Z_REFVAL_P(var); switch (type) { case SQLT_NTY: @@ -1242,9 +1242,9 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, size_t name_l if ((old_bind = zend_hash_str_find_ptr(statement->binds, name, name_len)) != NULL) { bindp = old_bind; - if (!Z_ISUNDEF(bindp->parameter)) { - zval_ptr_dtor(&bindp->parameter); - ZVAL_UNDEF(&bindp->parameter); + if (!Z_ISUNDEF(bindp->val)) { + zval_ptr_dtor(&bindp->val); + ZVAL_UNDEF(&bindp->val); } } else { zend_string *zvtmp; @@ -1254,9 +1254,6 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, size_t name_l zend_string_release(zvtmp); } - /* Keep a copy of bound variable in the bind hash */ - ZVAL_COPY(&bindp->parameter, var); - /* Make sure the minimum of value_sz is 1 to avoid ORA-3149 * when both in/out parameters are bound with empty strings */ @@ -1266,7 +1263,7 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, size_t name_l bindp->descriptor = oci_desc; bindp->statement = oci_stmt; bindp->parent_statement = statement; - bindp->zval = param; + ZVAL_COPY(&bindp->val, var); bindp->type = type; /* Storing max length set in OCIBindByName() to check it later in * php_oci_bind_in_callback() function to avoid ORA-1406 error while @@ -1360,11 +1357,14 @@ sb4 php_oci_bind_in_callback( php_oci_bind *phpbind; zval *val; - if (!(phpbind=(php_oci_bind *)ictxp) || !(val = phpbind->zval)) { + if (!(phpbind=(php_oci_bind *)ictxp) || Z_ISUNDEF(phpbind->val)) { php_error_docref(NULL, E_WARNING, "Invalid phpbind pointer value"); return OCI_ERROR; } + val = &phpbind->val; + ZVAL_DEREF(val); + if (Z_ISNULL_P(val)) { /* we're going to insert a NULL column */ phpbind->indicator = -1; @@ -1421,11 +1421,14 @@ sb4 php_oci_bind_out_callback( zval *val; sb4 retval = OCI_ERROR; - if (!(phpbind=(php_oci_bind *)octxp) || !(val = phpbind->zval)) { + if (!(phpbind=(php_oci_bind *)octxp) || Z_ISUNDEF(phpbind->val)) { php_error_docref(NULL, E_WARNING, "Invalid phpbind pointer value"); return retval; } + val = &phpbind->val; + ZVAL_DEREF(val); + if (Z_TYPE_P(val) == IS_RESOURCE) { /* Processing for ref-cursor out binds */ if (phpbind->statement != NULL) { @@ -1463,7 +1466,7 @@ sb4 php_oci_bind_out_callback( retval = OCI_CONTINUE; } else { convert_to_string(val); - zval_dtor(val); + zval_ptr_dtor(val); { char *p = ecalloc(1, PHP_OCI_PIECE_SIZE); @@ -1474,12 +1477,12 @@ sb4 php_oci_bind_out_callback( Z_STRLEN_P(val) = PHP_OCI_PIECE_SIZE; /* 64K-1 is max XXX */ Z_STRVAL_P(val) = ecalloc(1, Z_STRLEN_P(val) + 1); /* XXX is this right? */ - ZVAL_STRINGL(val, NULL, Z_STRLEN(phpbind->zval) + 1); + ZVAL_STRINGL(val, NULL, Z_STRLEN(val) + 1); #endif /* XXX we assume that zend-zval len has 4 bytes */ - *alenpp = (ub4*) &Z_STRLEN_P(phpbind->zval); - *bufpp = Z_STRVAL_P(phpbind->zval); + *alenpp = (ub4*) &Z_STRLEN_P(val); + *bufpp = Z_STRVAL_P(val); *piecep = OCI_ONE_PIECE; *rcodepp = &phpbind->retcode; *indpp = &phpbind->indicator; @@ -1527,10 +1530,10 @@ php_oci_out_column *php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAME column = php_oci_statement_get_column(statement, Z_LVAL(tmp), NULL, 0); if (!column) { php_error_docref(NULL, E_WARNING, "Invalid column index \"" ZEND_LONG_FMT "\"", Z_LVAL(tmp)); - zval_dtor(&tmp); + zval_ptr_dtor(&tmp); return NULL; } - zval_dtor(&tmp); + zval_ptr_dtor(&tmp); } return column; } @@ -1586,11 +1589,15 @@ int php_oci_statement_get_numrows(php_oci_statement *statement, ub4 *numrows) Bind arrays to PL/SQL types */ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, size_t name_len, zval *var, zend_long max_table_length, zend_long maxlength, zend_long type) { - php_oci_bind *bind, *bindp; + php_oci_bind *bind; sword errstatus; zend_string *zvtmp; + zval *val; - convert_to_array(var); + ZEND_ASSERT(Z_ISREF_P(var)); + val = Z_REFVAL_P(var); + SEPARATE_ZVAL_NOREF(val); + convert_to_array(val); if (maxlength < -1) { php_error_docref(NULL, E_WARNING, "Invalid max length value (" ZEND_LONG_FMT ")", maxlength); @@ -1601,11 +1608,11 @@ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, size_t case SQLT_NUM: case SQLT_INT: case SQLT_LNG: - bind = php_oci_bind_array_helper_number(var, max_table_length); + bind = php_oci_bind_array_helper_number(val, max_table_length); break; case SQLT_FLT: - bind = php_oci_bind_array_helper_double(var, max_table_length); + bind = php_oci_bind_array_helper_double(val, max_table_length); break; case SQLT_AFC: @@ -1614,14 +1621,14 @@ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, size_t case SQLT_AVC: case SQLT_STR: case SQLT_LVC: - if (maxlength == -1 && zend_hash_num_elements(Z_ARRVAL_P(var)) == 0) { + if (maxlength == -1 && zend_hash_num_elements(Z_ARRVAL_P(val)) == 0) { php_error_docref(NULL, E_WARNING, "You must provide max length value for empty arrays"); return 1; } - bind = php_oci_bind_array_helper_string(var, max_table_length, maxlength); + bind = php_oci_bind_array_helper_string(val, max_table_length, maxlength); break; case SQLT_ODT: - bind = php_oci_bind_array_helper_date(var, max_table_length, statement->connection); + bind = php_oci_bind_array_helper_date(val, max_table_length, statement->connection); break; default: php_error_docref(NULL, E_WARNING, "Unknown or unsupported datatype given: " ZEND_LONG_FMT, type); @@ -1638,7 +1645,7 @@ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, size_t bind->statement = NULL; bind->parent_statement = statement; bind->bind = NULL; - bind->zval = var; + ZVAL_COPY(&bind->val, var); bind->array.type = type; bind->indicator = 0; /* not used for array binds */ bind->type = 0; /* not used for array binds */ @@ -1677,6 +1684,8 @@ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, size_t efree(bind->array.indicators); } + zval_ptr_dtor(&bind->val); + efree(bind); statement->errcode = php_oci_error(statement->err, errstatus); @@ -1690,7 +1699,7 @@ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, size_t } zvtmp = zend_string_init(name, name_len, 0); - bindp = zend_hash_update_ptr(statement->binds, zvtmp, bind); + zend_hash_update_ptr(statement->binds, zvtmp, bind); zend_string_release(zvtmp); statement->errcode = 0; /* retain backwards compat with OCI8 1.4 */ @@ -1707,6 +1716,7 @@ php_oci_bind *php_oci_bind_array_helper_string(zval *var, zend_long max_table_le HashTable *hash; zval *entry; + SEPARATE_ARRAY(var); /* TODO: may be use new HashTable iteration and prevent inplace modification */ hash = HASH_OF(var); if (maxlength == -1) { @@ -1723,7 +1733,7 @@ php_oci_bind *php_oci_bind_array_helper_string(zval *var, zend_long max_table_le } bind = emalloc(sizeof(php_oci_bind)); - ZVAL_UNDEF(&bind->parameter); + ZVAL_UNDEF(&bind->val); bind->array.elements = (text *)safe_emalloc(max_table_length * (maxlength + 1), sizeof(text), 0); memset(bind->array.elements, 0, max_table_length * (maxlength + 1) * sizeof(text)); bind->array.current_length = zend_hash_num_elements(Z_ARRVAL_P(var)); @@ -1780,10 +1790,11 @@ php_oci_bind *php_oci_bind_array_helper_number(zval *var, zend_long max_table_le HashTable *hash; zval *entry; + SEPARATE_ARRAY(var); /* TODO: may be use new HashTable iteration and prevent inplace modification */ hash = HASH_OF(var); bind = emalloc(sizeof(php_oci_bind)); - ZVAL_UNDEF(&bind->parameter); + ZVAL_UNDEF(&bind->val); bind->array.elements = (oci_phpsized_int *)safe_emalloc(max_table_length, sizeof(oci_phpsized_int), 0); bind->array.current_length = zend_hash_num_elements(Z_ARRVAL_P(var)); bind->array.old_length = bind->array.current_length; @@ -1820,10 +1831,11 @@ php_oci_bind *php_oci_bind_array_helper_double(zval *var, zend_long max_table_le HashTable *hash; zval *entry; + SEPARATE_ARRAY(var); /* TODO: may be use new HashTable iteration and prevent inplace modification */ hash = HASH_OF(var); bind = emalloc(sizeof(php_oci_bind)); - ZVAL_UNDEF(&bind->parameter); + ZVAL_UNDEF(&bind->val); bind->array.elements = (double *)safe_emalloc(max_table_length, sizeof(double), 0); bind->array.current_length = zend_hash_num_elements(Z_ARRVAL_P(var)); bind->array.old_length = bind->array.current_length; @@ -1861,10 +1873,11 @@ php_oci_bind *php_oci_bind_array_helper_date(zval *var, zend_long max_table_leng zval *entry; sword errstatus; + SEPARATE_ARRAY(var); /* TODO: may be use new HashTable iteration and prevent inplace modification */ hash = HASH_OF(var); bind = emalloc(sizeof(php_oci_bind)); - ZVAL_UNDEF(&bind->parameter); + ZVAL_UNDEF(&bind->val); bind->array.elements = (OCIDate *)safe_emalloc(max_table_length, sizeof(OCIDate), 0); bind->array.current_length = zend_hash_num_elements(Z_ARRVAL_P(var)); bind->array.old_length = bind->array.current_length; diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h index 97ccbd57762..fc034d5892c 100644 --- a/ext/oci8/php_oci8_int.h +++ b/ext/oci8/php_oci8_int.h @@ -209,7 +209,7 @@ typedef struct { /* {{{ php_oci_define */ typedef struct { - zval *zval; /* zval used in define */ + zval val; /* zval used in define */ text *name; /* placeholder's name */ ub4 name_len; /* placeholder's name length */ ub4 type; /* define type */ @@ -244,8 +244,7 @@ typedef struct { /* {{{ php_oci_bind */ typedef struct { OCIBind *bind; /* bind handle */ - zval *zval; /* value */ - zval parameter; /* a copy of bound variable used for oci_bind_by_name */ + zval val; /* value */ dvoid *descriptor; /* used for binding of LOBS etc */ OCIStmt *statement; /* used for binding REFCURSORs */ php_oci_statement *parent_statement; /* pointer to the parent statement */ From c8dea7ae1ebdb50bddf7f981ee30c35d5a5a878e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 2 Oct 2017 17:04:26 +0300 Subject: [PATCH 2/5] Restored code for BOOL variables --- ext/oci8/oci8_statement.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c index 4c57dc91517..982e71ba6a0 100644 --- a/ext/oci8/oci8_statement.c +++ b/ext/oci8/oci8_statement.c @@ -1083,6 +1083,12 @@ int php_oci_bind_post_exec(zval *data) } break; } + } else if ((Z_TYPE_P(bind->zval) == IS_TRUE) || (Z_TYPE_P(bind->zval) == IS_FALSE)) { + /* This convetrsion is done on purpose (ext/oci8 uses LVAL as a temorary value) */ + if (Z_LVAL_P(bind->zval) == 0) + ZVAL_BOOL(bind->zval, FALSE); + else if (Z_LVAL_P(bind->zval) == 1) + ZVAL_BOOL(bind->zval, TRUE); } return 0; From 4d69587035f6d622134f86bbc9ee0afb00eeec88 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 3 Oct 2017 09:08:28 +0300 Subject: [PATCH 3/5] Fixed compilation errors --- ext/oci8/oci8_statement.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c index 982e71ba6a0..f2c380fd758 100644 --- a/ext/oci8/oci8_statement.c +++ b/ext/oci8/oci8_statement.c @@ -1083,12 +1083,12 @@ int php_oci_bind_post_exec(zval *data) } break; } - } else if ((Z_TYPE_P(bind->zval) == IS_TRUE) || (Z_TYPE_P(bind->zval) == IS_FALSE)) { + } else if ((Z_TYPE(bind->val) == IS_TRUE) || (Z_TYPE(bind->val) == IS_FALSE)) { /* This convetrsion is done on purpose (ext/oci8 uses LVAL as a temorary value) */ - if (Z_LVAL_P(bind->zval) == 0) - ZVAL_BOOL(bind->zval, FALSE); - else if (Z_LVAL_P(bind->zval) == 1) - ZVAL_BOOL(bind->zval, TRUE); + if (Z_LVAL(bind->val) == 0) + ZVAL_BOOL(&bind->val, FALSE); + else if (Z_LVAL(bind->val) == 1) + ZVAL_BOOL(&bind->val, TRUE); } return 0; From 24e595bf26279c315a7f120f866160e0a0833fad Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 3 Oct 2017 10:49:56 +0300 Subject: [PATCH 4/5] Use dereferenced value --- ext/oci8/oci8_statement.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c index f2c380fd758..f0cb16425a0 100644 --- a/ext/oci8/oci8_statement.c +++ b/ext/oci8/oci8_statement.c @@ -1083,12 +1083,12 @@ int php_oci_bind_post_exec(zval *data) } break; } - } else if ((Z_TYPE(bind->val) == IS_TRUE) || (Z_TYPE(bind->val) == IS_FALSE)) { + } else if ((Z_TYPE_P(zv) == IS_TRUE) || (Z_TYPE_P(zv) == IS_FALSE)) { /* This convetrsion is done on purpose (ext/oci8 uses LVAL as a temorary value) */ - if (Z_LVAL(bind->val) == 0) - ZVAL_BOOL(&bind->val, FALSE); - else if (Z_LVAL(bind->val) == 1) - ZVAL_BOOL(&bind->val, TRUE); + if (Z_LVAL_P(zv) == 0) + ZVAL_BOOL(zv, FALSE); + else if (Z_LVAL_P(zv) == 1) + ZVAL_BOOL(zv, TRUE); } return 0; From 1195de87ffa018abe4b1461b2b254fe6eee963cc Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 4 Oct 2017 09:56:25 +0300 Subject: [PATCH 5/5] Bumped ext/oci8 version --- NEWS | 3 +++ ext/oci8/php_oci8.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 2a2881cf0ef..5154345aeff 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,9 @@ PHP NEWS . Fixed bug #75290 (debug info of Closures of internal functions contain garbage argument names). (Andrea) +- OCI8: + . Fixed incorrect reference counting. (Dmitry, Tianfang Yang) + - litespeed: . Fixed bug #75248 (Binary directory doesn't get created when building only litespeed SAPI). (petk) diff --git a/ext/oci8/php_oci8.h b/ext/oci8/php_oci8.h index e70e2fe09cd..53449d5f4ce 100644 --- a/ext/oci8/php_oci8.h +++ b/ext/oci8/php_oci8.h @@ -43,7 +43,7 @@ */ #undef PHP_OCI8_VERSION #endif -#define PHP_OCI8_VERSION "2.1.7" +#define PHP_OCI8_VERSION "2.1.8" extern zend_module_entry oci8_module_entry; #define phpext_oci8_ptr &oci8_module_entry