Small fix and a test case to prove it's right

This commit is contained in:
Andrey Hristov 2008-03-20 15:29:14 +00:00
parent b72b4ce87e
commit 85cd8525c9
2 changed files with 149 additions and 8 deletions

View File

@ -0,0 +1,148 @@
--TEST--
mysqli_stmt_bind_param() - checking whether the parameters are modified (bug#44390)
--SKIPIF--
<?php
require_once('skipif.inc');
require_once('skipifemb.inc');
require_once('skipifconnectfailure.inc');
?>
--FILE--
<?php
include "connect.inc";
require('table.inc');
class foo {
// @var $bar string
public $bar;
}
$foo = new foo;
$foo->bar = "фубар";
echo "Test 1: \n";
$stmt = $link->prepare("SELECT ? FOO");
var_dump($foo); // here you can see the bar member var beeing a string
$stmt->bind_param("s", $foo->bar);
var_dump($foo); // this will show $foo->bar beeing a reference string
$stmt->bind_result($one);
$stmt->execute();
$stmt->fetch();
$stmt->free_result();
echo("$one\n\n");
// it is getting worse. Binding the same var twice with different
// types you can get unexpected results (e.g. binary trash for the
// string and misc data for the integer. See next 2 tests.
echo "Test 2: \n";
$stmt = $link->prepare("SELECT ? FOO, ? BAR");
var_dump($foo);
$stmt->bind_param("si", $foo->bar, $foo->bar);
echo "---\n";
var_dump($foo);
echo "---\n";
$stmt->execute();
var_dump($foo);
echo "---\n";
$stmt->bind_result($one, $two);
$stmt->fetch();
$stmt->free_result();
echo("$one - $two\n\n");
echo "Test 3: \n";
$stmt = $link->prepare("SELECT ? FOO, ? BAR");
var_dump($foo);
$stmt->bind_param("is", $foo->bar, $foo->bar);
var_dump($foo);
$stmt->bind_result($one, $two);
$stmt->execute();
$stmt->fetch();
$stmt->free_result();
echo("$one - $two\n\n");
echo "done!\n";
?>
--EXPECTF--
Test 1:
object(foo)#3 (1) {
["bar"]=>
string(10) "фубар"
}
object(foo)#3 (1) {
["bar"]=>
&string(10) "фубар"
}
фубар
Test 2:
object(foo)#3 (1) {
["bar"]=>
string(10) "фубар"
}
---
object(foo)#3 (1) {
["bar"]=>
&string(10) "фубар"
}
---
object(foo)#3 (1) {
["bar"]=>
&string(10) "фубар"
}
---
фубар - 0
Test 3:
object(foo)#3 (1) {
["bar"]=>
string(10) "фубар"
}
object(foo)#3 (1) {
["bar"]=>
&string(10) "фубар"
}
0 - фубар
done!
--UEXPECTF--
Test 1:
object(foo)#3 (1) {
[u"bar"]=>
unicode(5) "фубар"
}
object(foo)#3 (1) {
[u"bar"]=>
&unicode(5) "фубар"
}
фубар
Test 2:
object(foo)#3 (1) {
[u"bar"]=>
unicode(5) "фубар"
}
---
object(foo)#3 (1) {
[u"bar"]=>
&unicode(5) "фубар"
}
---
object(foo)#3 (1) {
[u"bar"]=>
&unicode(5) "фубар"
}
---
фубар - 0
Test 3:
object(foo)#3 (1) {
[u"bar"]=>
unicode(5) "фубар"
}
object(foo)#3 (1) {
[u"bar"]=>
&unicode(5) "фубар"
}
0 - фубар
done!

View File

@ -828,14 +828,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT *stmt, zend_uchar **buf, zend_uch
*p = php_mysqlnd_net_store_length(*p, 0);
}
break;
case MYSQL_TYPE_VAR_STRING:
/*
If the user uses refs, it could be that the type has
has changed and we need to convert, again. Which is noop,
if the type hasn't changed.
*/
convert_to_string_ex(&stmt->param_bind[i].zv);
{
case MYSQL_TYPE_VAR_STRING:{
unsigned int len = Z_STRLEN_P(data);
/* to is after p. The latter hasn't been moved */
*p = php_mysqlnd_net_store_length(*p, len);