]> granicus.if.org Git - php/commitdiff
Fixed few ext/oci8 bugs
authorDmitry Stogov <dmitry@zend.com>
Wed, 20 Sep 2017 13:46:04 +0000 (16:46 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 20 Sep 2017 13:46:04 +0000 (16:46 +0300)
ext/oci8/oci8.c
ext/oci8/oci8_failover.c
ext/oci8/oci8_interface.c
ext/oci8/oci8_statement.c
ext/oci8/php_oci8_int.h

index 93e7bce2a38c2b7ca3f595e60d92cba198cba14f..8a26cf66ca0f9556b6376408c8f71ead69bdbcbf 100644 (file)
@@ -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);
index 4bc522b8650787db356e968157f8a204fc952ccc..82b0f0134f4d082f187363a70e15a4e2f091493e 100644 (file)
@@ -75,10 +75,10 @@ sb4 callback_fn(void *svchp, void *envhp, void *fo_ctx, ub4 fo_type, ub4 fo_even
        ZVAL_NULL(&params[0]);
 
        /* Cleanup */
-       zval_dtor(&retval);
-       zval_dtor(&params[0]);
-       zval_dtor(&params[1]);
-       zval_dtor(&params[2]);
+       zval_ptr_dtor(&retval);
+       zval_ptr_dtor(&params[0]);
+       zval_ptr_dtor(&params[1]);
+       zval_ptr_dtor(&params[2]);
 
        return returnValue;
 }
index 5da3084520e451f5132e6bf565524a3001b8708d..5dabefcd2cf69f77b2e903ffdc78111bfed16d4a 100644 (file)
@@ -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)) {
index 7639340c129a6dc15ce4770f62a85e30f19c46cb..4c57dc915173ac1d7e1bf79550fc93943d97488a 100644 (file)
@@ -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;
index 97ccbd5776253e357337071ec78e0e12f5b9711b..fc034d5892cc71bac70cf5edd0e9db9174b8a7a8 100644 (file)
@@ -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 */