mirror of
https://github.com/php/php-src.git
synced 2025-08-19 08:49:28 +02:00
Merge branch 'PHP-7.0' into PHP-7.1
This commit is contained in:
commit
23e2c356b7
8 changed files with 261 additions and 33 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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. This restores PHP 5.6 behavior */
|
||||
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
|
||||
|
|
|
@ -46,12 +46,12 @@ Interoperability Support" (ID 207303.1) for details.
|
|||
<active>no</active>
|
||||
</lead>
|
||||
|
||||
<date>2016-08-18</date>
|
||||
<date>2016-10-17</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="/">
|
||||
|
@ -469,6 +468,23 @@ Fixed bug #72524 (Binding null values triggers ORA-24816 error)
|
|||
</extsrcrelease>
|
||||
<changelog>
|
||||
|
||||
<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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
191
ext/oci8/tests/bug71148.phpt
Normal file
191
ext/oci8/tests/bug71148.phpt
Normal file
|
@ -0,0 +1,191 @@
|
|||
--TEST--
|
||||
Bug #71448 (Binding reference overwritten on php7)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
$target_dbs = array('oracledb' => true, 'timesten' => true); // test runs on these DBs
|
||||
require(dirname(__FILE__).'/skipif.inc');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require(dirname(__FILE__).'/connect.inc');
|
||||
|
||||
// Initialize
|
||||
|
||||
$stmtarray = array(
|
||||
"CREATE OR REPLACE FUNCTION bindfunc(var1 varchar2, var2 varchar2)
|
||||
RETURN varchar2
|
||||
AS var3 VARCHAR2(20);
|
||||
BEGIN
|
||||
var3 := CONCAT(var1, var2);
|
||||
RETURN var3;
|
||||
END;",
|
||||
"CREATE OR REPLACE PROCEDURE bindproc(var1 IN string, var2 IN string, var3 IN OUT string) IS
|
||||
BEGIN
|
||||
var3 := CONCAT(var1, var3);
|
||||
var3 := CONCAT(var3, var2);
|
||||
END;"
|
||||
);
|
||||
|
||||
oci8_test_sql_execute($c, $stmtarray);
|
||||
|
||||
// Run test
|
||||
|
||||
function bindvar($stmt, $name, $var)
|
||||
{
|
||||
oci_bind_by_name($stmt, $name, $var);
|
||||
}
|
||||
|
||||
// Test 1: Bind input parameter in a local function
|
||||
$sql = "select :var1, :var2 from dual";
|
||||
$cache1 = "INSTR1";
|
||||
$cache2 = "INSTR2";
|
||||
|
||||
echo "Test 1: Bind input parameter in a local function\n";
|
||||
$stmt = oci_parse($c, $sql);
|
||||
|
||||
bindvar($stmt, ':var1', $cache1);
|
||||
bindvar($stmt, ':var2', $cache2);
|
||||
|
||||
oci_execute($stmt);
|
||||
|
||||
var_dump(oci_fetch_assoc($stmt));
|
||||
|
||||
oci_free_statement($stmt);
|
||||
|
||||
// Test 2: Bind output parameter in a local function
|
||||
$sql = "begin :output1 := 'OUTSTR1'; :output2 := 'OUTSTR2'; end;";
|
||||
$cache1 = "xxxxxx";
|
||||
$cache2 = "xxxxxx";
|
||||
|
||||
echo "\nTest 2: Bind output parameter in a local function\n";
|
||||
$stmt = oci_parse($c, $sql);
|
||||
|
||||
bindvar($stmt, ':output1', $cache1);
|
||||
bindvar($stmt, ':output2', $cache2);
|
||||
|
||||
oci_execute($stmt);
|
||||
|
||||
var_dump($cache1);
|
||||
var_dump($cache2);
|
||||
|
||||
oci_free_statement($stmt);
|
||||
|
||||
// Test 3: Bind output parameter within the same scope of execute
|
||||
$sql = "begin :output1 := 'OUTSTR1'; :output2 := 'OUTSTR2'; end;";
|
||||
$cache1 = "xxxxxx";
|
||||
$cache2 = "xxxxxx";
|
||||
|
||||
echo "\nTest 3: Bind output parameter within the same scope of execute\n";
|
||||
$stmt = oci_parse($c, $sql);
|
||||
|
||||
oci_bind_by_name($stmt, ":output1", $cache1);
|
||||
oci_bind_by_name($stmt, ":output2", $cache2);
|
||||
|
||||
oci_execute($stmt);
|
||||
|
||||
var_dump($cache1);
|
||||
var_dump($cache2);
|
||||
|
||||
oci_free_statement($stmt);
|
||||
|
||||
// Test 4: Bind output parameter within the same scope of execute
|
||||
$sql= "begin :output := bindfunc(:var1, :var2); end;";
|
||||
$cache1 = "STR1";
|
||||
$cache2 = "STR2";
|
||||
|
||||
echo "\nTest 4: Bind output parameter within the same scope of execute\n";
|
||||
$stmt = oci_parse($c, $sql);
|
||||
|
||||
oci_bind_by_name($stmt, ":var1", $cache1, -1);
|
||||
oci_bind_by_name($stmt, ":var2", $cache2, -1);
|
||||
oci_bind_by_name($stmt, ":output", $cache3, 100);
|
||||
|
||||
oci_execute($stmt);
|
||||
|
||||
var_dump($cache3);
|
||||
|
||||
// Test 5: Bind IN OUT parameter in a local function
|
||||
|
||||
$sql = "call bindproc(:var1, :var2, :var3)";
|
||||
$cache1 = 'STR1';
|
||||
$cache2 = 'STR2';
|
||||
$cache3 = ' ';
|
||||
|
||||
echo "\nTest 5: Bind IN OUT parameter in a local function\n";
|
||||
$stmt = oci_parse($c, $sql);
|
||||
|
||||
bindvar($stmt, ':var1', $cache1);
|
||||
bindvar($stmt, ':var2', $cache2);
|
||||
bindvar($stmt, ':var3', $cache3);
|
||||
|
||||
oci_execute($stmt);
|
||||
|
||||
var_dump($cache1);
|
||||
var_dump($cache2);
|
||||
var_dump($cache3);
|
||||
|
||||
oci_free_statement($stmt);
|
||||
|
||||
// Test 6: Bind IN OUT parameter within the same scope of execute
|
||||
|
||||
$sql = "call bindproc(:var1, :var2, :var3)";
|
||||
$cache1 = 'STR1';
|
||||
$cache2 = 'STR2';
|
||||
$cache3 = ' ';
|
||||
|
||||
echo "\nTest 6: Bind IN OUT parameter within the same scope of execute\n";
|
||||
$stmt = oci_parse($c, $sql);
|
||||
|
||||
oci_bind_by_name($stmt, ":var1", $cache1, -1);
|
||||
oci_bind_by_name($stmt, ":var2", $cache2, -1);
|
||||
oci_bind_by_name($stmt, ":var3", $cache3, 100);
|
||||
|
||||
oci_execute($stmt);
|
||||
|
||||
var_dump($cache1);
|
||||
var_dump($cache2);
|
||||
var_dump($cache3);
|
||||
|
||||
// Cleanup
|
||||
|
||||
$stmtarray = array(
|
||||
"DROP FUNCTION bindfunc",
|
||||
"DROP PROCEDURE bindproc"
|
||||
);
|
||||
|
||||
oci8_test_sql_execute($c, $stmtarray);
|
||||
|
||||
?>
|
||||
===DONE===
|
||||
<?php exit(0); ?>
|
||||
--EXPECT--
|
||||
Test 1: Bind input parameter in a local function
|
||||
array(2) {
|
||||
[":VAR1"]=>
|
||||
string(6) "INSTR1"
|
||||
[":VAR2"]=>
|
||||
string(6) "INSTR2"
|
||||
}
|
||||
|
||||
Test 2: Bind output parameter in a local function
|
||||
string(6) "xxxxxx"
|
||||
string(6) "xxxxxx"
|
||||
|
||||
Test 3: Bind output parameter within the same scope of execute
|
||||
string(7) "OUTSTR1"
|
||||
string(7) "OUTSTR2"
|
||||
|
||||
Test 4: Bind output parameter within the same scope of execute
|
||||
string(8) "STR1STR2"
|
||||
|
||||
Test 5: Bind IN OUT parameter in a local function
|
||||
string(4) "STR1"
|
||||
string(4) "STR2"
|
||||
string(1) " "
|
||||
|
||||
Test 6: Bind IN OUT parameter within the same scope of execute
|
||||
string(4) "STR1"
|
||||
string(4) "STR2"
|
||||
string(9) "STR1 STR2"
|
||||
===DONE===
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue