From: Andrey Hristov Date: Thu, 20 Mar 2008 15:34:09 +0000 (+0000) Subject: Small fix and a test case to prove it X-Git-Tag: RELEASE_2_0_0a1~76 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9732763eca9ca2453a7fa6450de9ddf9ab0d224a;p=php Small fix and a test case to prove it --- diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 509fa81ee9..a2f1ab2b85 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -749,8 +749,10 @@ PHP_FUNCTION(mysqli_stmt_execute) switch (stmt->stmt->params[i].buffer_type) { case MYSQL_TYPE_VAR_STRING: if (UG(unicode) && Z_TYPE_P(the_var) == IS_UNICODE) { - php_mysqli_stmt_copy_it(&copies, stmt->param.vars[i], stmt->param.var_cnt, i); - the_var = copies[i]; + if (the_var == stmt->param.vars[i]) { + php_mysqli_stmt_copy_it(&copies, stmt->param.vars[i], stmt->param.var_cnt, i); + the_var = copies[i]; + } zval_unicode_to_string_ex(the_var, UG(utf8_conv) TSRMLS_CC); } else { if (the_var == stmt->param.vars[i] && Z_TYPE_P(stmt->param.vars[i]) != IS_STRING) { diff --git a/ext/mysqli/tests/mysqli_stmt_bind_param_check_param_no_change.phpt b/ext/mysqli/tests/mysqli_stmt_bind_param_check_param_no_change.phpt new file mode 100644 index 0000000000..5aab1a6777 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_bind_param_check_param_no_change.phpt @@ -0,0 +1,148 @@ +--TEST-- +mysqli_stmt_bind_param() - checking whether the parameters are modified (bug#44390) +--SKIPIF-- + +--FILE-- +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! diff --git a/ext/mysqlnd/mysqlnd_ps_codec.c b/ext/mysqlnd/mysqlnd_ps_codec.c index 078ec93024..f393e42a54 100644 --- a/ext/mysqlnd/mysqlnd_ps_codec.c +++ b/ext/mysqlnd/mysqlnd_ps_codec.c @@ -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);