Patch oci8-php7-bind for OCI8 related Bug #71148
Patch version 2016-10-13 03:56 UTC
Return to Bug #71148 |
Download this patch
Patch Revisions:
Developer: sixd@php.net
diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c
index 0527b55..59f9931 100644
--- a/ext/oci8/oci8.c
+++ b/ext/oci8/oci8.c
@@ -1387,6 +1387,11 @@ 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 (bind->array.elements) {
efree(bind->array.elements);
bind->array.elements = NULL;
diff --git a/ext/oci8/oci8_interface.c b/ext/oci8/oci8_interface.c
index 727ec3e..18714d1 100644
--- a/ext/oci8/oci8_interface.c
+++ b/ext/oci8/oci8_interface.c
@@ -110,7 +110,7 @@ PHP_FUNCTION(oci_bind_by_name)
zval *bind_var = NULL;
php_oci_statement *statement;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsz/|ll", &z_statement, &name, &name_len, &bind_var, &maxlen, &type) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsz|ll", &z_statement, &name, &name_len, &bind_var, &maxlen, &type) == FAILURE) {
return;
}
diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c
index d4f0815..0d751a8 100644
--- a/ext/oci8/oci8_statement.c
+++ b/ext/oci8/oci8_statement.c
@@ -1094,13 +1094,20 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, size_t name_l
int mode = OCI_DATA_AT_EXEC;
sb4 value_sz = -1;
sword errstatus;
+ zval *param = NULL;
+
+ if (!Z_ISREF_P(var)) {
+ param = var;
+ } else {
+ param = Z_REFVAL_P(var);
+ }
switch (type) {
case SQLT_NTY:
{
zval *tmp;
- if (Z_TYPE_P(var) != IS_OBJECT || (tmp = zend_hash_str_find(Z_OBJPROP_P(var), "collection", sizeof("collection")-1)) == NULL) {
+ if (Z_TYPE_P(param) != IS_OBJECT || (tmp = zend_hash_str_find(Z_OBJPROP_P(param), "collection", sizeof("collection")-1)) == NULL) {
php_error_docref(NULL, E_WARNING, "Unable to find collection property");
return 1;
}
@@ -1122,7 +1129,7 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, size_t name_l
{
zval *tmp;
- if (Z_TYPE_P(var) != IS_OBJECT || (tmp = zend_hash_str_find(Z_OBJPROP_P(var), "descriptor", sizeof("descriptor")-1)) == NULL) {
+ if (Z_TYPE_P(param) != IS_OBJECT || (tmp = zend_hash_str_find(Z_OBJPROP_P(param), "descriptor", sizeof("descriptor")-1)) == NULL) {
php_error_docref(NULL, E_WARNING, "Unable to find descriptor property");
return 1;
}
@@ -1141,17 +1148,17 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, size_t name_l
case SQLT_INT:
case SQLT_NUM:
- if (Z_TYPE_P(var) == IS_RESOURCE || Z_TYPE_P(var) == IS_OBJECT) {
+ if (Z_TYPE_P(param) == IS_RESOURCE || Z_TYPE_P(param) == IS_OBJECT) {
php_error_docref(NULL, E_WARNING, "Invalid variable used for bind");
return 1;
}
- convert_to_long(var);
+ convert_to_long(param);
#if defined(OCI_MAJOR_VERSION) && (OCI_MAJOR_VERSION > 10) && \
(defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64))
- bind_data = (ub8 *)&Z_LVAL_P(var);
+ bind_data = (ub8 *)&Z_LVAL_P(param);
value_sz = sizeof(ub8);
#else
- bind_data = (ub4 *)&Z_LVAL_P(var);
+ bind_data = (ub4 *)&Z_LVAL_P(param);
value_sz = sizeof(ub4);
#endif
mode = OCI_DEFAULT;
@@ -1162,20 +1169,20 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, size_t name_l
case SQLT_LNG:
case SQLT_AFC:
case SQLT_CHR: /* SQLT_CHR is the default value when type was not specified */
- if (Z_TYPE_P(var) == IS_RESOURCE || Z_TYPE_P(var) == IS_OBJECT) {
+ if (Z_TYPE_P(param) == IS_RESOURCE || Z_TYPE_P(param) == IS_OBJECT) {
php_error_docref(NULL, E_WARNING, "Invalid variable used for bind");
return 1;
}
- if (Z_TYPE_P(var) != IS_NULL) {
- convert_to_string(var);
+ if (Z_TYPE_P(param) != IS_NULL) {
+ convert_to_string(param);
}
if ((maxlength == -1) || (maxlength == 0)) {
if (type == SQLT_LNG) {
value_sz = SB4MAXVAL;
- } else if (Z_TYPE_P(var) == IS_STRING) {
- value_sz = (sb4) Z_STRLEN_P(var);
+ } else if (Z_TYPE_P(param) == IS_STRING) {
+ value_sz = (sb4) Z_STRLEN_P(param);
} else {
- /* Bug-72524: revert value_sz from PHP_OCI_PIECE_SIZE to 0. This restores PHP 5.6 behavior */
+ /* Bug-72524: revert value_sz from PHP_OCI_PIECE_SIZE to 0 */
value_sz = 0;
}
} else {
@@ -1184,11 +1191,11 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, size_t name_l
break;
case SQLT_RSET:
- if (Z_TYPE_P(var) != IS_RESOURCE) {
+ if (Z_TYPE_P(param) != IS_RESOURCE) {
php_error_docref(NULL, E_WARNING, "Invalid variable used for bind");
return 1;
}
- PHP_OCI_ZVAL_TO_STATEMENT_EX(var, bind_statement);
+ PHP_OCI_ZVAL_TO_STATEMENT_EX(param, bind_statement);
value_sz = sizeof(void*);
oci_stmt = bind_statement->stmt;
@@ -1200,15 +1207,15 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, size_t name_l
#if defined(OCI_MAJOR_VERSION) && OCI_MAJOR_VERSION >= 12
case SQLT_BOL:
- if (Z_TYPE_P(var) == IS_RESOURCE || Z_TYPE_P(var) == IS_OBJECT) {
+ if (Z_TYPE_P(param) == IS_RESOURCE || Z_TYPE_P(param) == IS_OBJECT) {
php_error_docref(NULL, E_WARNING, "Invalid variable used for bind");
return 1;
}
- convert_to_boolean(var);
- bind_data = (zend_long *)&Z_LVAL_P(var);
- if (Z_TYPE_P(var) == IS_TRUE)
+ convert_to_boolean(param);
+ bind_data = (zend_long *)&Z_LVAL_P(param);
+ if (Z_TYPE_P(param) == IS_TRUE)
*(zend_long *)bind_data = 1;
- else if (Z_TYPE_P(var) == IS_FALSE)
+ else if (Z_TYPE_P(param) == IS_FALSE)
*(zend_long *)bind_data = 0;
else {
php_error_docref(NULL, E_WARNING, "Invalid variable used for bind");
@@ -1234,6 +1241,10 @@ 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);
+ }
} else {
zend_string *zvtmp;
zvtmp = zend_string_init(name, name_len, 0);
@@ -1241,16 +1252,20 @@ int php_oci_bind_by_name(php_oci_statement *statement, char *name, size_t name_l
bindp = zend_hash_update_ptr(statement->binds, zvtmp, bindp);
zend_string_release(zvtmp);
}
- /* Make sure the minimum of value_sz is 1 to avoid ORA-3149
- * when both in/out parameters are bound with empty strings
- */
+
+ /* 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
+ */
if (value_sz == 0)
value_sz = 1;
bindp->descriptor = oci_desc;
bindp->statement = oci_stmt;
bindp->parent_statement = statement;
- bindp->zval = var;
+ bindp->zval = param;
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
@@ -1510,7 +1525,7 @@ php_oci_out_column *php_oci_statement_get_column_helper(INTERNAL_FUNCTION_PARAME
convert_to_long(&tmp);
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));
+ php_error_docref(NULL, E_WARNING, "Invalid column index \"%pd\"", Z_LVAL(tmp));
zval_dtor(&tmp);
return NULL;
}
@@ -1577,7 +1592,7 @@ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, size_t
convert_to_array(var);
if (maxlength < -1) {
- php_error_docref(NULL, E_WARNING, "Invalid max length value (" ZEND_LONG_FMT ")", maxlength);
+ php_error_docref(NULL, E_WARNING, "Invalid max length value (%pd)", maxlength);
return 1;
}
@@ -1608,7 +1623,7 @@ int php_oci_bind_array_by_name(php_oci_statement *statement, char *name, size_t
bind = php_oci_bind_array_helper_date(var, max_table_length, statement->connection);
break;
default:
- php_error_docref(NULL, E_WARNING, "Unknown or unsupported datatype given: " ZEND_LONG_FMT, type);
+ php_error_docref(NULL, E_WARNING, "Unknown or unsupported datatype given: %pd", type);
return 1;
break;
}
diff --git a/ext/oci8/package.xml b/ext/oci8/package.xml
index 29b5d6d..9c243a9 100644
--- a/ext/oci8/package.xml
+++ b/ext/oci8/package.xml
@@ -46,12 +46,12 @@ Interoperability Support" (ID 207303.1) for details.
<active>no</active>
</lead>
- <date>2016-08-18</date>
+ <date>2016-09-14</date>
<time>12:00:00</time>
<version>
- <release>2.1.2</release>
- <api>2.1.2</api>
+ <release>2.1.3</release>
+ <api>2.1.3</api>
</version>
<stability>
<release>stable</release>
@@ -60,8 +60,7 @@ Interoperability Support" (ID 207303.1) for details.
<license uri="http://www.php.net/license">PHP</license>
<notes>
This version is for PHP 7 only.
-Fixed invalid handle error with Implicit Result Sets
-Fixed bug #72524 (Binding null values triggers ORA-24816 error)
+Fixed bug #71148 (Bind reference overwritten on PHP 7)
</notes>
<contents>
<dir name="/">
@@ -471,6 +470,23 @@ Fixed bug #72524 (Binding null values triggers ORA-24816 error)
<release>
<version>
+ <release>2.1.2</release>
+ <api>2.1.2</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.php.net/license">PHP</license>
+ <notes>
+This version is for PHP 7 only.
+Fixed invalid handle error with Implicit Result Sets
+Fixed bug #72524 (Binding null values triggers ORA-24816 error)
+ </notes>
+</release>
+
+<release>
+ <version>
<release>2.1.1</release>
<api>2.1.1</api>
</version>
diff --git a/ext/oci8/php_oci8.h b/ext/oci8/php_oci8.h
index 70200e4..ef9b35d 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.2"
+#define PHP_OCI8_VERSION "2.1.3"
extern zend_module_entry oci8_module_entry;
#define phpext_oci8_ptr &oci8_module_entry
diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h
index 3a63504..1d66f05 100644
--- a/ext/oci8/php_oci8_int.h
+++ b/ext/oci8/php_oci8_int.h
@@ -243,6 +243,7 @@ typedef struct {
typedef struct {
OCIBind *bind; /* bind handle */
zval *zval; /* value */
+ zval parameter; /* a copy of bound variable used for oci_bind_by_name */
dvoid *descriptor; /* used for binding of LOBS etc */
OCIStmt *statement; /* used for binding REFCURSORs */
php_oci_statement *parent_statement; /* pointer to the parent statement */
diff --git a/ext/oci8/tests/driver_name.phpt b/ext/oci8/tests/driver_name.phpt
index 9814703..d24044e 100644
--- a/ext/oci8/tests/driver_name.phpt
+++ b/ext/oci8/tests/driver_name.phpt
@@ -57,11 +57,11 @@ function get_attr($conn)
?>
--EXPECT--
**Test 1.1 - Default values for the attribute **************
-The value of DRIVER_NAME is PHP OCI8 : 2.1.2
+The value of DRIVER_NAME is PHP OCI8 : 2.1.3
***Test 1.2 - Get the values from different connections **************
Testing with oci_pconnect()
-The value of DRIVER_NAME is PHP OCI8 : 2.1.2
+The value of DRIVER_NAME is PHP OCI8 : 2.1.3
Testing with oci_new_connect()
-The value of DRIVER_NAME is PHP OCI8 : 2.1.2
+The value of DRIVER_NAME is PHP OCI8 : 2.1.3
Done
|